c语言整型提升 图解,关于C整型提升

ANSI C中的寻常算术转换

当执行算术运算时,操作数的类型如果不同,就会发生转换。 数据类型一般朝着浮点精度更高、长度更长的方向转换 。整型数如果转换为signed不会丢失信息,就转换为signed,否则就转换为unsigned。 这个称为值保留(value preserving)原则,与K&R C所采用的无符号保留(unsigned preserving)原则不同。

浮点类:

如果一个操作数的类型是long double,那么另一个操作数无论是什么类型都将被转换成long double。

如果两个操作数都不是long double型,那么当其中一个操作数的类型是double型,则另一个就将被转换成double 型。

如果两个操作数都不是double型,而其中一个操作数是float型,则另一个被转换成float型。

注意:double和float都不可用unsigned,short修饰,另外float还不可用long修饰整型类:

否则,两个操作数都不是三种浮点类型之一,它们一定是某种整值类型。在确定共同的目标提升类型之前,编译器将在所有小于int的整值类型上施加一个被称为整型提升(integral promotion)的过程。整型提升就是char、short int和位段类型(无论signed或unsigned)以及枚举类型将被提升为int, 前提是int 能够完整地容纳原先的数据,否则将被转换为unsigned int。wchar_t和枚举类型被提升为能够表示其底层类型(underlying type)所有值的最小整数类型。

一旦整型提升执行完毕,类型比较就又一次开始。如果一个操作数是unsigned long型,则第二个也被转换成unsigned long型。如果两个操作数的类型都不是unsigned long,而其中一个操作数是long型,则另一个也被转换成long型。long 类型的一般转换有一个例外,如果一个操作数是long型,而另一个是unsigned int型,那么只有机器上的long型足够长,以便能够存放unsigned int的所有值时(一般来说,在32位操作系统中,long型和int 型都用一个字长来表示,所以不满足这里的假设条件),unsigned int才会被转换为long型,否则两个操作数都被提升为unsigned long型。若两个操作数都不是long型,而其中一个是unsigned int型,则另一个也被转换成unsigned int 型。否则两个操作数一定都是int 型。int d = -1;

if (d <= sizeof(arr)/sizeof(arr[0]))

...

这样的比较语句有问题,sizeof运算符返回无符号数。

if语句在signed int和unsigned int之间测试相等性,

按照上面的说法,可以这样解释:

首先,signed int和unsigned int长度相同,不会向更长的方向转换。

其次,signed int不能完整地表示unsigned int的所有值。

因此,signed int d被转换为unsigned int类型。

这样,-1就变成一个非常巨大的正整数,导致比较结果与预期的不符。解决的方法是使用强制转换,(int)(sizeof(arr)/sizeof(arr[0]))。

不要因为无符号数不存在负值而用它表示数量(如年龄、国债等), 尽量使用int之类的有符号数,这样在混合运算中, 这样就不必担心边界情况(如-1被翻译为非常大的正数)。 只有在使用位段和二进制掩码时,才使用无符号数。 应该在表达式中使用强制类型转换,使所有的操作数均为有符号数或无符号数, 这样就不必由编译器来选择结果的类型。ANSI C表示,如果编译器能够保证运算结果一致, 也可以省略类型提升——这通常出现在表达式中存在常量操作数的时候。

另一个会发生隐式类型转换的地方就是参数传递。

在K&R C中,由于函数的参数也是表达式,所以也会发生类型提升。

在ANSI C中,如果使用了适当的函数原型,类型提升便不会发生,否则也会发生。

在被调用函数的内部,提升后的参数被裁减为原先声明的大小。这就是为什么单个的printf()格式字符串%d能适用于几个不同类型,short、char或int,而不论实际传递的是上述类型的哪一个。函数从堆栈中(或寄存器中)取出的参数总是int类,并在printf或其他被调用函数里按统一的格式处理。printf是一个可变参数函数,此时一般的参数提升始终会发生。

例如:

chara , b ,c;

c=a + b;

在上述过程中,尽管两个运算符"+"和"="的操作数全为char型,但在中间计算过程中存在着整数提升:对于表达式a+b ,a、b都是char型,因此被提升至int型后,执行“+”运算,计算结果(int型)再赋值给c(char型),又执行了隐式的类型转换。是不是有一种很不相信的感觉?Me too,然而标准就是标准。可以使用下面的代码证明上面所描述的过程。printf (" the size of the result of a+b :%d ",sizeof( a+b) );

理解了整型提升的概念后,面对下面这个C语言的FAQ,你应该不会产生困惑了“ 为什么语句 printf( "%d",sizeof ('A') );  的输出结果是4呢?char类型长度不是1字节么? ”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值