繁体   English   中英

什么解释了此C代码的输出?

[英]What explains the output of this C code?

#include <stdio.h>

struct abc{
  int a;
  int b;
} xyz;

int main()
{
  xyz.a = 10;
  xyz.b = 20;
  printf("%d %d", xyz, xyz.a);
}

上面程序的输出是10 20

如果我添加另一个printf语句为

printf("%d %d %d", xyz, xyz.a, xyz.b);

输出为10 20 10

这有什么解释?

这是因为对printf的调用将整个结构 xyz推入堆栈,并且该结构(在这种情况下)由两个整数组成。 在这种情况下, xyz.a被忽略,因为它超出了printf关心的堆栈区域。

尽管行为是不确定的(a),所以任何事情都可能发生,但是可以解释这种特殊情况,因为printf("%d %d",xyz,xyz.a); 语句可能将xyzxyz.a推入堆栈,如下所示:

xyz.a | 10 |    |
xyz   | 20 |    | Stack grows downward.
      | 10 |    V

并且由于给了两个%d ,因此printf代码本身将在底部打印10,在20打印。换句话说,格式字符串和参数之间不匹配。

当您添加另一个%d ,它会打印出它认为是第三个参数(但实际上是第二个),即上图中的前10个参数。

我应该提到依靠这种行为不是一个好主意。 当您切换编译器,编译器版本,甚至在奇数天时,它可能会更改:-)

诸如gcc类的良好编译器实际上会在printf参数内部查找以将其捕获为潜在错误:

pax$ cat qq.c
#include<stdio.h>
struct abc { int a; int b; } xyz;
int main (void) {
    xyz.a=10;
    xyz.b=20;
    printf("%d %d",xyz,xyz.a);
    return 0;
}

pax$ gcc -Wall -o qq qq.c
qq.c: In function 'main':
qq.c:6: warning: format '%d' expects type 'int',
        but argument 2 has type 'struct abc'
qq.c:6: warning: format '%d' expects type 'int',
        but argument 2 has type 'struct abc'

(a)从c99,第7.19.6.1/9节: 如果任何参数不是对应转换规范的正确类型,则行为未定义。

您已经调用了未定义的行为 任何结果都是允许的。

7.19.6.1 fprintf函数
...
9如果转换规范无效,则行为未定义。 248) 如果任何参数都不是对应转换规范的正确类型,则行为未定义。

强调我的。 xyz的类型为struct abc ,但printf期望该参数的类型为int

paxdiablo的答案是对这种结果可能发生的方式进行的事后分析,但这仅适用于您的特定情况。 更改任何有关代码,翻译环境或执行环境的内容,结果可能会有所不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM