指针的前加加和后加加运算
前加加和后加加
前加加和后加加的区别就是先自增还是先参与运算。顾名思义,后加加就是先参与运算,在进行自增。先加加就是先进行自增,再参与运算。
以下面的代码为例:
int i = 1, j = 1;
int num1 = 0, num2 = 0;
num1 = i++; // 先赋值,再自增
num2 = ++j; // 先自增,再赋值
printf("num1=%d\n", num1);
printf("num2=%d\n", num2);
printf("i=%d\n", i);
printf("j=%d\n", j);
它的输出结果是:
num1=1
num2=2
i=2
j=2
对于num1=i++
,可以拆分为两步,第一步是i
先参与赋值运算num1=i
,第二步是i
进行自增,i=i+1
。所以,结果是num1=1
,i=2
;
对于num2=++j
,第一步是先进行自增j=j+1
,第二步是参与运算num2=j
。所以,结果是num2=2
,j=2
。
下面的例子同理:
int m = 1, n = 1;
printf("m++:%d\n", m++); // 先输出,再自增
printf("++n:%d\n", ++n); // 先自增,再输出
printf("m=%d\n", m);
printf("n=%d\n", n);
输出:
m++:1
++n:2
m=2
n=2
下面是前加加和后加加为一条单独的语句,h
和k
都已经自增结束了,然后才输出。
int h = 1, k = 1;
h++; // 自增
++k; // 自增
printf("h=%d\n", h);
printf("k=%d\n", k);
输出:
h=2
k=2
*p++
因为++
运算符的优先级要大于*
运算符,等价于*(p++)
。
但是这是后加加,有了上面的分析,我们可以知道,它会先进行*
操作,取出指针的内容,然后再对指针进行自增。
以下面的代码为例:
int a[10] = {1, 2, 3, 4, 5, 6};
int *p = a;
printf("此时p指向的地址是:%d\n", p);
printf("*p=%d\n", *p); // p指向首元素的地址
printf("此时p指向的地址是:%d\n", p); // 便于观察,再次输出一次地址
printf("*p++=%d\n", *p++); // 输出的是首元素的内容,然后指针自增
printf("此时p指向的地址是:%d\n", p); // 指针已经完成了自增,地址改变
输出:
此时p指向的地址是:7077360
*p=1
此时p指向的地址是:7077360
*p++=1
此时p指向的地址是:7077364
可以看到*p++
的内容是1,然后指针进行了自增,因为int
类型是4个字节,所以地址加的数是4。(指针是根据所指向的变量类型大小自增的,不是简单地加1。)
*++p
同理,因为++
的优先级大于*
,*++p
等价于*(++p)
。是前加加,这里就是先进行指针的自增操作,再取出指针指向地址的内容。
示例:
int a[10] = {1, 2, 3, 4, 5, 6};
int *p = a;
printf("此时p指向的地址是:%d\n", p);
printf("*p=%d\n", *p);
printf("此时p指向的地址是:%d\n", p);
printf("*++p=%d\n", *++p); // 指针自增,然后取值
printf("此时p指向的地址是:%d\n", p);
输出:
此时p指向的地址是:7077360
*p=1
此时p指向的地址是:7077360
*++p=2
此时p指向的地址是:7077364
可以看到*++p
是2,同样指针也完成了自增的操作。
++*p
这个其实++
操作的对象就不是指针了,因为++
和指针p
之间还有个*
运算符。++
是不能跳过这个*
运算符对p
进行操作的。++
是对*p
进行自增。等价于++(*p)。
所以,我们只有知道p
指向的地址里面存储的内容,再对它进行前加加操作。
示例:
int a[10] = {1, 5, 7, 8, 9, 11};
int *p = a;
printf("此时p指向的地址是:%d\n", p);
printf("*p=%d\n", *p);
printf("此时p指向的地址是:%d\n", p);
printf("++*p=%d\n", ++*p); // 取值,对取出来的值自增
printf("此时p指向的地址是:%d\n", p);
输出:
此时p指向的地址是:7077360
*p=1
此时p指向的地址是:7077360
++*p=2
此时p指向的地址是:7077360
可以看到,p
指向的地址始终都没用改变。
(*p)++
这里使用括号,提升了*
运算符的优先级,就是先取值,然后对取出来的值进行后加加。未改变指针指向的地址。
int a[10] = {1, 5, 7, 8, 9, 11};
int *p = a;
printf("此时p指向的地址是:%d\n", p);
printf("*p=%d\n", *p);
printf("此时p指向的地址是:%d\n", p);
printf("(*p)++=%d\n", (*p)++); // 注意是后加加,所以输出的是为自增的值
printf("此时p指向的地址是:%d\n", p);
输出:
此时p指向的地址是:7077360
*p=1
此时p指向的地址是:7077360
(*p)++=1
此时p指向的地址是:7077360
要注意这里是后加加,所以输出的值是1。如果是前加加,也就是++(*p)
,那么这里输出的就是2了。