联合体数据成员的疑问

didijiji 2013-01-11 10:15:43
联合体中所有成员都是共用一段存储空间的,结构体的长度为结构体成员中最长的那个数据成员的长度,我写了如下测试实例:


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>

typedef union shift
{
char a;
char b;
int c;
}dao;

int main()
{
dao aa;
aa.a = 1;
printf("aa.a = %d\n", aa.a);
printf("aa.b = %d\n", aa.b);
printf("aa.c = %d\n", aa.c);
printf("\n");
system("pause");

return 0;
}



输出结果如下所示:

aa.a = 1
aa.b = 1
aa.c = -858993663

但是我想不明白这个-858993663是怎么来的,我用程序员计算器查看-858993663的二级制分布是这样的:


为什么会这样呢,我有这样一个疑问:
char是一个字节,int是四个字节的,char扩展到int的话,也不应该是把高三个字节中的每两个4位的高两位置1啊,希望朋友解答。
...全文
338 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
didijiji 2013-01-11
  • 打赏
  • 举报
回复
引用 11 楼 lgf2002 的回复:
引用 9 楼 didijiji 的回复:引用 4 楼 lgf2002 的回复: 本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。 那没初始化的那三个字节为什么都是 1100 1100 ……
失误,老糊涂了,呵呵。
didijiji 2013-01-11
  • 打赏
  • 举报
回复
引用 9 楼 didijiji 的回复:
引用 4 楼 lgf2002 的回复:本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。 那没初始化的那三个字节为什么都是 1100 1100 1100 1100 1100 110……
没问题,明白了。
lgf2002 2013-01-11
  • 打赏
  • 举报
回复
引用 9 楼 didijiji 的回复:
引用 4 楼 lgf2002 的回复: 本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。 那没初始化的那三个字节为什么都是 1100 1100 1100 1100 1100 1100这样子的啊,这算是默……
晕呀,你怎么计算的,11001100 11001100 11001100 是三个字节,11001100是CC,不是C0C0,一个十六进制数要占四位二进制数
crazy_samba 2013-01-11
  • 打赏
  • 举报
回复
楼主是用的什么编译器,我在gcc-4.3.4下面运行,aa.c =1
didijiji 2013-01-11
  • 打赏
  • 举报
回复
引用 4 楼 lgf2002 的回复:
本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。
那没初始化的那三个字节为什么都是 1100 1100 1100 1100 1100 1100这样子的啊,这算是默认初始化吗,好像是哦,就是0xc0,不对啊,默认初始化会初始化为0xcc的啊,而不是0xc0啊。
guotianyu2000 2013-01-11
  • 打赏
  • 举报
回复
正如你所说的,该共用体的长度是双字长度即是共用体成员int c的所占用字节长度。在未赋初值时a, b, c的值是随机的,因为不同的编译器对于不同数据类型对其随机值有不同的赋值。 在VC6.0下一般对对于未赋初值整型变量赋值为-858993460,其二进制为11001100110011001100110011001100。 在你的验证程序中你对共用体成员a赋值为1,a为字符类型,只占有一个字节,所以该赋值只影响了共用体的低字节(对于小端模式)。因为c初值为-858993460,第一个字节被改变为1后,其值也相应的变为-858993663,二进制形式为11001100110011001100110000000001,也就是你得到的结果。
lgf2002 2013-01-11
  • 打赏
  • 举报
回复
引用 4 楼 lgf2002 的回复:
本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。
你所看到的CC,并不是你的程序置的,而是你的编译器里的未初始化的一块内存区域里的默认值
lee_鹿游原 2013-01-11
  • 打赏
  • 举报
回复
这个楼主自己结合union资料, union的空间大小(此处是4),和大端小端。 楼主的机器应该是小端。
氰客 2013-01-11
  • 打赏
  • 举报
回复
引用 3 楼 gpshq 的回复:
引用 1 楼 gpshq 的回复: 你sizeof一下看看结构体是多大size! 有内存对齐的啊! 额,看错了,原来是联合 楼主这个应该是大小端的问题 -- debug下内存为0x01CCCCCC
补充一下,在VS的debug环境下,内存都会自动初始化为 0XCCCCCCCC, 0x01CCCCCC为小端模式下的情况,换成值就是 0XCCCCCC01
lgf2002 2013-01-11
  • 打赏
  • 举报
回复
本应该是这样,你给char型的变量赋值,它只用了四字节里的第一字节,其余三字节都没有使用,用char类型的变量读取时,刚好读了一字节的内容,没问题,但是用int型的变量读取时,是解析了内存里的四字节,其中有三字节都是没有初始化的。
氰客 2013-01-11
  • 打赏
  • 举报
回复
引用 1 楼 gpshq 的回复:
你sizeof一下看看结构体是多大size! 有内存对齐的啊!
额,看错了,原来是联合 楼主这个应该是大小端的问题 -- debug下内存为0x01CCCCCC
didijiji 2013-01-11
  • 打赏
  • 举报
回复
引用 1 楼 gpshq 的回复:
你sizeof一下看看结构体是多大size! 有内存对齐的啊!
这是联合体,不是结构体!!!
氰客 2013-01-11
  • 打赏
  • 举报
回复
你sizeof一下看看结构体是多大size! 有内存对齐的啊!
赵4老师 2013-01-11
  • 打赏
  • 举报
回复
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
赵4老师 2013-01-11
  • 打赏
  • 举报
回复
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