注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:ubuntu 14.04
GCC版本:4.8.4
一、类型之间的转换
1)C语言中的数据类型可以进行转换
* 强制类型转换
* 隐式类型转换
int main()
{
long l = 800;
int i = (int)l; //强制类型转换
short s = 800;
int j = s; //隐式类型转换
//no error, no warning
return 0;
}
二、强制类型转换
1)强制类型转换的语法
* (
Type
)var_name;
* (
Type
)value;
2)强制类型转换的结果
* 目标类型
能够容纳
目标值:
结果不变
* 目标类型
不能容纳
目标值:
结果将产生截断
注意:
不是所有的强制类型转换都能成功,当不能进行强制类型转换时,编译器将产生错误信息。
实例分析
强制类型转换分析
4-1.c
#include <stdio.h>
struct TS
{
int i;
int j;
};
struct TS ts;
int main(void)
{
short s = 0x1122;
char c = (char)s; //0x22,数据高位截断
int i = (int)s; //0x00001122
int j = (int)3.1415; //3
unsigned int p = (unsigned int)&ts;
printf("s = %#x\n", s); //0x1122
printf("c = %#x\n", c); //0x22
printf("i = %#x\n", i); //0x00001122
printf("j = %#x\n", j); //0x3
printf("p = %#x\n", p);
printf("&ts = %p\n". &ts);
return 0;
}
操作:
1)gcc 4-1.c -o 4-1.out编译,打印如下:
s = 0x1122
c = 0x22
i = 0x1122
j = 0x3
p = 0x804a024
&ts = 0x80a024
分析:
编译正常,都可以正常打印。
2)增加内容,测试强制转换失败:
#include <stdio.h>
struct TS
{
int i;
int j;
};
struct TS ts;
int main(void)
{
short s = 0x1122;
char c = (char) s; //0x22,数据高位截断
int i = (int) s; //0x00001122
int j = (int)3.1415; //3
unsigned int p = (unsigned int) &ts;
long l = (long) ts; //error 结构体不能转换成其他类型
ts = (struct TS)l; //error
printf("s = %#x\n" , s); //0x1122
printf("c = %#x\n" , c); //0x22
printf("i = %#x\n" , i); //0x00001122
printf("j = %#x\n" , j); //0x3
printf("p = %#x\n" , p);
printf("&ts = %p\n" , &ts);
return 0;
}
gcc 4-1.c -o 4-1.out编译错误:
4-1.c:23:2: error: aggregate value used where an integer was expected
long l = (long) ts;
^
错误:结构体的值期望被转换为long
4-1.c:24:15: error: conversion to non-scalar type requested
ts = (struct TS)l;
^
错误:基础类型转换为结构体类型
解释:
编译时如果有无法转换成功的类型,编译器会报错。
三、隐式类型转换
1)隐式类型转换
*
编译器主动进行的类型转换
char c = 0; //变量C占用1个字节
short s = c; //c到s隐式类型转换
int i = s; //s到i隐式类型转换
long l = i; //i到l隐式类型转换
注意:
低类型到高类型的隐式类型转换是安全的,不会产生截断;
高类型到低类型的隐式类型转换是不安全的,会产生截断,可能丢失数据。
四、表达式中的隐式类型转换
1)隐式类型转换的发生点
* 算术运算式中,低类型转换为高类型
* 赋值表达式中,表达式的值转换为左边变量的类型
* 函数调用时,实参转换为形参的类型
* 函数返回值,return表达式转换为返回值类型
实例分析
隐式类型转换分析
4-2.c
#include <stdio.h>
int main()
{
char c = 'a';
int i = c; //safe,低类型转换为高类型
unsigned int j = 0x11223344;
short s = j; //unsafe,0x3344
printf("c = %c\n",c); //a
printf("i = %d\n", i); //97
printf("j = %x\n", j); //0x11223344
printf("s = %x\n", s); //0x3344
printf("sizeof(c + s) = %d\n", sizeof(c + s)); //4
return 0;
}
操作:
1)gcc 4-2.c -o 4-2.out编译,打印如下:
c = a
i = 97
j = 11223344
s = 3344
sizeof(c + s) = 4
分析:
* unsigned int转换为short,发生截断,导致高位数据丢失(小端系统)
* 计算c+s大小时,先将字符c隐式转为int型
小结
1)强制类型转换由程序员负责
* 转换可能产生截断
* 转换不区分类型的高低
* 转换不成功时,编译器给出错误信息
2)隐式类型转换由编译器自动完成
* 低类型向高类型的转换是安全的
* 高类型向低类型的转换是不安全的