首页
社区
课程
招聘
[原创]c语言中变量比较规则
发表于: 2015-6-10 11:21 3445

[原创]c语言中变量比较规则

2015-6-10 11:21
3445
收藏
免费 3
支持
分享
最新回复 (2)
雪    币: 272
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
一般比较前强制转换下比较保险,比如a为char, b为int  ,  if( (int)a < b ) {}
2015-6-10 14:27
0
雪    币: 93
活跃值: (52)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
0x00 简介
C语言中无符号整形与有符号整形,低层次与高层次类型的比较等等,涉及到默认的一些规则,
需要理解清楚。

0x01 实验
1. 无符号整形与有符号整形
       
        unsigned int        un_a = 1;
        int                n_b  = -1;
        printf("un_a<n_b: %d\n", un_a<n_b);
       
        >> un_a<n_b: 1
        有符号整形与无符号整形比较时,按无符号进行比较,所以n_b = -1 => n_b = 0xffffffff > 1

2. 无符号char与有符号char
       
        char                c_a = -1;
        unsigned char uc_b = -1;
        printf("c_a<uc_b: %d\n", c_a<uc_b);

        >> c_a<uc_b: 1
        char与unsigned char以及short与unsigned short都会先扩展为与其同符号的整形,即char->int,
        unsigned char->unsigned int等等,然后再做有符号比较。

3. 有符号整形与无符号char
       
        int                n_a = 1;
        unsigned char        uc_b = -1;
        printf("n_a<uc_b: %d\n", n_a<uc_b);
       
        >> n_a<uc_b: 1
        uc_b先做无符号扩展(movzx)为uint型0xff,然后再做有符号比较,则n_a = 1 < 0xff = (int)((uint)uc_b)
       
4. 无符号整形与有符号char比较
        unsigned int un_a = 1;
        char c_b = -1;
        printf("un_a<c_b: %d\n", un_a<c_b);
       
        >> u_a<c_b: 1
        c_b先做有符号扩展(movsx)为int型0xffffffff,然后再做无符号比较,则un_a = 1 < 0xffffffff = (uint)((int)c_b)

5. 有符号整形与常量比较
        int n_a = -1;
        printf("n_a<80: %d\n", n_a<80);

        >> n_a<80: 1
        有符号整形跟常量比较时,做有符号比较

6. 无符号整形与常量比较
        unsigned int un_a = -1;
        printf("un_a<80: %d\n", un_a<80)
       
        >> un_a<80: 0
        无符号整形与常量比较时,做无符号比较

7. 低层次有符号类型与常量比较
        char ch = 0xff;
        printf("ch<80: %d\n", ch<80);

        >> ch<80: 1
        ch先做符号扩展(movsx)为0xffffffff,然后再做有符号比较,则(int)ch = 0xffffffff < 80

8. 低层次有符号类型与常量比较
        unsigned char u_ch = 0xff;
        printf("u_ch<0xffffffff: %d\n", u_ch<0xffffffff);

        >> u_ch<0xffffffff: 1
        u_ch先做无符号扩展(movzx)为0x000000ff,然后再做无符号比较。

9. 低层次有符号类型强制转化为高层次类型再与常量比较
        char ch = 0xff;
        int n_a = (int)ch;
        printf("n_a<0x80: %d\n", n_a<0x80);

        >> n_a<0x80: 1
        ch先做符号扩展为0xffffffff,所以n_a = 0xffffffff = -1 < 0x80

10. 低层次有符号类型强制转化为高层次类型再与常量比较
        char u_ch = 0xff;
        int n_a = (int)u_ch;
        printf("n_a<0x80: %d\n", n_a<0x80);
        printf("n_a<0xffffffff: %d\n", n_a<0xffffffff)
       
        int n_b = -1;
        printf("n_a<n_b: %d\n", n_a<n_b);

        >> n_a<0x80: 0
        >> n_a<0xffffffff: 1
        >> n_a<n_b: 0
        有没有一点意外,u_ch先做无符号扩展为0x000000ff,当与常量作比较时,做无符号比较,而与变量做比较时,按实验1中规则,这个我也觉得很诡异,还望理解清楚的说一下,附上编译后的汇编代码:

        mov        byte ptr[u_ch], 0FFh
        movzx        eax, byte ptr [u_ch]
        mov        dword ptr[n_a], eax
        cmp        dword ptr[n_a], 0FFFFFFFFh
        sbb        eax, eax
        neg        eax
        mov        esi, esp
        push        eax
        push         offset string "n_a<0xffffffff: %d\n"
        call         _printf

11. 指针类型与指针类型比较
        unsigned char *pch = (unsigned char *)-1;
        unsigned char *pch2 = (unsigned char *)1;
        printf("pch<pch2: %d\n", pch<pch2);

        >> pch<pch2: 0
        指针类型相互做比较时,做无符号比较

       
0x02 小结
1. 无符号类型与有符号类型(这里的类型都是不低于整形层次的类型)做比较时,按无符号进行比较;
2. 两个低层次类型(低于整形的同属于低层次)的变量进行比较时,先同符号扩展为高层次的类型,然后再做有符号比较;
3. 低层次与高层次类型做比较时,低层次的先同符号扩展为与高层次同级的类型,然后再根据高层次类型有无符号,做相应的有无符号比较。
4. 变量与常量进行比较时,做与变量本身同符号的比较,即变量本来是有符号,则做有符号比较,否则做无符号比较。
5. 低层次的变量与常量进行比较时,低层次的先同符号扩展为与高层次同级的类型,然后再做与其符号相同的比较。
6. 低层次类型强制转换为高层次类型时,先做与低层次类型同符号的扩展,然后当转换后高层次类型与常量比较时,也是做与低层次类型同符号的比较。
7. 指针类型做比较时,做无符号比较。
2015-6-11 09:50
0
游客
登录 | 注册 方可回帖
返回
//