数组的初始化
int ages[3] = {0};
int ages[3] = {4, 6, 9};
int nums[10] = {1,2}; // 其余的自动初始化为0
int nums[] = {1,2,3,5,6}; // 根据大括号中的元素个数确定数组元素的个数
int nums[5] = {[4] = 3,[1] = 2}; // 指定元素个数,同时给指定元素进行初始化
int nums[3]; nums[0] = 1; nums[1] = 2; nums[2] = 3; // 先定义,后初始化
定义但是未初始化,数组中有值,但是是垃圾值。
对于数组来说,一旦有元素被初始 化,其他元素都被赋值0。
计算数组中元素的个数
int count = sizeof(数组) / sizeof(数组[0]) // 数组的长度 = 数组占用的总字节数 / 数组元素占用的字节数
在定义数组的时候[]里面只能写整型常量或者是返回整型常量的表达式,[]中不能放变量。
int length = 10;
int Array[length ]; // 不报错, 但是没有初始化, 里面是随机值
int length = 10;
int Array[length ] = {19, 22, 33} // 直接报错
int Array[5];
Array= {19, 22, 33}; // 错误。只能在定义数组的时候进行一次性(全部赋值)的初始化
#define length 10
int Array[length] = {0}; //正确
数组作为函数参数
当数组名作为函数参数时, 因为自动转换为了指针类型,所以在函数中无法动态计算除数组的元素个数。
在64位编译器下,指针类型默认为8个字节。
有的时候我们可能想要在一个函数里面动态计算数组的个数,所以可能会这么做:
void printMyArray(int myArray[]) {
int length = sizeof(myArray) / sizeof(myArray[0]);
for(int i = 0; i < length; i++) {
printf("%i", myArray[i]);
}
}
int main() {
int myArray[5] = {1,2,3,4,5};
printMyArray(myArray);
return 0;
}
可以看到在printMyArray函数中我们动态计算传进来的数组的个数,但是结果是错误的,因为它只能输出前两个数。
这是因为,在把数组当成函数的参数的时候,数组会被认为成指针,所以是8个字节,所以计算出的length是2,所以只能输出前两个数字。
解决:我们需要给出一个新的参数来获得length,在main()里面计算好length然后传入printMyArray。
void printMyArray(int myArray[], int length) {
for(int i = 0; i < length; i++) {
printf("%i ", myArray[i]);
}
}
int main(int argc, const char * argv[]) {
int myArray[5] = {1,2,3,4,5};
int length = sizeof(myArray) / sizeof(myArray[0]);
printMyArray(myArray, length);
return 0;
}
数组地址计算
首先假设一个int类型一维数组arr[4], arr的地址是0x00; 那么arr +1是多少呢?
arr是这个数组首元素地址==&arr[0],
无论&什么什么+1 就是&符号后面的内容占据的地址单元数+指针起始位置 arr[0]占据4地址单元
所以:
arr +1 == &arr[0]+1 =4+0x00=0x04;
arr +2 == &arr[0]+2 =8+0x00=0x08;
而 &arr+1 = 0x10; 这里&后面arr是个数组名就可以当成是arr这整个数组占据的地址单元数+地址.它占据16个地址单元
所以:
&arr+ 1=16+ 0x00= 0x10.
&arr+ 2=32+ 0x00= 0x20.
一维数组中各元素也是如此,arr[0]+1等于 arr[1]同样适用,arr[0]是int 类型在内存中占用四个字节,所以+1也是跳到第5个字节就是arr[1]的字节那儿,所以就是arr[1]了。
数组和指针
C语言中 int*p[4] 和 int(*p)[4]的区别
int *p[4]; //定义一个指针数组,该数组中每个元素是一个指针,每个指针指向哪里就需要程序中后续再定义了。
int (*p)[4]; //定义一个数组指针,该指针指向含4个元素的一维数组(数组中每个元素是int型)。
区分int *p[n]; 和int (*p)[n]; 就要看运算符的优先级了。
int p[n]; 中,运算符[ ]优先级高,先与p结合成为一个数组,再由int说明这是一个整型指针数组。
int (*p)[n]; 中( )优先级高,首先说明p是一个指针,指向一个整型的一维数组。
int b[2];
int *a;
a=b; //a指向数组b首地址,暨b[0]的地址
*a + 1 // *a就是取a指向地址的值,暨b[0],所以*a+1 == b[0]+1
*(a+1) // a+1,指针+1,就是指针指向下一个地址,暨b[1]的地址,所以*(a+1)== b[1]