C语言中*++ptr与++*ptr的差异解析及指定代码输出异常原因咨询
嘿,这俩问题都是C语言指针操作里的经典考点,咱们一个个来拆解清楚!
问题1:C语言中
*++ptr与++*ptr的区别 要搞懂这俩表达式的差异,核心得记住前缀++和*的优先级相同,结合性是从右到左,然后看操作的对象是指针本身,还是指针指向的元素:
*++ptr:先移动指针,再解引用- 第一步执行
++ptr:把指针ptr自身的地址值加1(让它指向内存中的下一个同类型元素),返回的是更新后的指针。 - 第二步对更新后的指针做
*解引用,拿到它现在指向的元素的值。
举个实际例子:
int nums[] = {10, 20, 30}; int *ptr = nums; printf("%d\n", *++ptr); // 输出20,因为ptr先跳到nums[1],再取对应值- 第一步执行
++*ptr:先解引用,再修改元素值- 第一步执行
*ptr:解引用指针,拿到当前指针指向的元素的数值。 - 第二步对这个数值做前缀
++,把元素的值加1,返回的是加1后的数值。
同样用上面的例子:
int nums[] = {10, 20, 30}; int *ptr = nums; printf("%d\n", ++*ptr); // 输出11,因为先取nums[0]的10,再加1;ptr本身的指向没变划重点:这个操作不会改变指针
ptr的指向,只会修改它指向的元素的值。- 第一步执行
问题2:为什么代码最后输出
3 4 4而非预期的4 4 4? 咱们先把初始化的变量关系理清楚,再一步步跟踪每一行的执行:
初始状态
int a[] ={0,1,2,3,4}; // a数组:a[0]=0, a[1]=1, ..., a[4]=4 int *p[] = {a,a+1,a+2,a+3,a+4}; // p是指针数组:p[0]指向a[0], p[1]指向a[1], ..., p[4]指向a[4] int **ptr= p; // ptr是指向指针的指针,初始指向p[0]
分步执行
ptr++;ptr从指向p[0]移动到p[1]。第一个printf输出:1 1 1(这里不是重点,略过细节)*ptr++;
后缀++优先级高于*,等价于*(ptr++):先把ptr移动到p[2],再对原来的ptr指向(p[1])解引用(只是读取,无修改)。第二个printf输出:2 2 2*++ptr;
前缀++和*优先级相同,右结合等价于*(++ptr):先把ptr移动到p[3],再对新的ptr指向(p[3])解引用(读取,无修改)。第三个printf输出:3 3 3++*ptr;
这是关键!前缀++和*右结合,等价于++(*ptr):- 第一步:
*ptr是ptr指向的p[3],也就是原本指向a[3]的指针(a+3) - 第二步:对这个指针做
++,把p[3]的值改成a+4(现在指向a[4]) - 注意:
ptr本身的指向没变,依然指向p[3]
所以第四个
printf的三个值分别是:ptr-p:ptr指向p[3],和p的起始地址差3个元素,输出3*ptr-a:*ptr现在是a+4,和a的起始地址差4个元素,输出4**ptr:解引用a+4得到a[4]=4,输出4
最终这行输出就是3 4 4,而你预期的4 4 4是误以为++*ptr会让ptr本身移动到p[4],但实际上++作用的是p[3]这个指针变量,而非ptr本身。
- 第一步:
内容的提问来源于stack exchange,提问作者Kushagra Sinha




