为了账号安全,请及时绑定邮箱和手机立即绑定

如下关于union的C语言题目,为什么结果是39和9 ?求解析?

如下关于union的C语言题目,为什么结果是39和9 ?求解析?

千巷猫影 2022-05-12 14:11:44
#include "stdio.h"main(){union{int i[2];long k;char c[4];}t,*s=&t;s->i[0]=0x39;s->i[1]=0x38;printf("%1x\n",s->k);printf("%c\n",s->c[0]);}
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

首先 union 和 struct 不同的一点就是一个 Union 中的所有成员都是共用一个内存空间的,大小由成员中要求空间最大的来决定。也就是说你给其中一个成员赋值以后,其他成员就都是这个值,只不过因为成员类型不同导致这个值的表现不同。现在看这个程序,定义了一个 union


union {    int i[2];    long k;    char c[4];} t;

所有成员的大小分别如下:


i: 2 * sizeof(int) = 2 * 4 = 8k: sizeof(long) = 4c: 4 * sizeof(char) = 4 * 1 = 4

可见最大的是那个整数数组 i,占 8 个字节,所以这个 union t 的大小就是 8。

然后,你通过


s->i[0] = 0x39; s->i[1] = 0x38;

给 i 数组赋值,也就是 i 的前四个字节存储的是十六进制整数 0×39,后四个字节存储的是十六进制整数 0×38。因为 union 的所有成员共享一个内存空间,所以 k 和 c 的值同 i 的值是一样的。然而 k 和 c 只有四个字节的长度,所以后面的 0×38 就被忽略了,因为 0×39 已经占据了前 4 个字节。也就是说,现在 k 的值是 0×39,c 的值也是 0×39。

然后看你的输出


printf("%1x\n", s->k);                                     printf("%c\n", s->c[0]);

你要将 k 以十六进制整数的方式输出到屏幕上,c 以字符的方式输出到屏幕上,也就是将 0×39 分别以十六进制整数和字符的方式输出到屏幕上。0×39 代表的十六进制整数当然还是 39,而 0×39 所代表的字符是 '9'(注意这个 9 是字符而不是整数),这个你可以查一下 ASCII 表看看十六进制的 39 对应的字符是不是 '9'。所以输出的结果自然就是 39 和 9 了。

下图为 ASCII 表的一部分,可见十进制的 57,也就是十六进制的 39 所代表的字符是 '9'。

为了更好理解 union,你也可以使用


printf("%c\n", s->c[4]);

打印出来 c[4],看看结果是不是 '8'。这是因为虽然定义 c 的长度是 4,但由于整个 union 在内存中的长度有 8,所以 c[4] 到 c[7] 这四个字节在内存中仍然是存在的,而它的值就是刚才存在 i 中的第二个整数 0×38。然后因为十六进制的 38 对应的字符是 '8'(见上图),所以打印出 c[4] 的值是 8。

一点题外话是,包含系统头文件时请使用


#include <stdio.h>

而不是


#include "stdio.h"

这样会稍微提高执行效率。还有就是请让 main 函数返回整数 0 而不是 void,返回 void 是不规范的写法。



查看完整回答
反对 回复 2022-05-16
?
红颜莎娜

TA贡献1842条经验 获得超13个赞

  1. int和long一样都是4个字节,所以s->k取的就是i[0]的值。

  2.  printf("%c\n",s->c[0]) 算出是9和大小端有关,只有小端才是9。就是ANSI char '9',换成十六进制就是39。char[0]取了i[0]的低八位。


查看完整回答
反对 回复 2022-05-16
  • 2 回答
  • 0 关注
  • 250 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号