免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1057 | 回复: 0
打印 上一主题 下一主题

关于 UNION,STRUCT,位段,原码,补码,类型提升的学习分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-29 22:59 |只看该作者 |倒序浏览

                程序如下:
#include  
#include  
#include  
int main(int argc, char** argv)
{
union
{
struct
{
char a:1;
char b:2;
char a:3;
}d;
char e;
} f;
f.e = 1;
printf("%d\n",f.d.a);
getchar();
return 0;
}
分析:
1.分析结构体(struct)中的含义.
char a:1; a占1位;
char b:2; b占2位;
char a:3; c占3位;
这个地方涉及到 struct 中的位段.
2.分析联合体(union)的含义.
union,共享内存,里面的数据是从低位开始的,这点很重要哦!
所以我们清楚,在 f.e = 1 之前, struct里面的内存是混乱的,因为没有初始化.
赋值之后,该Union中的内存应是下面的情况.("s"代表未知)
s s s s s s s s 1
?3.这里我们假设是小端模式.(同样,大端模式,小端模式自己Baidu下拉,这里不罗嗦了)   大小端模式是指多字节下,字节的顺序。但是这里只有一个字节。  这里有待商榷。也许是和编译器的实现有关。
4.printf("%d",f.d.a);
我们以 %d 的模式输出,因为此时读的是 a 所在的一位而 %d 需要32位.
怎么办呢,这个时候就需要类型提升了. (关于类型提升,照例去Baidu)
此时,1被作为符号位,做类型提升,使得 %d 读出的数据 32位全为 1.
即 0xFFFF.
5.0xFFFF,正是 -1 在内存中的补码形式. 所以这个程序会输出 -1.
延伸分析:
1.类型提升,是按照什么样的规则?
如果 a 不是占一位,而是占4位,5位,内存分布值为 10010/10100/01011 等等,会被提升成什么?
解答:首先提取符号位,也就是第一位.后面的原则未知.
?2.大端模式和小端模式. 针对上题中的 char 类型,两者有区别么? 可以找一个大端模式的编译器,测试即得.
3.有兴趣的朋友可以尝试将 char类型改为 int/unsigned int,进行更多的调试.
解答:int 是 -1;unsigned int 是 1。
4.关于原码,反码,补码.
众所周知,反码是原码各位取反,补码末位加1.我只想说,这不是绝对正确的.
5.关于赋值.
这需要有点ASCII的基础.因为ASCII可以表示char型常用的128个字符.(这些可以Baidu下)
此时将 char e 的值赋给了 这个 Union,所以 a,b,c 三个值都会有自己对应的位值.(0或者1)
不管我们赋的值是多少,只需保证最末一位是 1,也就是 a 的位是1,程序就会输出 -1.
提到ASCII码,让我想起了一个可以让windows死机的小程序.(只有几行代码,利用了ASCII码的控制符)
#include  
#include  
int main()
{
for(;;)
{
    printf("hung up\t\t\b\b\b\b\b\b");
    print("hung up\t\t\b\b\b\b\b\b";
    }
  return 0;
}
大概是这个样子,我记不太清楚了.还请高手留言赐教~!
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/67131/showart_1759742.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP