c - 以下程序 : 的输出是什么

标签 c

  #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/

相关文章:

c - C的打开覆盖文件将被打开,并且fdopen返回NULL

c - 结构内部定义的 MACRO 的范围是什么?

c - 我的套接字发生接收超时

c - stafs 结构的元素返回负值

c - 禁用 SSE 的 SSE 寄存器返回

c - 数的 n 次根

c - 为什么 ioctl 调用的原型(prototype)使用 unsigned long 作为第三个参数?

c - 我是否需要一个单独的线程来为主程序中的 while 循环设置计时器?

c - 读取二进制文件的全部内容

c - 在树型数据结构中,逐级显示树节点