什么是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)大。