Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 它的输出是什么?为什么?_C - Fatal编程技术网

C 它的输出是什么?为什么?

C 它的输出是什么?为什么?,c,C,我仔细研究了范围规则问题,然后得到了一个代码片段,如下所示: #include <stdio.h> int main() { int x = 1, y = 2, z = 3; printf(" x = %d, y = %d, z = %d \n", x, y, z); { int x = 10; float y = 20; printf(" x = %d, y = %f, z = %d \n", x, y, z);

我仔细研究了范围规则问题,然后得到了一个代码片段,如下所示:

#include <stdio.h>
int main()
{
  int x = 1, y = 2, z = 3;
  printf(" x = %d, y = %d, z = %d \n", x, y, z);
  {
       int x = 10;
       float y = 20;
       printf(" x = %d, y = %f, z = %d \n", x, y, z);
       {
             int z = 100;
             printf(" x = %d, y = %f, z = %d \n", x, y, z);
       }
  }
  return 0;
}
我得到以下输出,我不明白:


那么,你能解释一下为什么z要打印那个值吗?

x、y和z被解析为大多数局部定义

使用不正确的printf%说明符时,行为未定义

y是浮动的,但您正在使用%d在后面的行中打印它

printf使用varargs,一旦您使用不正确的说明符%d而不是%f损坏堆栈,在这种情况下,堆栈将损坏,并且错误解释偏移量不正确的堆栈数据将导致许多令人痛苦的意外

解码这个UB

这是您的机器上可能发生的情况—一种可能的解释。由于,十六进制中的位模式被推送到堆栈中达到20.0f。小endian机器上的int大小是4字节。当您将float打印为int时,您的计算机0x00000000将被使用并解释为int,它将先打印0,然后%d将使用0x40340000将其解释为int并打印1077149696。最后100 0x00000064保留在堆栈中未使用,printf返回

但永远不要依赖于此,始终要编写行为定义明确的代码。

z=1077149696 使用%d打印浮点值是未定义的行为。 改用%f

您使用的所有变量都具有存储类型Auto或Automatic。 自动变量的作用域位于声明它的块内。 如果存在嵌套块,则最外层块中声明的变量将对所有其他块可见。 如果一个块的声明变量与外部块中声明的变量相匹配,那么它将覆盖其块中的外部变量,即本地变量。 总而言之:
自动变量是声明它们的块的局部变量。

@mohit jain是正确的

使用错误的格式说明符会在堆栈上产生错误的参数解释,从而导致未定义和特定于编译器的行为

请注意,在现代编译器(如gcc或clang)上,它会抱怨您的格式规范错误:

$ clang test.c 
test.c:12:54: warning: format specifies type 'int' but the argument has type 'float'
      [-Wformat]
             printf(" x = %d, y = %d, z = %d \n", x, y, z);
                                  ~~                 ^
                                  %f
1 warning generated.

我的假设是因为printf使用vargs,除了%d表示浮点y,它读取浮点的前4个字节,即0,并将后4个字节留给下一个%d,即z,因此z打印了一个未定义的值。此代码与ideone中的示例不相同。-1此代码完全有效,并且与您获取结果的ideone中的代码不同。ideone代码有一个漏洞。我想,如果最里面的打印是这个呢?我想,如果我在头顶上开个洞,然后把酸倒进去呢。。。可能会发生什么?此代码与ideone中的示例不同。-阅读理解?这个问题包含了修改。这是您在ideone上的代码-不,这是更改前的代码。我想是的,至少看看问题中的代码,printf格式字符串看起来不错。你真的在引用链接中的代码吗?顺便说一句,这是关于ideone的问题的代码:我想,如果最里面的印刷品是:在问题中。好的,问题很不清楚。因为这个原因,我把我的反对票改为赞成票。@JimBalter我看到了3到4张反对票,惊慌失措地删除了我的答案,但没有发现任何错误。所以我取消了答案并添加了更多信息。
x = 10, y = 0, z = 1077149696
$ clang test.c 
test.c:12:54: warning: format specifies type 'int' but the argument has type 'float'
      [-Wformat]
             printf(" x = %d, y = %d, z = %d \n", x, y, z);
                                  ~~                 ^
                                  %f
1 warning generated.