这篇文章中,我们来讨论一下指针的算术运算。在C语言中支持3种格式的指针算术运算,而且只有三种:
- 指针加上整数
- 指针减去整数
- 两个指针相减
指针加上整数
指针p加上整数j指向特定元素的指针,这个特定元素是p原先指向的元素后的j个位置。更确切地说,如果p
指向数组元素a[i]
,那么p+j
指向a[i+j]
。因为通常情况下,指针就是地址,我们下面就用地址来解释其中的运算原理。
假设指针p
指向int
类型的数组a[9]
,执行p+3
的操作就会得到Xp+3*4
的地址(Xp表示指针p的地址,即p所表示的值;4为int
型的大小,这里假设int型的大小为4)。因此,其计算公式为:Xp+i*L,其中Xp为指针的地址,i为加数,L为类型的大小。
NOTE:当将指针从一种类型强制转换成另一种类型时,就会有所不同。例如如果p是一个char*
的指针,它的值为Xp,那么表达式(int *)p+7
的计算结果为Xp+7*4(我们要知道强制类型转换的优先级高于加法),而(int *)(p+7)
的计算结果为Xp+7。
指针减去整数
如果p
指向数组元素a[i]
,那么p-j
指向a[i-j]。其中的原理和指针加上整数类似,这里就不再赘述了。
两个指针相减
当两个指针相减时,结果为指针之间的距离(用数组元素的个数来度量)。因此,如果p
指向a[i]
且q
指向a[j]
,那么p-q
就等于i-j
。
NOTE:不存在两个指针相加的算术运算。
++/–运算
在for
循环中我们经常会用到++
或者--
运算,根据前面的知识,我们不难猜到指针也是支持这样的运算的。下面我以++
为例进行讲解。
对于一个指针p
执行p++
的话,就相当于对指针进行加一操作p=p+1
,++p
也是一样的。和我们以前学习的一样,++
放在前面与放在后面效果是不一样的:前者是先赋值,然后再自增;后者是先自增,后赋值。下面我们来看几个例子:
*p++ = j; // 先将j赋给p指向的值(*p),然后再对指针进行自增
(*p)++; // 自增前值为*p,之后对指针p指向的值进行自增
*++p = j; // 先对指针进行自增,然后再对自增后的指针指向的值(*(p+1))赋值j
++*p; // 先对指针指向的值进行自增,之后的值为(*p)+1
我们要知道后缀++
符号的优先级高于*
,所以*p++ = j
相当于*(p++)
。
指针比较
这里我们顺便介绍下指针比较。我们可以用关系运算符<、<=、>、>=和判等符==和!=进行指针比较,比较的结果依赖于数组中两个元素的相对位置。
NOTE:后两种运算中,只有两个指针指向同一数组时,才有意义。
参考资料
- C语言程序设计现代方法, K.N.King, 人民邮电出版社
- 深入理解计算机系统, 卡内基梅隆大学,机械工业出版社
- David8631的CSDN博客:i++和++i的区别
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。