zoukankan      html  css  js  c++  java
  • char和unsigned char强制转换成int后的差异(转)

    最近有人提到char和unsigned char有什么区别,当然这个问题如果刚学计算机或者编程语言的人来说,非常简单。我也这么认为,无非就是有符号和无符号的差别嘛。

    这个问题让我想到了以前学习计算机常识的时候关于补码,原码,反码的差异。这里摘取参考文章【1】中的部分内容:

    注意:此处的'=='是相等的意思。'='是赋值的意思。

    在机器世界里:
    正数的最高位是符号位0,负数的最高位是符号位1。
    对于正数:反码==补码==原码。
    对于负数:反码==除符号位以外的各位取反。
         补码==反码+1.
         原码==补码-1后的反码==补码的反码+1。(读完本文后,应该能够直观地认识到本式的正确性)


    可以轻易发现如下规律:
    自然计算 :a-b==c.
    计算机计算:a-b==a+b的补码==d.
    c的补码是d.
    通过此法,可以把减法运算转换为加法运算。


    所以补码的设计目的是:
    1.使符号位能与有效值部分一起参加运算,从而简化运算规则.
    2.减运算转换为加运算,进一步简化计算机中运算器的线路设计.

    讲的非常清晰了吧,是的。但是在计算机中,常做类型转换,当char或者unsigned char转换成int的时候,两者的差异是显而易见的。这里采用了部分文章【2】的代码对转换过程做了验证。

    1)当我对uch和sch同时赋值-100的时候uch和sch都是十六进制的0x9c

    2)此时由于两者一个是有符号,另一个是无符号的,我们可以看到十进制输出的时候,无符号的是156,而有符号的,最前面一个bit解释为了负值 -100

    3)然后我们看下对uch进行类型转换(int)然后看下真值,原码,反码和补码

    4)最后我们看下对sch进行类型转换(int)然后看下真值,原码,反码和补码

    可以看出uch和sch最大的差异就是前面的那个符号位,仅仅那一个bit位,对于我们计算机来说,存储的内容(补码)将是绝然不同的。

    真值,原码,反码和补码转换代码请详见参考文章【2】

    1. /* 检查uchar */  
    2. void CheckUchar(unsigned char uch)  
    3. {  
    4.     int x;  
    5.     char b[MAX+1];   
    6.       
    7.     x = uch;  
    8.     printf("CheckUchar Decimal value:%d\n", x);  
    9.   
    10.     TruthValue(b, x);//获取真值  
    11.     printf("TruthValue:\t%s\n", b);  
    12.   
    13.     TrueForm(b, x); //获取原码  
    14.     printf("TrueForm:\t%s\n", b);  
    15.   
    16.     RadixMinus(b, x);//获取反码   
    17.     printf("RadixMinus:\t%s\n", b);  
    18.   
    19.     Complement(b, x);//获取补码  
    20.     printf("Complement:\t%s\n", b);  
    21. }  
    22.   
    23. /* 检查schar */  
    24. void CheckSchar(char sch)  
    25. {  
    26.     int x;  
    27.     char b[MAX+1];   
    28.   
    29.     x = sch;  
    30.     printf("CheckSchar Decimal value:%d\n", x);  
    31.   
    32.     TruthValue(b, x);//获取真值  
    33.     printf("TruthValue:\t%s\n", b);  
    34.   
    35.     TrueForm(b, x); //获取原码  
    36.     printf("TrueForm:\t%s\n", b);  
    37.   
    38.     RadixMinus(b, x);//获取反码   
    39.     printf("RadixMinus:\t%s\n", b);  
    40.   
    41.     Complement(b, x);//获取补码  
    42.     printf("Complement:\t%s\n", b);  
    43. }  
    44.   
    45. int main()  
    46. {  
    47.     unsigned char uch = -100;  
    48.     char sch = -100;  
    49.     printf("hex: uch = 0x%x, sch = 0x%x\n", uch, sch);  
    50.     printf("dec: uch = %d, sch = %d\n", uch, sch);  
    51.       
    52.     CheckUchar(uch);  
    53.     CheckSchar(sch);  
    54.       
    55.     return 0;  
    56. }  

    参考文章:

    【1】反码和补码技术是怎样被提出的?

    【2】闲扯原码,补码和反码

  • 相关阅读:
    使用node-inspector调试nodejs程序<nodejs>
    2015 2月记事(1)
    设置npm安装模块目录<nodejs>
    BZOJ 1965 [AHOI2005]洗牌
    BZOJ 1924 [Sdoi2010]所驼门王的宝藏
    【NOIP2003】传染病控制
    BZOJ [Scoi2015]情报传递
    [Noi2002]Savage
    BZOJ 4025: 二分图
    BZOJ 4999 This Problem Is Too Simple!
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2871613.html
Copyright © 2011-2022 走看看