C语言中可以做隐式类型转换,不需要我们明确指明,这点很方便,当有时候也带来隐性的问题。先看看C语言中隐式类型转换的规则:
1)、算术运算式中,低类型转换为高类型;
类型的高低参考下图:
2)、赋值表达式中,表达式的值转换为左边变量的类型;
例如:
int i=0;
char c=’a’;
i=c;//这里的变量c会被转换成int类型,值为‘a’的ASCII码
3)、函数调用时,实参转换为形参类型;
4)、函数返回值,return 表达式转换为返回值类型。
试着分析如下的程序:
#include <stdio.h>
int main()
{
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);
return 0;
}
运行结果为:
按照我们正常的计算,结果应该是-1,输出的应该会是“i+j的值小于0!”,而这里正好相反,输出了“i+j的值大于0!”!!这是什么问题?要说计算出错,可为什么最后一句输出的是正确的值-1呢??
实际上问题出在if判断语句中的“(i+j)>=0”此句上,按照变量的定义,i为int型变量,j为unsigned int 类型,它们属于不用类型的值相加,那么它们相加前就会产生类型转换,转换成unsigned int 类型后再相加,i为int类型,且值为-2,那么在内存中表示为-2的补码:
16进制形式为:
此时将它转换成一个无符号整型,即是无符号的16进制数:
换成十进制为:
让它加1肯定大于0,即是说此时i+j的值被当作一个无符号整数来看待的,因此才会有大于0的判断;
那为什么最后输出的是正确的值-1呢?
原因出在我们使用了%d这个格式字符,表示以带符号的十进制形式输出整数!
根据以上的分析,-2在内存中的补码应该为:
只是此时把该补码当作无符号整型来看待,在这个二进制基础上加上二进制的1,结果就成了:
在使用%d格式输出时,又把它看做有符号的整数,因此结果就成了-1;其实也可以反向来证明,通过计算也能发现,-1的补码其实也就是: