1.什么时候数组和指针相同
图1 指针和数组何时相同
2.c标准中的数组规定
规则1:"表达式中的数组名"就是指针
编译器自动把下标值的步长调整到数组元素的大小。如果数组元素的大小是4字节,那么a[i]和a[i+1]在内存中的距离就是4。对起始地址执行加法之前,编译器会负责计算每次增加的步长。这就为什么指针总是有类型限制的,每个指针只能指向一个类型的原因所在:编译器需要知道对指针进行解引用操作时应该取几个字节,以及每个下标的步长应取几个字节。
规则2:c语言把数组下标作为指针的偏移量
规则3:“作为函数参数的数组名”等同于指针
在函数形参定义这个特殊情况下,编译器必须把数组形式改成指向数组第一个元素的指针形式,编译器只向函数传递数组的地址,而不是整个数组的拷贝。
例如:定义函数
在func函数的调用上,实参是数组和指针都是合法的void func(int *ptr){...} void func(int ptr[]){...} void func(int ptr[20]){...}
3.数组和指针的可交换性的总结
1)用a[i]这样的形式对数组进行访问总是被编译器解释为像*(a+i)这样的指针访问。
2)指针始终是指针。它绝不可以改成数组,你可以用下标形式访问指针,一般都是指针作为函数参数时,而且你知道实际传递给函数的是一个数组。3)把一个数组定义为函数的参数时,可以选择把它定义为数组,也可以定义为指针;不管是哪种,在函数内部获得的都是一个指针。4)在其他所有情况中,定义和声明必修匹配。如果定义了一个数组,在其它文件对它进行声明时也必须把它声明为数组,指针也是如此。
4.多维数组的内存布局
在C语言中数组的元素可以是另一个数组,有助于数组的分解,例如声明如下的三维数组:
int array[2][3][5]
图 2 整个数组的内存
图 3 sizeof[i]的内存空间
图4 sizeof[i][j]的内存空间
再如:图 5 sizeof[i][j][k]的内存空间
有人把二维数组看作是排列在一张表格中的一行行的一维数组,如下:
char ch[4][3];
图 6 假想的内存分布
实际的内存分布如下:
图 7 实际内存分布
char b[2][2];