C 中 *ptr += 1 和 *ptr++ 的区别

Difference between *ptr += 1 and *ptr++ in C

我刚开始学C,在做一个关于将指针传递给指针作为函数参数的例子时,我发现了一个问题。

这是我的示例代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int* allocateIntArray(int* ptr, int size){
    if (ptr != NULL){
        for (int i = 0; i < size; i++){
            ptr[i] = i;
        }
    }
    return ptr;
}

void increasePointer(int** ptr){
    if (ptr != NULL){
        *ptr += 1; /* <----------------------------- This is line 16 */
    }
}

int main()
{
    int* p1 = (int*)malloc(sizeof(int)* 10);
    allocateIntArray(p1, 10);

    for (int i = 0; i < 10; i++){
        printf("%d\n", p1[i]);
    }

    increasePointer(&p1);
    printf("%d\n", *p1);
    p1--;
    free(p1);
    fgets(string, sizeof(string), stdin);
    return 0;
}

问题出现在第16行,当我将*ptr+=1修改为*ptr++时。预期结果应该是整个数组和数字 1,但是当我使用 *ptr++ 时,结果是 0。

+=1++有区别吗?我以为他们两个是一样的。

不同之处在于运算符优先级。

post 递增运算符 ++ 的优先级高于解引用运算符 *。所以 *ptr++ 等价于 *(ptr++)。换句话说,post 增量修改指针,而不是它指向的内容。

赋值运算符 += 的优先级低于取消引用运算符 *,因此 *ptr+=1 等同于 (*ptr)+=1。换句话说,赋值运算符修改了指针指向的值,并没有改变指针本身。

您问题中涉及的 3 个运算符的优先顺序如下:

post-增量++ > 解引用* > 赋值+=

您可以查看此 page 以了解有关该主题的更多详细信息。

When parsing an expression, an operator which is listed on some row will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further below it. For example, the expression *p++ is parsed as *(p++), and not as (*p)++.

长话短说,为了使用 post 递增运算符来表达此赋值 *ptr+=1,您需要向取消引用运算符添加括号,以使该运算优先于 ++就像这个 (*ptr)++

让我们用括号来显示 order of operations

a + b / c
a + (b/c)

让我们再做一次

*ptr   += 1
(*ptr) += 1

再次与

*ptr++
*(ptr++)
  • *ptr += 1中,我们将我们的指针指向的变量的值递增到。
  • *ptr++ 中,我们在 整个语句(代码行)完成后递增指针 ,并且 return 对变量 our 的引用指针指向到.

后者允许您执行以下操作:

for(int i = 0; i < length; i++)
{
    // Copy value from *src and store it in *dest
    *dest++ = *src++;

    // Keep in mind that the above is equivalent to
    *(dest++) = *(src++);
}

这是将一个src数组复制到另一个dest数组的常用方法。

很好的问题。

在K&R "C programming language"“5.1指针和地址”中,我们可以得到答案。

"The unary operators * and & bind more tightly than arithmetic operators"

*ptr += 1      //Increment what ptr points to.

"Unary operators like * and ++ associate right to left."

*ptr++        //Increment prt instead of what ptr point to.

//像*(ptr++).

正确的方法是:

(*ptr)++      //This will work.

*ptr += 1 :增加ptr指向的数据。 *ptr++ : 递增指向下一个内存位置的指针,而不是指针指向的数据。