1.一种初始化数组的方法
int array[] = {1, 3, 5, 7, 9}; //编译器根据花括号内元素的数目自动确定数组的大小
需要注意的是:不允许在初始化之外的任何地方使用花括号对数组进行赋值,如
int array[4];
array[4] = {2, 4, 6, 8}; //错误
2.快速获得数组长度的方法
int a[5];
int b[] = {1, 2, 3, 4, 5};
int * c = (int *)malloc(5*sizeof(int));
printf("%d, %d, %d\n", sizeof(a)/sizeof(int), sizeof(b)/sizeof(int), sizeof(c)/sizeof(int)); //打印结果为5, 5, 1
Tips:sizeof返回操作数所占字节数
3.另一种初始化数组的方法:可以制定任意位置的元素进行单个初始化,其余元素默认初始化为0,如
int array[5] = { [4] = 9 }; //将array[4]初始化为9,其余默认为0
int array[5] = { [2] = 5, 7, 9 }; //将array[2]初始化为5,array[3]初始化为7,array[4]初始化为9
4.C中不允许将一个数组直接整体赋值给另一个数组,如
int array1[4] = {1, 2, 3, 4};
int array2[4];
array2 = array1; //错误
5.编译器不对数组越界进行检查,因此编译通过的程序在运行时可能会报段错误(segment fault)
6.声明数组时,数组大小必须用整型常量或整型常量表达式来表示(包括预编译命令#define,但不包括const)
7.二维数组的一种初始化方法:
int dArray[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
Tips:花括号内数量若不足的话,默认初始化为0
8.数组名也是数组首元素的地址,即array == &array[0]
9.C中,对指针加1的结果是对该指针增加一个存储单元,而不是增加一个字节
可以从两方面理解记忆这个设计:
1)为指针声明指针类型,正是为了使编译器知道+1时需要步进的字节数
2)上述设计与数组索引相印证,即*(array+n)等价于array[n]
10.处理数组的函数实际上是使用指针作为参数的。以下两种函数原型是等价的:
int sum(int [], int);
int sum(int *, int);
11.对数组的遍历除了传递指向数组头部的指针和数组长度这一方法之外,还有另一种方法,即传递两个指针,分别指向数组的头和尾
12.C保证在为数组分配存储空间的时候,指向数组之后的第一个位置的指针也是合法的,但不保证该位置内存储的内容
13.虽然数组名和首元素指针变量是等价的,但++这种自增操作只能用于指针变量
14.两指针相减获得对应元素之间的距离,如:
int * pt1 = array;
int * pt2 = &array[4]; //等价于int *pt2 = array+4;
printf("%d", pt2-pt1); //结果为4
Tips:进行相减运算的前提是这两个指针均指向同一个数组
15.如果函数想修改数组,那么在声明数组参量时不要使用const;如果函数不需要修改数组,那么在声明数组参量时应使用const
使用const并不要求原始数组是固定不变的,这只是说明函数在处理数组时,应把数组当做固定不变的
延伸:形参和实参的const限制可以不同,见另一文章《关于const与参数传递的讨论》
16.一般地,声明N维数组参量,除最左边的方括号可以留空外,其他都需要填写数值,如:
int sum4d(int ar[][12][20][30], int n);