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("%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
和++
之间是否有差异? 我以为他们都是一样的。
差异是由于运营商的优先权。
后置增量运算符++
优先级高于解引用运算符*
。 所以*ptr++
相当于*(ptr++)
。 换句话说,增量修改指针,而不是它指向什么。
赋值运算符+=
优先级低于解引用运算符*
,所以*ptr+=1
相当于(*ptr)+=1
。 换句话说,赋值运算符修改指针指向的值,并不改变指针本身。
涉及您的问题的3个操作员的优先顺序如下:
后增量++
>取消引用*
>赋值+=
您可以查看此页面以获取有关该主题的更多详细信息。
在parsing一个expression式时,某行上列出的操作符将比其下一行中列出的任何操作符更紧密(如同括号一样)。 例如,expression式
*p++
被parsing为*(p++)
,而不是(*p)++
。
长话短说,为了expression这个赋值*ptr+=1
使用后增加运算符,您需要添加括号给解除引用运算符,使该运算的优先级高于++
(*ptr)++
我们应用括号来显示操作顺序
a + b / c a + (b/c)
我们再来一次
*ptr += 1 (*ptr) += 1
再一次
*ptr++ *(ptr++)
- 在
*ptr += 1
,我们增加指针指向的variables的值。 - 在
*ptr++
,我们在整个语句(代码行)完成之后递增指针,并返回指针指向的variables的引用。
后者允许你做这样的事情:
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 ++:递增指向下一个内存位置的指针,而不是指针指向的数据。