为什么这个程序不打印“4”?

Why doesn't this program print '4'?

执行*ptrj++后ptrj的值不应该是4吗?

int j=3,*ptrj = NULL;
ptrj = &j;
*ptrj++;
printf("%i",*ptrj);

*ptrj++ 等同于 *(ptrj++)。您期望的是 (*ptrj)++。您应该查看 运算符优先级 以了解有关哪些运算符先于其他运算符执行的更多信息。要了解 ptrj++ 的作用,您应该阅读 指针算法 。但这里有一个简单的解释:

  • *(ptrj++) returns ptrj 指向 (3) 的值,然后递增 ptrj 指向下一个值。

  • (*ptrj)++ returns ptrj 指向 (3) 的值,然后递增 ptrj 指向 3 到 4。

这意味着您要打印的是地址 &j + 1 处的值,该值位于 之后 中的变量 j记忆。这是 未定义的行为。正如 Sourav 指出的那样,如果启用编译器警告,您会收到一条警告,指出这一点。

*ptrj++ptrj++ 之间的唯一区别是它 return 是什么。由于您不使用 return 值,因此您的代码相当于:

int j=3,*ptrj = NULL;
ptrj = &j;
ptrj++;
printf("%i",*ptrj);

如果在启用警告的情况下编译程序,您将看到

source_file.c:9:5: warning: value computed is not used [-Wunused-value]
     *ptrj++;
     ^

也就是说,价值计算是没有用的。

换句话说,根据 operator precedence *ptrj++;*(ptrj++); 相同,并且根据 post-increment 运算符 属性,值该操作是操作数的值,值增加为side-effect.

引用 C11,章节

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). [....]

所以,这与

相同
 *ptr;
  ptr++;

如果要在地址处增加 value,则需要使用显式括号强制执行运算符优先级,例如

(*ptrj)++;   // first get the value, then update the value.

*ptrj++ 等价于 *(ptrj++).

可以使用 (*ptrj)++ 实现所需的输出。

请参阅 https://www.geeksforgeeks.org/c-operator-precedence-associativity/ 了解运算符的工作原理。

后缀++的优先级高于*。表达式 *ptrj++ 被视为 *(ptrj++) 因为后缀 ++ 的优先级高于 *。如果你想打印 4(即 ptrj+1 ),你应该使用以下代码:-

int j=3,*ptrj = NULL;
ptrj = &j;
(*ptrj)++;
printf("%i",*ptrj);
return 0;

要了解更多关于运算符优先级的信息,请参考link: https://en.cppreference.com/w/c/language/operator_precedence