概念:
- C语言的整型算术运算总是至少以缺省(默认)整型类型的精度来进行的
- 为了获得这个精度,表达式中字符和短整型操作数在使用之前被转换为普通整型,这种转换成为整型提升
如何进行整型提升
整型提升是按照变量的数据类型的符号位来提升的
注1:如果对二进制,原码,反码,补码还不是特别了解,建议先看看二进制,原码,反码,补码>
注2:
%d是以十进制形式打印有符号整数,对字符和短整型进行整型提升时,高位补符号位
%u是以十进制形式打印无符号整数,对字符和短整型进行整型提升时,高位补0
举个例子:
#include
int main() { char num_1 = 5; /* 数字5是一个整型数据,在内存中的存储形式为: 0000 0000 0000 0000 0000 0000 0000 0101 由于要存入char型变量中,而char只有一个字节,因此要进行截断 num_1 = 0000 0101 */ char num_2 = 127; /* 数字127是一个整型数据,在内存中的存储形式为: 0000 0000 0000 0000 0000 0000 0111 1111 由于要存入char型变量中,而char只有一个字节,因此要进行截断 num_1 = 0111 1111 */ char num_3 = num_1 + num_2; /* 由于整型提升,字符型数据num_1, num_2在使用之前要提升为int型(高位补符号位0) num_1 = 0000 0000 0000 0000 0000 0000 0000 0101 num_2 = 0000 0000 0000 0000 0000 0000 0111 1111 num_3 = 0000 0000 0000 0000 0000 0000 1000 0100 进行整形阶段 num_3 = 1000 0100 */ printf("num_3 = %d\n", num_3); /* %d是以十进制的形式打印有符号整数 char num_3 = 1000 0100,符号位为1 整型提升: 1111 1111 1111 1111 1111 1111 1000 0100 补码转反码:1111 1111 1111 1111 1111 1111 1000 0011 反码转原码:1000 0000 0000 0000 0000 0000 0111 1100 -> -124 */ return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
下面两个例子也能说明整型提升的存在:
Eg1:
#include
int main() { char num_1 = 0xb6; short num_2 = 0xb600; int num_3 = 0xb6000000; if (0xb6 == num_1) printf("num_1\n"); /* num_1 = 1011 0110 整型提升:1111 1111 1111 1111 1111 1111 1011 0110 明显,与0xb6不相等 */ if (0xb600 == num_2) printf("num_2\n"); /* num_2 = 1011 0110 0000 0000 整型提升:1111 1111 1111 1111 1011 0110 0000 0000 可见,与0xb600不相等 */ if (0xb6000000 == num_3) printf("num_3\n"); /* num_3就是int型,不要整型提升,因此num_3即为0xb6000000 */ return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
Eg2:
#include
int main() { char num = 1; printf("sizeof(num) = %u\n", sizeof(num)); printf("sizeof(+num) = %u\n", sizeof(+num)); printf("sizeof(-num) = %u\n", sizeof(-num)); //%u是以十进制的形式打印无符号整数,由于操作符sizeof的值一定是整数,因此用%u打印 /* 由于num参与了运算,因此要整型提升为int型 */ return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
如果某个操作符的各个操作数属于不同的类型,那么除非其中的一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换
long double double float unsigned long int long int unsigned int int //向上转换 /* 没有char和short类型,是因为在使用时char和short要先整型提升为int */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
例如执行程序:
int num_1 = 5; float num_2 = 3.14; float num_3 = num_1 + num_2;
- 1
- 2
- 3
num_1和num_2相加时,int要先转换为float类型,再和num_2相加