一维数组的声明: int a[10]; 这里a就是一个数组. 数组a的类型就是一个指向整型的常量指针.
但是数组和指针是**不相同**的.
**数组具有特定数量的元素,而指针只是一个标量值.**
只有但数组名在表达式中使用时,编译器才会为它产生一个指针常量.(注意是指针常量,不是指针变量)
如有 int b[10];
则 *(b + 3) 代表的就是b[3]
除了优先级之外,下标引用和间接访问完全相同
所以 array[subscript] 和 (array + (subscript) ) 完全相同.在使用下标引用的地方,你可以使用对等的指针表达式来代替.
下标可以是负数
如:
int array[10];
int ap = array + 2;
由于ap 指向array 的第三个元素, ap[-1] 指向 array的第二个元素.
下标一定越界
ap[9] 是非法的.
一个奇葩 2[array]
它是合法的,把它转换成对等的间接访问表达式,为 (2 + (array) ) ,去掉内括号,交换 array 和 2 的位置, 得 (array+ 2). 也就是array[2]
假定可以互换使用指针和下标.下标绝对不会比指针更有效率,但指针有时会比下标更有效率.
比较编译器对指针和下标的处理过程.:
//下标循环
int array[10], a;
for(a = 0; a < 10; a +=1)
array[a] = 0;
为了对下标表达式求值,编译器在程序中插入指令,取得 a 的值,并把它与整型的长度(4)相乘.这个乘法需要话费一定的时间和空间.
//指针
int array[10], *ap;
for( ap = array; ap < array + 10; ap++)
*ap = 0;
尽管这里不存在下标计算,但是还是存在乘法运算.乘法运算出现在for语句的调整部分, ap++ 中这个值必须与整型的长度相乘.然后再与指针相加.
但这里在循环每次执行的时,执行乘法运算的都是两个相同的数(1和4, 步长和整型元素长度). 结果这个乘法只是在编译时执行一次,即程序中现在包含来一条指令,把4与指针相加,程序在运行时并不执行乘法运算.
原文:https://www.cnblogs.com/wjw-blog/p/10414225.html