对于编译器而言,一个数组就是一个地址,一个指针就是一个地址的地址。
什么时候数组和指针是相同的:
1、表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针(在表达式中,指针和数组是可以互换的,因为它们在编译器里的最终形式都是指针,并且都可以去下标操作.例对数组的引用如a[i]在编译时总是被编译器改写成*(a+i)的形式);
2、下标总是与指针的偏移量相同;
3、在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针。
另外,对第一点的解释:存在几个极少见的例外,就是把数组当作一个整体来使用。
如下列情况:
1、数组作为sizeof的操作数-显然 此时需要的是整个数组的大小,而不是指向第一个元素的大小;
2、使用&操作符取数组的地址(原因:一个数组就是一个地址,一个指针就是一个地址的地址);
3、数组是一个字符串(或宽字符串)常量初始值。
编译器自动把下标值的步长调整到数组元素的大小。
对起始地址执行加法操作之前,编译器会负责计算每次增加的步长。这就是为什么指针总是有类型限制,每个指针只能指向同一种类型的原因所在-因为编译器需要知道对指针进行解除引用操作时应该取几个字节,以及每个下标的步长应取几个字节。
步长计算方法:偏移量乘以每个数组元素所占字节数,计算结果就是偏移数组起始地址的实际字节数。步长因子常常是2的乘方(如int是4个字节,double是8个字节)这样编译器在计算时就可以使用快速的左移位运算,而不是相对缓慢的加法运算。
C语言把数组下标改写成指针偏移量的根本原因是是真和偏移量是底层硬件所使用的基本模型。亦即是,在底层硬件中,都是使用指针来访问数据的(如前面说的,编译器都会把改写成指针形式)。
对于多维数组的方位ca[i][j],编译为*(*(ca+i)+j)。
只有字符串常量才可以初始化指针数组,指针数组不能由非字符串的类型直接初始化。
int (*ga)[20] 是被翻译成一个指向20个元素的的int数组的指针,而不是一个20个指针元素的数组。
也可以参考本博博文 多维数组(数组的数组)及指针对其访问:http://www.cnblogs.com/ziwuge/archive/2011/06/11/2078567.html
快捷操作:
坚其志,苦其心,劳其力,事无大小,必有所成。
@如有侵权,请作者本人尽快与我(chrayo#163.com)联系,我将及时删除侵权内容。