一位朋友向我展示了他在课堂上必须做的多项选择练习,他知道正确的答案是什么,但他并不真正理解给定代码中发生的原因或内容。
这是(假设我输入没有任何错误):
What does the following code display ?
typedef union{
long adr;
struct{
unsigned char a,b,c,d,e;
}x;
}Ip;
static Ip y;
printf("%l2ld | %02X.%02X.%02X.%02X.%02X\n",
y.adr,y.x.a,y.x.b,y.x.c,y.x.d,y.x.e);
y.adr=1234567890;
printf("%l2ld | %02X.%02X.%02X.%02X.%02X\n",
y.adr,y.x.a,y.x.b,y.x.c,y.x.d,y.x.e);
y.x.a='A';y.x.b='B';y.x.c='C';y.x.d='D';y.x.e='E';
printf("%l2ld | %02X.%02X.%02X.%02X.%02X\n",
y.adr,y.x.a,y.x.b,y.x.c,y.x.d,y.x.e);
Answers (?? means a random value) :
A)
0 | 00.00.00.00.00
1234567890 | 00.00.00.00.00
1234567890 | 41.42.43.44.45
B)
0 | 00.00.00.00.00
1234567890 | ??.??.??.??.??
?????????? | 41.42.43.44.45
C)
?????????? | ??.??.??.??.??
1234567890 | ??.??.??.??.??
1234567890 | 41.42.43.44.45
D) Something else
现在,他得到了正确的答案,即B,但他并不理解为什么,并说他会期望C是正确的答案。不幸的是,我不确定这里发生了什么。有人可以给我们详细分析这些代码的作用并帮助我们理解答案吗?提前谢谢!
答案 0 :(得分:2)
答案可能是选择B
* 。 y
是static
限定的,因此其成员(具有最大字节:adr
)将使用0
进行初始化。
作业y.adr=1234567890;
后,adr
将为1234567890
。 struct成员的成员值取决于数字1234567890
中的字节数。根据{{3}},输出会有所不同。
以小尾数来计算输出将是
二进制文件中的1234567890
为1001001 10010110 00000010 11010010
。
01001001 => 49
10010110 => 96
00000010 => 02
11010010 => D2
类似于第三个printf
,ascii字符的十进制等值
'A' => 01000101
'B' => 01000100
'C' => 01000011
'D' => 01000010
'E' => 01000001
组合01000101 01000100 01000011 01000010 01000001
的十进制等效于297498001985
。
假设:具有小端硬件的64位计算机。
答案 1 :(得分:2)
我认为这是一个误导性的问题。变量声明为static的事实是初始值为0的原因。静态变量在运行时初始化为0。这消除了C.
答案的问题(以及让我摸不着头脑的一段时间)是B中的?不是随机数。它们完全由存储在adr或a-e中的内容决定。如果你不明白他们来自哪里,他们就会看起来像胡言乱语。
在联合中,变量都在内存中共享相同的地址空间。在这种情况下,adr和struct x在内存中共享空间。因此,当您更改一个值时,它会更改另一个的值。
因此,如果将adr设置为1234567890,则还要设置a到e的值。它们将是任何字节,排列成代表adr的长整数部分。
同样,如果你设置了-e,那么它会损坏" adr的值并更改显示的内容。
答案 2 :(得分:-1)
正确的答案是A.
在第一个printf
上,y
尚未初始化。因为它是static
它是zeo。
在第二个printf
y.adr
被初始化,但成员没有。因为它们是全球性的,所以它们是零。
在第三个printf
上,所有内容都已初始化。 42
是ASCII B
的十六进制。