--事物的难度远远低于对事物的恐惧!
在本章节,我们来聊聊C语言中的类型转换,我们知道,C语言中有int、char等不同的数据类型,他们在内存中的表示方式也不一样,那么在这里提出的问题是:不同的数据类型间,可以相互转换吗?假如可以,转换过程会发生什么我们所不知道的事?针对这个问题,我们一起来聊聊。
开门见山:C语言中的数据可以进行类型转换!类型转换又分为强制类型转换与隐式类型转换。下边通过代码来展示两种不同的转换方式。
#include <stdio.h>
int main()
{
long l = 200;
int i = (int)l; //强制类型转换
short s = 200;
int j = s; //隐式类型转换,no error no warning
return 0;
}
强制类型转换:
语法 (Type)var_name 或(Type)value
转换结果:
-目标类型能够容纳目标值:结果不变
-目标类型不能容纳目标值:结果将产生截断
但是要注意的是:强制类型转换不一定都能成功,当不能进行强制类型转换时,编译器将产生错误信息。
下边这个例子,可以很明显的体现强制类型转换所发生的情况。
#include <stdio.h>
struct TS
{
int i;
int j;
};
struct TS ts;
int main()
{
short s = 0x1122;
char c = (char)s; //char类型不能容纳short类型,产生截断,结果为 0x22
int i = (int)s; //int类型能容纳short类型,不产生截断,结果为 0x00001122
int j = (int)3.1415; //产生截断,只保留整数部分,结果为 3
unsigned int p = (unsigned int)&ts; //与运行环境有关,32位环境,&ts占四个字节,不会产生截断
//64位环境,&ts占8个字节,会产生截断
//long l = (long)ts; // error,编译错误
//ts = (struct TS)l; // error,编译错误
printf("s = %x\n", s);
printf("c = %x\n", c);
printf("i = %x\n", i);
printf("j = %x\n", j);
printf("p = %x\n", p);
printf("&ts = %p\n", &ts);
return 0;
}
运行结果为:
隐式类型转换:
隐式类型转换时编译器主动进行的类型转换,对于隐式类型转换,需要谨记2点:
-低类型到高类型的转换,是安全的。例如char转换为int,因为int类型目标能够容纳char类型变量大小。
-高类型到低类型的转换,是不安全的。例如int型要转换成char型,目标char型无法完全容纳int类型。
隐式类型转换广泛存在于表达式中,对隐式类型转换的不清楚,就及容易埋下bug,下边来说说表达式中的隐式类型转换发生的时机。
-算术运算中,低类型隐式转换为高类型
-赋值表达式中,右边的值隐式转换为左边变量的类型
-函数调用时,实参转换为形参的类型
-函数返回值,return表达式转换为返回值类型
下边图中的隐式转换方式是安全的转换方式
通过一个代码来展示隐式类型转换所发生的情况
#include <stdio.h>
int main()
{
char c = 'a';
int i = c; // 安全的隐式类型转换
unsigned int j = 0x11223344; //安全的隐式类型转换
short s = j; // 不安全的隐式类型转换,会产生截断
printf("c = %c\n", c);
printf("i = %d\n", i);
printf("j = %x\n", j);
printf("s = %x\n", s);
printf("sizeof(c + s) = %d\n", sizeof(c + s)); //c 跟 s都会隐式转换为int类型
return 0;
}
输出为:
从输出结果可以看出,不安全的隐式类型转换,会产生截断行为,所以在写代码的时候,需要格外的注意。
总结:
1、强制类型转换由程序员负责完成
-转换可能产生截断
-转换不区分类型的高低
-转换不成功是,编译器会给出错误信息
2、隐式类型转换由编译器自动完成
-低类型向高类型的转换时安全的
-高类型向低类型的转换时不安全的
-隐式转换可能带来意外的错误