数据类型之char
每一位学习过C语言的同学都知道char这个数据类型是用来存储字符变量的。可它在内部到底是怎么表示的呢?我们看到的仅仅是由编译器进行解析过之后的情形。如果你觉得没必要深究,就不用再往下面看了。
在C语言中其实都把char分为了unsigned char和signed char. 我们平时使用unsigned char和char 并不一定全都是为了表达一个字符,有时候我们可能会在别的地方使用它们,比如:在有些时候我们为了节省内存空间(用更少的内存区表达相同的信息),比如在嵌入式编程中长用到的在表达的整数在比较小的范围中时,就可以仅仅用char类型来表示整数,免去了浪费多余的空间。(用char类型来存储数字在嵌入式中是常用到的方法)
而在我们的刚开始写程序的时候大多的情况下是没有区分你定义的是char还是unsigned char? 因为很多的时候我们确实用不到它们。当你声明一个char类型的变量的时候,其实不同的编译器对它的解释是不一样的(C语言把对默认的char声明所表达意义这个任务分到了编译器身上--称之为Implementation Defined)。不同的编译器对它的解释不同,这其实是很可怕的事情,同样的程序在不同的编译器上作出不同的解释,后果你就可想而知了。在这里的不同解释就是:当我们在程序中声明一个这样的变量的时候,char a;有的编译器会解释成signed char,而有的编译器会解释成unsigned char。关于这一点下面的例子就可以看出来不同。
char a=0xb6;
if(a==0xb6) puts("a==0xb6");
你是怎么看待这个代码的呢?如果编译器将char a解释成unsigned char,那么结果能够正常输出,而大部分的编译器(将它解释成为signed char)却不能解释出来。至于为什么且看下面的分析。
不知道现在的你知不知道Integral Promotion(整数提升)这个概念。以下是关于摘自别人的关于整数提升的内容:
K&R C中关于整型提升(integral promotion)的定义为:
"A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion."
上面的定义归纳下来就是以下两个原则:
1). 只要一个表达式中用到了整型值,那么类型为char、short int活整型位域(这几者带符号或无符号均可)的变量,以及枚举类型的对象,都可以被放在这个整型变量的位置。
2). 如果1)中的变量的原始类型值域可以被int表示,那么原值被转换为int;否则的话,转为unsigned int。
以上两者作为一个整体,被成为整型提升(Integral promotion)。整型提升的概念容易与普通算术类型转换产生混淆。这两者的区别之一在于后者是在操作数之间类型不一致的情况下发生,最终将操作数转换为同一类型。而在算术运算这种情景下,即使操作数具有相同的类型,仍有可能发生整型提升。
这下你就明白了整数提升的概念了。那么我们就可以分析上面的程序为什么char不同的解释会有不同的结果。
在大部分的编译器中将char a;自动改为是signed char了。那么这个所谓的signed char是1个字节的(内存空间中存储的是一个8bit的有符号数),然而在这个a遇到运算的时候会自动的发生整数提升的过程,根据你对整数提升的理解,不难想象出现在的if(a==0xb6)是不成立的,因为经过整数提升后的a变成了0xffffffb6而不是0xb6.
if(a==0xb6) puts("a==0xb6");
else if(a==0xffffffb6) puts("a==0xffffffb6");
也许现在你一眼就能看出上面的输出了。而对于把char a;解释成为unsigned char a;的编译器的输出结果不用我的提示,想必你已经知道答案了吧?
整数提升部分参考自:http://blog.csdn.net/lovekatherine/article/details/1565969
浙公网安备 33010602011771号