C无符号数和有符号数探讨

C 、C++都支持有符号(默认)和无符号数,java只支持有符号数。

整数表示:无符号整数:无符号编码 

                    有符号数:补码(范围不对称),| TMIN |=| TMAX |+1

C语言标准并没有要求用补码形式来表示有符号数,但是几乎所有的机器都是这么做的

C标准只规定了每种数据类型必须能够表示的最小的取值范围而不是确定范围。long long是ISO  C99中引入的

C库中文件<limits.h>定义了一组常量,来限制编译器运行的这台机器的不同整形数据类型的取值范围 例如INT_MAVX 、INT_MIN、UINT_MAX、UINT_MIN

java标准明确规定基本数据类型的取值范围,其中整形数据要求采用补码表示,单字节数据类型是byte而不是char,且没有long long数据类型。这些非常具体的要求是为了保证无论在什么机器上,java程序运行的表现都能完全一样。byte 1、short  int 2、int 4、long  8、float 4、double 8  字符串中每个字符依据具体编码而定一般采用UTF-8(unicode字符集中的一种变长编码,字母采用单字节兼ACSCII、中文采用3字节)

有符号数和无符号数之间的转换(前提:有符号数采用补码表示):

C语言允许在各种不同的数字数据之间做强制类型转换。C规定:

1:同长度的有符号数和无符号数转换原则:底层位表示保持不变

2:不同长度有符号数和无符号数转换原则:

        1):隐式转换(由小类型数-->大类型数之间的转换):a):小类型数据为无符号数:零扩展

                                                                                                       b):小类型数据为有符号数:符号扩展

        2):强制转换(由大类型数-->小类型数之间的转换):a):大类型数据为无符号数:直接截取高位

                                                                                                       b):大类型数据为有符号数:先转化为同长度无符号数,然后截取高位,最后再转化为有符号数

3:一运算中如果同时出现有符号数和无符号数,一般将有符号数强制转化为无符号数 

          eg1: 一台采用补码的32位机器-1<0U   <==>  4294967295U<0U

          eg2:   unsigned length;

                     int i;

                     ......

                    if(i<length-1)------------------------bug,i为有符号数,length为无符号数,两者运算将进行无符号数运算:length+(unsigned)(-1)结果得到UINT_MAX,总是真


建议:有符号数到无符号数的隐式类型转换可能会导致某些错误,避免这种错误的方法就是绝不使用无符号数,除了C和C++很少有语言支持无符号数,这些语言的设计者认为他们带来的麻烦要比益处多得多,比如:java只支持有符号的数,

你可能感兴趣的:(C无符号数和有符号数探讨)