前言
前面在“走进指针世界”中我已经讲解过指针相关的很多前置知识,其实还有一个很重要的部分就是指针的运算。这篇博客,就让我们一起了解一下指针的运算吧!
指针作为变量,是可以进行算术运算的,只不过情况会和整型变量、浮点型变量有所不同,比较特殊。
当指针指向一个数组时,C语言是允许对指针进行算术运算的,往往是加法或减法,这给我们提供了一种数组下标以外的对数组进行处理的方式。
指针的算术运算
我们知道,指针可以指向数组元素:
int arr[10],*p;//创建一个整型数组和整型指针
p = &arr[0];//让p指向arr[0]
我现在告诉你,通过指针算数运算,我们可以通过p访问数组arr的其他所有元素。
指针加整数:
我们给指针p加上一个整数m,得到的就是p原先指向的元素后的m个位置。结合上面的代码具体来说,我们有p指向元素arr[0],p+m就指向arr[0+m]也就是arr[m],推广到一般情况就是如果p指向arr[i],p+m就指向arr[i+m]。
现在我再画个图,来更形象地理解指针的加法运算:
当然,也可以让p自己向后移动:
p+=6;即(p=p+6),会发生什么?
指针减整数:
其实和指针加整数道理类似:当p指向数组元素arr[i],p-m就指向arr[i-m],画出的示意图也是类似的:
当然,也可以让p自己向前移动:
p-=6;即(p=p-6),会发生什么?
两个指针相减:
其实,当两个指针指向同一个数组的时候(如果不是指向同一个数组,相减也就没有意义了),它们可以相减, 它们相减得到的绝对值是这两个指针之间元素的个数(而不是具体的p和q存储的地址数值的差值)。
当p指向arr[i],q指向arr[j],p-q其实就会等于i-j,我们还是可以画图说明:
你可能会发现在这一次画图的时候,我特意把q和p的箭头画到了指向元素空间的最前方,一方面是为了更好展示出相差4个元素的效果,另一方面这其实是更准确的画法,因为我们知道内存中每个字节对应一个地址编号,而指针中存的就是地址编号,我们的p和q是指向int类型的指针,一个int类型一般占4个字节,所以我们其实存的是第一个字节的地址,所以指向最前方是更精确的画法。
指针比较:
我们其实可以用关系运算符(<、<=、>、>=)和判等运算符 (==、!=)来进行指针的比较。同样的,只有两个指针指向同一个数组时,用关系运算符进行指针比较才有意义。那么比较的结果应该是什么样的呢?
其实比较的是两个指针指向的元素在数组中的相对位置。如:
p = &arr[6];
q = &arr[1];
此时我们的p<=q的值为0(假),p>=q的值则是1(真)。
两个指针比较,可能出现的场景举例:
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = &arr[0];
while (p < &arr[sz])//或写为p<arr+sz
{
printf("%d ", *p);
p++;
}
return 0;
}
vs运行结果:
这里&arr[sz]或者arr+sz是地址,而地址也就是指针,所以p<&arr[sz]其实就是指针的比较。
那么到此指针的运算就讲解完了,希望大家阅读愉快^_^