#include<stdio.h>
main()
{
int val=1234;
int* ptr=&val;
printf("%d %d",val,*ptr++);
}
out of my knowledge i would manually get 1235 1234,
*ptr++ 将给出 1234 作为输出,并在 val 变量打印 1235 之后在内存中给出 1235 。 后来我意识到我对此的看法是错误的,在ideone it之后。请纠正我错误的地方,它显示输出为1234 1234
最佳答案
基本上,输出是 1234 1234
,因为:
-
++
优先级高于*
, postifx++
应用于指针,而不是它指向的值 -
ptr
将增加,但同样:后缀,所以printf
将收到当前值ptr
指向 (*ptr
),与 val 相同 -
ptr++
是有风险的生意。正如 @EOF 指出的,指向“数组中最后一个元素之后的一个”甚至有效对象 + 1 都会产生一个“有效指针”。确实如此,但据我所知,取消引用该指针至少是未指定的行为,我认为甚至存在 UB 的风险。
简单来说,您的printf("%d %d\n", val, *ptr++)
语句相当于写:
printf("%d %d\n", val, *ptr);
++ptr;//shift pointer to &val + 1
现在这不会造成任何问题。这取决于您如何处理 ptr
增加它之后。您可以将指针移动到对象后面的 1 个位置,该内存将被视为包含随机值的同一时间的值。
据我所知,C99 标准没有指定任何 WRT 取消引用此指针的行为。最好的情况:它将产生垃圾值。可能会产生未定义的行为,具体取决于指针的类型以及作为陷阱表示的值。
大多数类型都有陷阱表示,据我所知,除了 unsigned char
之外的所有类型。做。陷阱表示定义如下(C99 6.2.6 类型表示)
Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.[41] Such a representation is called a trap representation.
还有脚注
[41] Thus, an automatic variable can be initialized to a trap representation without causing undefined behavior, but the value of the variable cannot be used until a proper value is stored in it.
因为保存陷阱表示的变量不是问题,所以有一个指向 O+1 的指针是完全可以的,但使用该值是另一回事。
正如 EOF 再次指出的那样,C11 标准更加具体:无论何种类型都会带来风险,结果指针都无法安全地取消引用 WRT 陷阱表示:如果结果指向最后一个元素之后的一个数组对象的,它不应该用作被评估的一元 * 运算符的操作数(引用 EOF 的注释)。
<小时/>回到你的问题:
所以如果你想要输出1234 1235
,最简单的方法是这样的:
#include <stdio.h>
int main ( void )
{
int i = 123, *p = &i;
printf("%d %d\n", i, i+1);
printf("%d %d\n", *p, *p + 1);//using pointers
return 0;
}
由于缺少序列点,不可能在一行中使用指针递增一个值,并打印其旧值,然后打印新值。在将参数传递给函数之前有一个序列点,因此编写 printf("%d %d\n", i, ++(*p));
将打印 1235 1235。
重要的是要理解表达式的求值没有特定的顺序。如果你尝试做一些像这样奇怪的事情:
int i = 8, *p = &i;
printf("%d %d %d\n", ++(*p), printf("%d", *p), ++(*p));
仍然无法可靠地预测输出。可能的输出是:
- 810 1 10:内部
printf
首先评估调用,因此是 8 - 910 1 10:内部调用是要计算的第二个表达式 (9)
- 1010 2 10:最后评估内部调用 (10)
关于c - 以下程序 : 的输出是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37794763/