iOS开发 — C语言基础6(数组)

iOS开发 — C语言基础6(数组)

C语言数组

一、数组的概念

用来囤积一组数据的布局数据类型

特性:只可以存放一种档次的多寡,如所有是int型或许全体是char型,数组里的数量变成成分。

为了让大家更好地学习和精晓数组,大家先来认识一下内存中的”地址”。

二、地址

1.统计机中的内存是以字节为单位的存储空间。内存的各个字节都有一个唯一的编号,这些编号就叫做地址。凡存放在内存中的先后和数目都有一个地点,也就是说,一个函数也有和好的内存地址。

2.当定义一个变量时,系统就分配一个分包唯一地址的存储单元来存储那么些变量。比如:

char a = ‘A’; // A的ASCII值为65

int b = 66;

在16bit编译器环境下,系统为a、b分别分配1个字节、2个字节的存储单元。变量存储单元的第四个字节的地点就是该变量的地方。

可以看来,变量a的地址是ffc3;变量b的地址是ffc1。内存中蕴藏的都是2进制数据。

3.在调节进程中,我们利用打印的不二法门查看变量的地方:

int c = 10;

// 以16进制方式出口地址

printf(“16进制:%x\n”, &c);

// 以10进制格局出口地址

printf(“10进制:%d”, &c);

出口结果:

三、一维数组

1.概念的款型为:类型  数组名[要素个数]

int a[5];

* []不得不放在数组名的末端,上面的都是张冠李戴写法:

int[5] a; // 错误

int[] b; // 错误

*
[]中间的个数必须是一个固定值,可以是常量(比如6、8)、常量表明式(比如3+4、5*7)。相对不可以接纳变量恐怕变量表明式来表示成分个数,大部分情况下不要省略成分个数(当数组作为函数的形参和数组早先化时除了)

上边的都是毋庸置疑写法:

int  a[5];  // 整型常量

int  b[‘A’];  // 字符常量,其实就是65

int  c[3*4];  // 整型常量表达式

上面的都是错误写法:

int a[]; // 没有点名元素个数,错误

int i = 9;

int a[i]; // 用变量做成分个数,错误

2.一维数组的仓储

概念数组时,系统将如约数组类型和个数分配一段连接的贮存空间来储存数组成分,如int
a[3]占据了三番五次的6字节囤积空间(在16位编译器环境下,一个int类型占用2个字节)。要小心的是,数组名代表着一切数组的地址,也就是数组的原初地址。

专注:其实a不到底变量,是个常量,它意味着着数组的地址。上图把a放到变量一栏是为着方便大家精通数组结构。

数组a的地点是ffc1,a[0]的地址是ffc1,a[1]的地方是ffc3,a[2]的地点是ffc5。因而a
== &a[0],即首先个成分的地点就是整套数组的地方。

3.一维数组的初叶化

* 初阶化的形似方式是:类型  数组名[要素个数] = {元素1, 元素2, …};

int a[2] = {8, 10};

实际上一定于:

int a[2];

a[0] = 8;

a[1] = 10;

只顾的是:C语言中编译器是不会对数组下标越界举办检查的,所以本人走访数组成分时要小心

* 成分值列表可以是数组所有因素的初值,也可以是前方部分要素的初值

int a[4] = {2, 5};

当数组为整型时,开头化未确定初值的要素,默认为0,所以地方的a[2]、a[3]都为0

* 当对一切数组成分都赋初值时,可以省略成分个数

int a[] = {2, 5, 7};

注明数组a的要素个数是3

*
数组起先化时的赋值方式只可以用于数组的定义,定义之后只好一个成分一个元素地赋值

下边的写法是错误的:

1 int a[3];

2 a[3] = {1, 2, 3}; // 错误

3 a = {1, 2, 3}; // 错误

其实为啥是不对的写法呢?大家得以几乎分析一下。

1>
第2行的a[3]意味着着访问数组的第4个因素,首先那里曾经是数组下标越界了;固然没有越界,给a[3]赋值时也应当赋一个int类型的平头,不应有是{}。

