Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80148
  • 博文数量: 16
  • 博客积分: 670
  • 博客等级: 上士
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-21 20:11
文章分类

全部博文(16)

文章存档

2011年(1)

2009年(5)

2008年(10)

最近访客

分类:

2008-12-21 20:16:23

程序如下:
        #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 中的位段.随便Baidu,Google拉!

        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,进行更多的调试.

        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;
          }

      大概是这个样子,我记不太清楚了.还请高手留言赐教~!
阅读(1518) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:工作随想

给主人留下些什么吧!~~