C语言中数据类型的自动类型转换

非常的重要的声明:
这篇博客的内容,主要参考网友的博客
尊重知识产权,尊重原创!

一、 C在以下四种情况下会进行隐式转换:

  1. 算术运算式中,低类型能够转换为高类型。
  2. 赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
  3. 函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
  4. 函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

二、 运算表达式中的自动类型转换

运算表达式中,有如下类型转换规则:

  1. 字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。
  2. short型转换为int型(同属于整型) 。
  3. float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型)

其次,有下面的规则:

当不同类型的数据进行操作时,应当首先将其转换成相同的数据类型,然后进行操作,转换规则是由低级向高级转换。转换规则如下图所示:
C语言中数据类型的自动类型转换

如上图所示,再根据上述的算数表达式的转换规则,我们可以得知:

  • 字符型数据和short型数据在算术表达式中,一律转换为int型数据后,再参与运算。
  • float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型)。
  • 注意有符号数与无符号数之间的运算中出现的转换。

三、 有符号数与无符号数之间的运算中出现的转换

当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此,从这个意义上讲,无符号数的运算优先级要高于有符号数,这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。

举个栗子:
代码如下:
C语言中数据类型的自动类型转换
运行结果如下:
C语言中数据类型的自动类型转换
结果分析如下:

在c语言操作中,如果遇到无符号数与有符号数之间的操作,编译器会自动转化为无符号数来进行处理,因此a=20,b=4294967166,这样比较下去当然b>a了。

再举个栗子:
C语言中数据类型的自动类型转换

编个代码测试如下:(注意要用gdb调试,不要用printf函数打印。因为printf函数会对传进去的参数进行类型转换。)
C语言中数据类型的自动类型转换
gdb调试结果如下:(结果不是:-3)
C语言中数据类型的自动类型转换


以下全文摘抄自网友博客


下表来自MSDN:
C语言中数据类型的自动类型转换
对上表补充说明一下:
1)在32位机上,int型和unsigned int型都是32位的(4个字节)。
2)enum会跟据最大值来决定类型,一般来说为int型,如果超出int型所能表示的范围,则用比int型大的最小类型来表示(unsigned int, long 或者unsigned long)
3)关于类型的大小。一般用所能表示的数据范围来比较类型的大小,如char型unsigned char型short型…在表达式中,一般都是由小的类型向大的类型转换(强制类型转换除外)

  1. 所有比int型小的数据类型(包括char, unsigned char, short, unsigned short)转换为int型。如果转换后的数据会超出int型所能表示的范围的话,则转换为unsigned int型;
  2. bool型转化为int型时,false转化为0,true转换为1;反过来所有的整数类型转化为bool时,0转化为false,其它非零值都转为true;
  3. 如果表达式中混有unsigned short和int型时,如果int型数据可以表示所有的unsigned short型的话,则将unsigned short类型的数据转换为int型,否则,unsigned short类型及int型都转换为unsigned int类型。举个例子,在32位机上,int是32位,范围–2,147,483,648 to 2,147,483,647,unsigned short是16位,范围0 to 65,535,这样int型的足够表示unsigned short类型的数据,因此在混有这两者的运算中,unsigned short类型数据被转换为int型;
  4. unsigned int 与long类型的转换规律同3,在32位机上,unsigned int是32位,范围0 to 4,294,967,295,long是32位,范围–2,147,483,648 to 2,147,483,647,可见long类型不够表示所有的unsigned int型,因此在混有unsigned int及long的表达式中,两者都被转换为unsigned long;
    (我自己的理解:在32位机上,unsigned long 和 unsigned int 是等效的,所以才会出现下面的结果。)
    C语言中数据类型的自动类型转换
  5. 如果表达式中既有int 又有unsigned int,则所有的int数据都被转化为unsigned int类型。

经过这番总结,前面提出的问题的答案应该就很明显了吧。在表达式a*-1中,a是unsigned int型,-1是int型(常量整数的类型同enum),按第5条可以知道-1必须转换为unsigned int型,即0xffffffff,十进制的4294967295,然后再与i相乘,即4294967295*3,如果不考虑溢出的话,结果是12884901885,十六进制0x2FFFFFFFD,由于unsigned int只能表示32位,因此结果是0xfffffffd,即4294967293。