C递增指针地址传递给函数++运算符

C Incrementing pointer address passed to a function ++ operator

我从这个讨论中提出了一个问题: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!.

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

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

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

*ptr++;

解析为:

*(ptr++);

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

(*ptr)++;

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

*ptr++

相当于

*( ptr++ )

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

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

你可以这样写

( *ptr )++

但是使用像

这样的一元递增运算符会更清晰,更不容易混淆
++*ptr

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

正如其他人所解释的,++* 更重要(具有更高的优先级),因此您的函数 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.
}