整型提升(integer promotion)

整型提升在计算中确保小型整数类型被转换为int或unsigned int以避免溢出。通过这种方式,例如在算术操作、一元运算符和位移运算符中,中间值的溢出错误得以避免。在示例中,即使两个signed char相加可能溢出,通过整型提升,它们先被转换为int进行计算,然后结果再截断回原始类型。这种机制保证了表达式的正确评估。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是integer promotion:


Integer Promotions

Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int.

Integer promotions are applied as part of the usual arithmetic conversions (discussed later in this section) to certain argument expressions, operands of the unary +, -, and ~ operators, and operands of the shift operators. The following code fragment illustrates the use of integer promotions:

char c1, c2;
c1 = c1 + c2;

Integer promotions require the promotion value of each variable (c1 and c2) to int size. The two ints are added and the sum truncated to fit into the char type.

Integer promotions are performed to avoid arithmetic errors resulting from the overflow of intermediate values. On line 5 of Figure 5-7, the value of c1 is added to the value of c2. The sum of these values is then added to the value of c3 (according to operator precedence rules). The addition of c1 and c2 would result in an overflow of the signed char type because the result of the operation exceeds the maximum size of signed char. Because of integer promotions, however, c1, c2, and c3 are each converted to integers and the overall expression is successfully evaluated. The resulting value is then truncated and stored in cresult. Because the result is in the range of the signed char type, the truncation does not result in lost data.

Figure 5-7. Preventing arithmetic errors with implicit conversions

1. char cresult, c1, c2, c3;
2. c1 = 100;
3. c2 = 90;
4. c3 = -120;
5. cresult = c1 + c2 + c3;


更多例子:


1. 这个例子来自: http://blog.youkuaiyun.com/dyllove98/article/details/9004872



开门见山,先来看一段简单的代码:

  1 #include <stdio.h>
  2 
  3 int array[] = {1, 2, 3, 4, 5, 6, 7};
  4 #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
  5 
  6 int main()
  7 {
  8     int i = -1;
  9     int x;
 10 
 11     if(i <= TOTAL_ELEMENTS - 2) {               //整型提升
 12         x = array[i + 1];
 13         printf("x = %d.\n", x);
 14     }
 15 
 16     printf("now i = %d.\n", TOTAL_ELEMENTS);
 17 
 18     return 0;
 19 }

执行结果:

randy@ubuntu:~/C_Language$ ./a.out 

now i = 7.

是不是很奇怪?为什么没有打出line13的x = ?。

是这样的。这个小例子有三点值得注意:

1.sizeof()是运算符,返回类型是无符号的,即非负数。

2.if语句在singned int和unsigned int之间进行判断语句,根据C语言整型提升规则,如果原始类型的所有值都可用int类型表示,则其值将被转换为int类型;否则将被转换为unsigned int类型。因此此时的i将会被升级成无符号类型。

3.i = -1被升级为无符号型,值究竟是多少?这要用到整型转换规则:K&R上这样解释,将任何整数转换为某种指定的无符号数类型数的方法是:以该无符号数类型能够表示的最大值加1为摸,找出与此整数同余的最小的非负值。听着很拗口,其实说白了,只要知道原整数的二进制表达方法,再用要即将转换的类型去解析,就得到升级后的值了。 比如-1,负数在计算机里用补码表示,0xffffffff,那升级成无符号型之后,值就是0xffffffff,显然比TOTAL_ELEMENTS(7)大。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值