导言:
强制数据类型转换在我们的工作和学习中使用得非常的多,所以很有必要弄清楚其中的本质和原理,我们通过代码的测试来验证以及加强我们对知识点的理解!!!
强制数据类型转换的形式:(type)数据,其中,type代表的是要转换成什么类型,这边的数据可以变量,也可以是函数的返回值。
分类
一、强转基本数据类型
例子1
引入:
我们来看一个例子,比如13+13.3,当我们在C语言中这样去写的时候,编译器是怎样进行处理的呢?它是将13隐式转换成13.0(double类型),因为按照规则来,double的类型强度>int类型强度的,编译器一看13是int,但是根据只有同类型的数据才能进行运算的规则,只好将13(int)转换成13.0(double),此时就发生了隐式数据类型的转换,最终的结果是26.3.
强制转换:
13+13.3,其实对于我们还可以有另外一种做法,即我们人为的进行干预,我们可以将13.3强制转换成13,形式是:(int)13.3,这样,我们就将13.3转换成int型的13了,这本质上其实就是一个显式数据类型转换,最终的结果就是26(int)了,因为把一个浮点型的数据转换成整型数据的时候,结果就是将小数点后面的全部去掉,留下整数部分.
代码测试:
printf("%lf,%d\n",13+13.3,13+(int)13.3);
结果截图:
notes(注意点):
强制类型转换也是具有一定的要求的,并不是可以随随便便的进行转换,比如我们要将1234.5强制转换成char类型的,你们想想能够行得通吗? 我们知道,char类型的本质是一个整数,而有符号的char范围是-128~127,无符号的char范围是0~255,因为char类型的代表的是一个字节,所以(char)1234.5,进行强转的时候,是会出现问题的
代码测试:
unsigned char t = (unsigned char)1234.5; //1234%256
printf("%d\n",t);
结果截图:
分析结果:为什么是210呢?因为编译器认为1234.5太大了,自己根本没有办法将这么大的数放到小小的unsigned char类型的变量中,毕竟unsigned char的范围是255,哈哈,于是它就这样做:把1234.5->1234->1234%256,最终的结果就是模256,进行了一个模运算
二、强转指针类型(重点)
指针在C语言中,既是一个重点也是一个难点,特别是在指针的类型这块,因为指针的类型决定了指针每一次对内存的操作大小(一次操作几个字节),如果指针的类型改变,那么对内存的操作情况(比如int*类型的指针,一次读写4字节空间,double*类型的指针,一次读写8字节的空间)是不同的。
例子1:
代码:
int a = 12; //定义了变量a,开辟了4字节的空间
double *p = (double*)&a; //获得第一个字节的地址,将地址类型转换成double型
*p = 21.3; //通过*内存操作符去操作空间,此时操作的是8个字节的空间,已经越界了,合法的只有我们申请的4个字节
结果截图:
结果分析:
根据程序运行的结果,得到如上所示的异常,这样的异常是由于内存越界造成的,为什么呢?根据提示,说a这个变量被破坏(直接翻译是这样了,哈哈),其实就是内存越界了,根据上面的代码注释,我们知道a这个变量占用4个字节的空间,我们使用double*的指针去指向a这个空间,那么然后进行了内存的操作,而这次操作,一次性操作的是8个字节的空间,因此造成了内存越界的情况。所以强转的时候一定要小心,不要越界.
例子2:
代码:
double a = 12.3;
int *p = (int*)&a;
*p = 12;
结果分析:
执行以上代码之后,程序的运行情况是正常的,不会有异常的发生,为什么呢?此时,a这个变量占用了8字节的空间,我们定义了一个int*指针去指向这块空间,当我们用指针去操作这块内存的时候,我们操作的是4个字节的空间,并没有造成内存访问越界的问题,因此并不会报告异常.
例子3:
代码:
int a = 12;
float *p = (float*)&a;
*p = 12.2;
结果分析:
执行以上代码之后,程序的运行情况是正常的,不会有异常的发生,为什么呢?此时,a这个变量占用了4字节的空间,我们定义了一个float *指针去指向这块空间,当我们用指针去操作这块内存的时候,我们操作的是4个字节的空间,并没有造成内存访问越界的问题,因此并不会报告异常.
总结:
指针这块的知识点是很重要的,所以一定要去弄清楚这些指针的类型,和类型对应的一次能够操作多少大小的内存空间。