You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言中*++ptr与++*ptr的差异解析及指定代码输出异常原因咨询

嘿,这俩问题都是C语言指针操作里的经典考点,咱们一个个来拆解清楚!


问题1:C语言中*++ptr++*ptr的区别

要搞懂这俩表达式的差异,核心得记住前缀++*的优先级相同,结合性是从右到左,然后看操作的对象是指针本身,还是指针指向的元素:

  • *++ptr:先移动指针,再解引用

    1. 第一步执行++ptr:把指针ptr自身的地址值加1(让它指向内存中的下一个同类型元素),返回的是更新后的指针。
    2. 第二步对更新后的指针做*解引用,拿到它现在指向的元素的值。
      举个实际例子:
    int nums[] = {10, 20, 30};
    int *ptr = nums;
    printf("%d\n", *++ptr); // 输出20,因为ptr先跳到nums[1],再取对应值
    
  • ++*ptr:先解引用,再修改元素值

    1. 第一步执行*ptr:解引用指针,拿到当前指针指向的元素的数值。
    2. 第二步对这个数值做前缀++,把元素的值加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]

分步执行

  1. ptr++;
    ptr从指向p[0]移动到p[1]。第一个printf输出:1 1 1(这里不是重点,略过细节)

  2. *ptr++;
    后缀++优先级高于*,等价于*(ptr++):先把ptr移动到p[2],再对原来的ptr指向(p[1])解引用(只是读取,无修改)。第二个printf输出:2 2 2

  3. *++ptr;
    前缀++*优先级相同,右结合等价于*(++ptr):先把ptr移动到p[3],再对新的ptr指向(p[3])解引用(读取,无修改)。第三个printf输出:3 3 3

  4. ++*ptr;
    这是关键!前缀++*右结合,等价于++(*ptr)

    • 第一步:*ptrptr指向的p[3],也就是原本指向a[3]的指针(a+3
    • 第二步:对这个指针做++,把p[3]的值改成a+4(现在指向a[4]
    • 注意:ptr本身的指向没变,依然指向p[3]

    所以第四个printf的三个值分别是:

    • ptr-pptr指向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

火山引擎 最新活动