C 语言中的 *ptr += 1 和 *ptr++ 之间的区别



我刚刚开始研究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("%dn", p1[i]);
    }
    increasePointer(&p1);
    printf("%dn", *p1);
    p1--;
    free(p1);
    fgets(string, sizeof(string), stdin);
    return 0;
}

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

+=1++之间有什么差异吗?我以为它们都是一样的。

差异是由于运算符优先级造成的。

后增量运算符++的优先级高于取消引用运算符*。所以*ptr++相当于*(ptr++).换句话说,帖子增量修改指针,而不是它指向的内容。

赋值运算符+=的优先级低于取消引用运算符*,因此*ptr+=1等价于 (*ptr)+=1 。换句话说,赋值运算符修改指针指向的值,并且不会更改指针本身。

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

后递增++>取消引用*>分配+=

您可以查看此页面以获取有关该主题的更多详细信息。

解析表达式时,与在其下方的行上列出的任何运算符相比,列在某行上的运算符与其参数的绑定更紧密(就像用括号一样)。例如,表达式 *p++ 被解析为 *(p++) ,而不是 (*p)++

长话短说,为了使用后递增运算符表示此赋值*ptr+=1,您需要在取消引用运算符中添加括号,以使该操作优先于++,如本(*ptr)++

让我们应用括号来显示操作顺序

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

让我们再做一次

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

再一次

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

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

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编程语言"5.1指针和地址"中,我们可以得到答案。

"一元运算符 * 和 & 比算术运算符绑定得更紧"

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

"像 * 和 ++ 这样的一元运算符从右到左关联。"

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

它的工作原理类似于 *(ptr++)。

正确的方法是:

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

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

最新更新