自动转换发生在不同数据类型的变量混合运算时,由编译系统自动完成。自动转换遵循以下各则:
1.若参与运算变量的类型不同,则先转换成同一类型,然后进行运算。
A.char型和short型参与运算时,必须先转换成int型。
B.所有的浮点运算都是以双精度进行的,即使仅含float单精度变量运算的表达式,也要先转换成double型,再作运
算。A和B的运算都属于升级(promotion).
C.在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。按照从高到低的顺序给
各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned
long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned
int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们参与运算时就应该已经被
升级成了 int 或者 unsigned int。(在我用的编译环境中VC6,没有unsigned long long 和 long long,
sizeof long double, double, float, unsigned long, long, unsigned int, int, short, char的值
分别是8,8,4,4,4,4,4,2,1)
2.在赋值语句中,= 右边的值在赋予 = 左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。
3. 作为参数传递给函数时,char 和 short 会被转换成 int,float 会被转换成 double。使用函数原型可以避免这种自动升级。
二、上述转换的一些结果的一些结果。
1.无符号--有符号
A例:unsigned char uc = 255;
char c = uc;
printf("%d\n",c); 输出:-1 内存中11111111第一位转为符号位
B例: int i = 255;
char c = i;
printf("%d\n",c);
输出:-1 当将i赋值给char型的变量c时,会将i所在的内存空间中的最低一个sizeof(char)(即一个字节)的内容copy到c所在的内存空间中,即只截取适合左值变量大小的空间中的内容。
C例: char c = 2;
int i = c;
printf("%d"n",i);
输出2
char型变量c为2,在内存中的表示形式如下:
00000010 |
将c用于给int型变量i赋值,即将c转换成int型,先将c的一个字节的内存空间copy到i的最低一个字节,然后用c的符号位0填充i剩余的高3个字节,所以i的内存形式如下:
00000000 |
0000000 |
00000000 |
00000010 |
于是将i的这段内存内容以int型进行解释,即为2。
D: char c = -2;
int i = c;
printf("%d\n",i);
输出:-2
变量c为-2,在内存中的表示形式如下:
11111110 |
11111111 |
11111111 |
11111111 |
11111110 |
E:unsigned char c = -2;
int i = c;
printf("%d"n",i);
输出:254
用文字量-2为无符号char型变量c赋值,保存文字量-2的临时4字节内存空间的内容如下:
11111111 |
11111111 |
11111111 |
11111110 |
将该文字量通过截取最低一个字节的内容复制到unsigned char型变量c的内存空间中,得到c的内存内容如下:
11111110 |
再将c用于给int型变量i赋值,先将c的一个字节的内存内容copy到i的最低一个字节,由于c是unsigned char型变量,没有符号位,所以用0填充i剩余的高3个字节,得到i的内存内容如下:
00000000 |
00000000 |
00000000 |
11111110 |
将i的这段内容以int型进行解释,即为255。
2.混合计算。
A.unsigned int a=6;
int b=-20;
(a+b>6)?puts(">6"):puts("<=6");
unsigned char a1=6;
char b1=-20;
(a1+b1>6)?puts(">6"):puts("<=6");
unsigned short a2=6;
short b2=-20;
(a2+b2>6)?puts(">6"):puts("<=6");
unsigned int a3=6;
short b3=-20;
(a3+b3>6)?puts(">6"):puts("<=6");
unsigned short a4=6;
int b4=-20;
(a4+b4>6)?puts(">6"):puts("<=6");
输出结果是:>6,<=6,<=6,>6,<=6
把握住,short,char 之类是转换为int而不是unsigned int;而当unsigned int 和int一起
时,由于unsigned int 的范围比int大,所以转为unsigned int。当unsigned short和int
的大小一样时,也可能转为unsigned short
B. char ch;
int i;
float fl;
double db;
db = fl = i = ch = 'C'; /* 10 */
printf("ch=%c, i=%d, fl=%2.2f, db=%2.2f\n", ch, i, fl, db);
ch = ch + 1; /* 13 */
i = db + fl + 2 * ch; /* 14 */
fl = 2.0 * ch + i; /* 15 */
db = 22 * i + ch - fl; /* 16 */
printf("ch=%c, i=%d, fl=%2.2f, db=%2.2f\n", ch, i, fl, db);
第 10 行,'C' 的值被转换为 char,然后赋值给 ch。ch 的值被转换成 int,然后赋值给 i。
以此类推。
第 13 行,= 右边的 ch 的值先被转换成 int,然后和 1 相加,得到 32 位的 int 类型整数
68。最后,68 降级为 char,然后赋值给 ch。在 ASCII 中,D 的编码是 68。
第 14 行,ch 的值被转换成 int,然后和 2 相乘得 136。fl 的值被转换成 double,然后和
db 相加,其和再与转换成 double 的 136 相加得 270.0 。最后,270.0 被转换成 int,然
后赋值给 i。
第 15 行,ch 的值被转换成 double,然后和 2.0 相乘,i 的值被转换成 double,然后和前
面得到的乘积相加,相加的得数被转换成 float,然后赋值给 fl。
第 16 行,22 和 i 相乘得 5940,ch 的值被转换成 int,然后和 5940 相加得 6008,然
后,6008 被转换成 float,再和 fl 相减得 5602.0f,最后 5602.0f 被转换成 double,再
赋值给 db。
大部内容摘抄自:http://stdcpp.cn/html/1/2/0606/150.htm
http://mucian.bokee.com/4136626.html
有空再研究下强制类型转换。