【问题标题】:C Incrementing pointer address passed to a function ++ operatorC递增指针地址传递给函数++运算符
【发布时间】:2021-12-27 19:17:20
【问题描述】:

我对此讨论提出了一个问题:C - modify the address of a pointer passed to a function

假设我有以下代码:

#include <stdio.h>
foo(char **ptr){
    *ptr++;
}

int main()
{

    char *ptr = malloc(64);
    char arr[] = "Hello World!";
    memcpy(ptr, arr, sizeof(arr)); 
    foo(&ptr);
    foo(&ptr);
    printf("%s",ptr);
    return 0;
}

我想知道这个程序的输出是什么,我想应该是llo World!。

经过一番调查,我发现了上面链接的问题,并意识到在 C 中,函数的参数总是通过 value 传递。到目前为止没有任何问题。将*ptr++; 表达式更改为-> *ptr = *ptr +1; 输出变为:llo World!。

在这一点上,我可以说我有点困惑。为了改变指针地址,我们需要一个双指针。这很好,但为什么后增量操作会有所不同?是不是因为运算符优先级?

Here我在在线 C 编译器中尝试了该示例。

【问题讨论】:

    标签: c pointers pass-by-reference post-increment


    【解决方案1】:

    后缀递增运算符++ 的优先级高于取消引用运算符*。所以这个:

    *ptr++;
    

    解析为:

    *(ptr++);
    

    所以它改变了参数值本身,而不是它指向的东西。你反而想要:

    (*ptr)++;
    

    【讨论】:

    • @asevindik prefix 增量与取消引用具有相同的优先级。 后缀更高。
    • 我会将此评论标记为已接受的答案。但是,正如下面其他人所说,++*ptr 也是解决此问题的另一种方法。对我来说,更好更清晰的说法是*ptr = *ptr+1;Thanks!
    【解决方案2】:

    后缀运算符的优先级高于一元运算符。所以这个表达式

    *ptr++
    

    等价于

    *( ptr++ )
    

    子表达式ptr++的值是指针递增前的值。

    所以实际上你正在递增具有char ** 类型的参数ptr。所以这个递增不会改变原来的指针,没有意义。

    你可以写

    ( *ptr )++
    

    但是像这样使用一元自增操作符会更清晰,更不容易混淆

    ++*ptr
    

    如果你想增加原始指针本身。

    【讨论】:

      【解决方案3】:

      正如其他人所解释的,++ 比* 更重要(具有更高的优先级),因此您的函数foo 实际上编译为:

      foo (char **ptr) {
          ptr = ptr + 1; // This modifies the parameter, which is a copy of a variable, copied *specifically* for this function; hence, modifying it will have no effect outside of the function.
          *ptr; // This is just an expression; it doesn't actually do anything, as the compiler would tell you if you wrote it this way.
      }
      

      如果你把*ptr++改成(*ptr)++,函数会这样工作:

      foo (char **ptr) {
          *ptr = *ptr + 1; // Sets the variable pointed to by ptr to be equal to itself plus one.
      }
      

      【讨论】:

        猜你喜欢
        • 2020-01-09
        • 2015-02-16
        • 2019-07-26
        • 1970-01-01
        • 1970-01-01
        • 2013-05-14
        • 1970-01-01
        • 2012-02-22
        • 2021-01-05
        相关资源
        最近更新 更多