2>
第3行的a是数组名,代表着数组的地方,它是个常量!给常量赋值,那必将错了!

4.一维数组与函数参数

如若忘记了实参和形参的意思,可以回看下《iOS开发 —
C语言基础3(函数)》这篇文章

*
一维数组的要素作为函数实参,与同类型的概括变量作为实参一样,是单向的值传递,即数组元素的值传给形参,形参的变动不影响实参

// b是test函数的形参(格局参数)

void test(int b) {

b = 9;

}

int main()

{

int a[3];

a[0] = 10;

printf(“函数调用前的a[0]:%d\n”, a[0]);

test(a[0]); // a[0]是test函数的实参(实际参数)

printf(“函数调用后的a[0]:%d”, a[0]);

return 0;

}

输出结果:

*
大家都知道,数组名代表着方方面面数组的地址,如若一维数组的名字作为函数实参,传递的是全部数组,即形参数组和实参数组完全一样,是存放在在同样存储空间的同一个数组。那样形参数组修改时,实参数组也还要被修改了。形参数组的因素个数可以不难。

// b是test函数的形参(方式参数)

void test(int b[]) { // 也得以写int b[3]

b[0] = 9;

}

int main()

{

int a[3];

a[0] = 10;

printf(“函数调用前的a[0]:%d\n”, a[0]);

test(a); // a是test函数的实参(实际参数)

printf(“函数调用后的a[0]:%d”, a[0]);

return 0;

}

输出结果:

四、二维数组

1.二维数组的概念

概念格局:类型  数组名[行数][列数]

int a[2][3]; // 共2行3列,6个元素

2.二维数组的贮存

*
C语言把二维数组当作是一维数组的聚集,即二维数组是一个新鲜的一维数组:它的要素是一维数组。例如int
a[2][3]可以用作由一维数组a[0]和一维数组a[1]结缘,那多少个一维数组都饱含了3个int类型的成分

*
二维数组的存放顺序是按行存放的,先寄存第一行的因素,再存放第2行的因素。例如int
a[2][3]的寄放顺序是:a[0][0] → a[0][1] → a[0][2] →
a[1][0] → a[1][1] → a[1][2]

* 再来看看在内存中的存储景况,例如int a[2][2]

(注意:a[0]、a[1]也是数组,是一维数组,而且a[0]、a[1]就是数组名,由此a[0]、a[1]就象征着这一个一维数组的地点)

1> 数组a的地点是ffc1,数组a[0]的地方也是ffc1,即a = a[0];

2>
元素a[0][0]的地方是ffc1,所以数组a[0]的地址和成分a[0][0]的地方一样,即a[0]
= &a[0][0];

3> 最终得以得出结论:a = a[0] =
&a[0][0],以此类推,可以得出a[1] = &a[1][0]

3.二维数组的初步化

* 按行举行开始化

int a[2][3] = { {2, 2, 3}, {3, 4, 5} };

* 按存储顺序进行起头化(先存放第1行,再存放第2行)

int a[2][3] = {2, 2, 3, 3, 4, 5};

* 对部分因素举行开端化

int a[2][3] = { {2}, {3, 4} };

int b[3][3] = { { }, { , , 2}, {1, 2, 3}};

* 若是只初阶化了一部分成分,可以简简单单行数,可是不可以简简单单列数

int a[][3] = {1, 2, 3, 4, 5, 6};

int a[][3] = {{1, 2, 3}, {3, 5}, {}};

有些人唯恐想不亮堂,为啥可以简容易单行数,但不可以不难列数。也有人或者会问,可不得以只指定行数,但是简单列数?

实质上那些题材很简单,如若大家这么写:

int a[2][] = {1, 2, 3, 4, 5, 6}; // 错误写法

大家都领悟,二维数组会先寄存第1行的要素,由于不确定列数,也就是不确定第1行要存放多少个因素,所以那边会时有暴发很七种气象,大概1、2是属于第1行的,也或然1、2、3、4是首先行的,甚至1、2、3、4、5、6全体都是属于第1行的

三维乃至更加多维的数组就不再提及了,大家以此类推。