1、为什么要进行强制类型转换?
-
什么是数据类型? 数据类型说明了一个变量的属性(空间大小以及存储结构),空间大小是指变量在内存中所占字节数,存储结构说明了变量是以什么类型的存储结构在内存中存储。比如:int a;从这个语句就可以看出,变量a在内存中所占空间大小是4字节,以int类型的结构存储在内存中。 -
接下来说为神马要进行强制类型转换? 因为有的时候我们需要将某些类型的数据转换为另一种类型的数据,比如:float a = 10;当我们需要一个整形的10,就可以将a转换为int型 int b = (int)a;
2、强制类型转换(对于普通变量)
在强制类型转换的过程中,可能会改变空间大小,也可能改变存储结构。
2.1 改变空间大小
char a = 1;
int b = (int)a;
在这段代码中,a的空间大小是1个字节,b的空间大小是4字节,char类型与int类型都是整型的数据类型,所以相互转换其存储结构不会发生改变,只改变空间大小。这里就是将1个字节转化为4个字节
int a = 0x11223344;
char b = (char)a;
在这段代码中,a占4个字节,b占一个字节,所以将int类型转换为char类型必将丢失3个字节数据,至于会留下0x11还是留下0x44,这个涉及到了计算机存储的大小端模式(在其他博客,没写…)。总之这里存储结构没有发生变化,但是空间大小会发生变化,会丢失一定的数据,所以谨慎使用。
2.2 存储结构发生改变
float a = 10.0;
int b = (int)a;
在这段代码中,a与b的空间大小都是4个字节。但是存储结构是不同的。
a以float类型存储在这4个字节的内存中 b以int类型存储在这4个字节的内存中 这里涉及到了临时匿名变量,可以看文章最后面的一节。至于结果,都知道。
3 强制类型转换(指针变量)
3.1 指向空间的强制类型转换
int a = 0;
float b = 20.34;
int *pa = &a;
float * pb = &b;
*pa = (int) *pb;
正如代码所示,1和2等价
3.2 指针本身强制类型转换
int a = 0;
int *pa = &a;
float *pb = NULL;
pb = (float *)pa;
如代码所示①②片段语句等价,指针变量pa 与指针变量pb都是占4个字节空间大小,只不过是存储结构不同,pa存储的是(int *)类型的数据,pb存储的是(float *)类型的数据。所以想在pb(float *)中存储pa(int *)类型的数据只能通过强制类型转换,将(int *)类型的地址数据转换为(float *)类型地址数据并存储在pb中。
实际上pa、pb都是指向a变量(int 类型),pa中存储的地址值等于pb中存储的地址值,但是*pa访问变量a的时候是以int类型的空间大小及存储结构进行访问,*pb是以float类型的空间大小和存储结构进行访问。
3.3 指针变量引用发生空间大小变化
float a = 10.0;
double *pa = (double)&a;
double b = *pa;
*pa = 123.45;
- ① 定义了一个float类型的变量a;(4字节)
- ② 定义了一个(double *)类型的指针变量,用来接受转换后的(double *)类型的地址《&a:取出a的地址【4字节】,(double)&a 将这个地址转换为double类型,然后存进pa中》
- ③ *pa:以double类型访问float类型的变量a,所以会访问到a内存空间的四个字节以及紧跟后面的四个字节。然后将访问到的这8个字节数据存放进变量b的内存空间中。
- ④ *pa = 123.45:以double类型去修改float类型的变量a,不仅会修改a空间的四个字节,还会修改紧跟a空间后面的四个字节内存空间。很明显这个错误很严重,访问了未知的内存空间。
3.4 指针变量引用发生存储结构变化
int a = 123;
float b;
float * pa = NULL;
pa = (float *)&a;
float b = *pa;
printf("&f\n",b);
分析:代码运行后会出现乱码!!!为什么?
① pa只能存储(float *)类型地址,所以取出a的地址,并将其转换为(float *)类型存储在pa中。
② *pa,以float类型的方式去访问int型的a变量,虽然两者都是四字节,但是存储结构不同,所以将a变量空间中的内容直接搬移到b空间中,很明显,int类型的存储空间与float类型的存储空间不同(至于怎样存储,嗯,www.baidu.com),所以b中的数据并不是按照float类型存储(这里并没有发生隐式转换。。。我猜的),所以打印不会得到正确的结果
4、临时匿名变量
float a = 10.12;
int b = (int)a;
- 在上述代码执行完后a与b的数据类型不会发生变化,为什么?
因为编译器会在内存的另一个地方创建一个临时变量x(int类型),然后将float类型的a变量的整数部分赋值给临时变量x,然后将x变量赋值给b变量,然后将临时变量x销毁。
这个x就是临时匿名变量(理解即可)
|