参考1:C语言中的数据类型的隐式转换
参考2:C语言隐式类型转换和整型提升
1. c语言整值提升规则
double ← float ⾼
↑
long
↑
unsigned int
↑
int ← char或short 低
- 在c语言的运算中,如果两个数据的类型不一样,将会按照上述规则将低级数据类型转换成高级数据类型再运算。
- 如果表达式(如 算术计算和 关系判断)中的所有数据类型都⼩于int (⼩于int的有 枚举类型,bool、char、unsigned char、short ),则会将这些数据类型全部提升为int或unsigned int,提升后再进⾏表达式计算,计算后再进⾏截断得到最终结果。
2. c语言数据类型隐式转换场景
- 算术运算时,低级转换为高级数据类型后再运算;
- 赋值时,右值转换为左值类型;
- 函数传参时,强制转换成形参类型;
- 函数返回值时,强制转换为返回值类型;
3. 典型题目
int i = -2;
unsigned int j = 1;
if( (i + j) >= 0 )
{
printf("i+j>=0\n"); //结果输出该句
}
else
{
printf("i+j<0\n");
}
printf("i+j=%d\n", i + j);//结果输出-1
// 原因,i+j隐式转换成了unsigned int类型,肯定大于0;
// printf打印时又将i+j的结果转换成int类型,所以是-1;
uint32_t a=3;
cout << "cout<<a*-1="<< a * -1;//结果4294967293=0xfffffffd
printf("a * -1 = %d\n", a * -1); //结果-3
//原因,由于cout是将数据原始类型输出。数字默认是int型,所以-1先转成uint32_t类型后再计算。
//-3的16机制也是0xfffffffd,由于printf的参数是%d,所以这里又有一个隐式转换。
4. windows下的自测验证
#include <stdio.h>
#include <stdint.h>
void main(void)
{
int8_t _int8_1 = -1;
uint8_t _uint8_1 = -1;
uint8_t _uint8_2 = 1;
int16_t int16_1 = -1;
int16_t int16_2 = 2;
uint16_t uint16_1 = 1;
int32_t int32_1 = 1;
uint32_t _uint32_1 = 10;
printf("_int8_1 < _uint8_1 =%d\n",_int8_1 < _uint8_1);
printf("_int8_1 > 26 =%d\n",_int8_1 > 26);
printf("_uint8_1 > 26 =%d\n",_uint8_1 > 26);
printf("_uint8_1 > -1 =%d\n",_uint8_1 > -1);
printf("_int8_1 > _uint8_2 =%d\n",_int8_1 > _uint8_2);
printf("-1 > _uint8_2 =%d\n",-1 > _uint8_2);
printf("_int8_1 > _uint32_1 =%d\n",_int8_1 > _uint32_1);
printf("_int8_1 > int16_1 =%d\n",_int8_1 > int16_1);
printf("_int8_1 > uint16_1 =%d\n",_int8_1 > uint16_1);
printf("int16_1 > uint16_1 =%d\n",_int8_1 > int16_1);
printf("int16_1 > int32_1 =%d\n",int16_1 > int32_1);
printf("int16_1 > _uint32_1 =%d\n",int16_1 > _uint32_1);
}
根据测试结果得出结论:
- 当uint32_t的数和有符号数变量或常数做运算时,是无符号数之间的运算;
- 当uint16_t的数和有符号数变量做运算时,是有符号数之间的运算;
- 当uint64_t的数和常数做运算时,是无符号数之间运算;