https://zhuanlan.zhihu.com/p/399327901
很久以前就想写一些文章记录一下学习中碰到的种种,但一直忙于他事外加文思枯竭未曾发布文章,近日阅读 Pointers On C (C和指针) 略有所感,聊胜于无
任何比C语言更低级的语言,都不足以完整地抽象一个计算机系统; 任何比C高级的语言,都可以用C来实现。
下标的实现方式
C 中下标引用与其他的语言的下标引用很相似,不过它们的实现方式略有不同。C 的下标值总是从零开始,并且不会对下标值进行有效性检查。除了优先级不同,下标引用操作符和间接访问表达式是等价的。它们的映像关系如下:
array[下标]
*(array + (下标))
下标应用实际上是通过后面这种形式实现的。
数组中的下标引用

int array[10];
int *ap = array + 2;
对指针进行下标引用
在这个例子中 ap[0] 的值为什么呢?
“不能这样做,ap 不是一个数组!” 如果你这样想就大错特错了,根据上文中提出的下标引用的实现方式中可以知道,这个表达式等价于 *(ap+(0)) 即 *(array + 2) 也就是 array[2]
对指针进行负的下标引用
接下来也有一个类似的例子。
ap[-1]
此时的你心中一定有个大大的问号:“为什么会是负的下标?其他语言里面...”
这就是将其他语言中的惯性思维带入到了 C 的学习中。ap 指向数组的第 3 个元素,所以使用偏移量 -1 可以得到它的其哪一个元素,也就是 array[1]。
奇奇怪怪的表达方式
2[array]
尽管你的心中肯定会有许多的疑惑,但是,它是合法的!
根据下标引用的实现方式,把它转换成对等的间接访问表达式,你就会发现其中的奥妙
*(2 + (array))
内括号其实是冗余的,而且加法操作符的两个操作时是可以交换位置的,所以它等价于:
*(array + 2)
也就是说: 2[array] 与 array[2] 是等价的。
这个方式是可行的,对编译器来说这两种形式没有什么差别,但是会严重影响程序的可读性。
指针与下标的效率问题
如果可以互换地使用指针表达式和下标表达式,应该选择哪一种方式?
假定这两种方式都是正确的,下标绝对不会比指针更有效率,但指针有时会比下标更有效率。
下标表达式:
int array[10], a;
for (a = 0; a < 10; a += 1;)
array[a] = 0;
指针表达式:
int array[10], *ap;
for (ap = array; ap < array + 10; ap++)
*ap = 0;
这两种实现方式就结果而言并无不同,但是问题来了,哪一种方式的效率更高?
指针表达式
在下标表达式中,为了对下标表达式求值,编译器在程序中插入指令,取得 a 的值,并把它与整型的长度(也就是 4)相乘。而对于指针表达式来说,只需要 1 这个值与整型的长度相乘,然后再与指针相加。这个乘法只需要在编译时进行一次。
所以使用指针表达式将会更加节省时间和空间。
704

被折叠的 条评论
为什么被折叠?



