C 中下标与指针杂谈

C 中下标与指针杂谈

很久以前就想写一些文章记录一下学习中碰到的种种,但一直忙于他事外加文思枯竭未曾发布文章,近日阅读 Pointers On C (C和指针) 略有所感,聊胜于无

任何比C语言更低级的语言,都不足以完整地抽象一个计算机系统; 任何比C高级的语言,都可以用C来实现。

下标的实现方式

C 中下标引用与其他的语言的下标引用很相似,不过它们的实现方式略有不同。C 的下标值总是从零开始,并且不会对下标值进行有效性检查。除了优先级不同,下标引用操作符和间接访问表达式是等价的。它们的映像关系如下:

array[下标]

*(array + (下标))

下标应用实际上是通过后面这种形式实现的。

数组中的下标引用

image

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 这个值与整型的长度相乘,然后再与指针相加。这个乘法只需要在编译时进行一次。

所以使用指针表达式将会更加节省时间和空间。

本文同步发布于本人的个人博客:诺念的小站

博客中的地址:C 中下标与指针杂谈

相关推荐

近泊乐共享充电桩:开启绿色出行新生态,破解充电难题的智慧方案
数说点球对决(2022年卡塔尔世界杯特别报道)
mobile365sport365

数说点球对决(2022年卡塔尔世界杯特别报道)

📅 08-03 👁️ 9110
对不起!我的朋友圈屏蔽了你
mobile365sport365

对不起!我的朋友圈屏蔽了你

📅 08-05 👁️ 4377