强制类型转换中“自以为是”的问题
来源:互联网 发布:淘宝销售计划书 编辑:程序博客网 时间:2024/06/11 09:59
一、“自以为是”引发的错误
1、问题来源:
# include <iostream>using namespace std;int main (void){ int i = -185; int * p = &i; char * q = (char *)p; char ch = *q; cout << ch << '\t' << (short)ch << '\t' << (int)ch << endl; cout << (char)i << '\t' << (short)i << '\t' << i << endl; return 0;}
最近在学习C++,闲来无事突发奇想随便写了几行代码,如上所示。本以为输出结果会是:
G -185 -185G -185 -185Press any key to continue
而最终结果却是:
G 71 71G -185 -185Press any key to continue
2、这种错误想法的来源
如下图:
int x = -185在内存中的二进制存储:
错误出就出在了误以为ch的内存,就是q指向的地址,即0X18FF3C这一个字节,并以此错误为基础认为:
ch 是1000 0111十进制为71即71的ASCII对应字符G;那么(short)ch当然是占用了0X18FF3C和0X18FF3D两个字节,其二进制为1111 1111 1000 0111,所以结果为-185;(int)ch则占用了x的所有四个字节内存,结果依然为-185;
自以为是这样,而实际并非如此,即“自以为是而以人为非也”。那么真正的存储形式是怎样的呢?
二、问题的关键所在
1、系统为ch分配的内存在哪?
首先我们来看变量ch的地址测试结果:
注意测试时,由于cout的特性需要在&ch和q前加上(int *),否则输出的就是字符形式的类似于乱码的地址了。由测试结果可以看出,指针q的指向和指针p的指向相同,但是ch的地址并非“自以为是”的q指向的地址。而是下图所示的存储形式:
测试结果:
存储形式:
2、解释所有问题:
这样就可以解释为什么,强制转换x和强制转换ch的输出结果有差异的问题了:
(1)、ch的地址并非q指向的地址,q指向的地址也并非为ch所占有,只是ch通过*q读取了q指向地址的存储值1000 0111,并复制了该二进制到自己所占有的内存之中即0X18FF30。而强制类型转换(short)ch,(int)ch都只读取了ch仅有的1000 0111,所以其值也为71(或者G)。
(2)、对于如何通过ch和*q的区别,我们可以用以下代码具体地完全地区分开(对于C++的cout使用时的细节还不是特别熟悉。所以用C代码测试):
# include <stdio.h>int main (void){ int i = -185; int * p = &i; char * q = (char *)p; char ch = *q; printf("%d\t%d\t%c\n", i,(short)i, (char)i); printf("%d\t%d\t%c\n", *p, *((short*)p), *(char *)p); printf("%d\t%d\t%c\n", *((int *)q), *((short *)q) ,*q); printf("%d\t%d\t%c\n", (int)ch, (short)ch, ch); printf("%#x\t%#x\t%#x\n", i,(short)i, (char)i); printf("%#x\t%#x\t%#x\n", *p, *((short*)p), *(char *)p); printf("%#x\t%#x\t%#x\n", *((int *)q), *((short *)q) ,*q); printf("%#x\t%#x\t%#x\n", (int)ch, (short)ch, ch); return 0;}
代码运行结果为:
-185 -185 G-185 -185 G-185 -185 G71 71 G0xffffff47 0xffffff47 0x470xffffff47 0xffffff47 0x470xffffff47 0xffffff47 0x470x47 0x47 0x47Press any key to continue
q是指向x地址首字节的指针,只要将其类型char * 强制转换成int * ,其特点与属性就与指针p完全相同,也对x有了完全的操作权限。而ch仅仅是x地址首字节存储内容的拷贝,和x没有任何直接关系 。
1 0
- 强制类型转换中“自以为是”的问题
- 强制类型转换的问题
- 类型强制转换的问题
- (+=)运算符中隐藏的强制类型转换问题
- java中强制类型转换问题
- foreach 参数强制类型转换的问题
- 一个强制类型转换的问题
- 关于强制类型转换的小问题
- Java中对象类型的强制转换
- C++中强制类型转换的应用
- Java中对象类型的强制转换
- java中强制类型转换的注意
- 强制的类型转换
- 强制类型的转换
- String强制类型转换问题
- 强制类型转换注意问题
- 强制类型转换与非强制类型转换后出现的问题
- C#中强制类型转换
- CSS快速学习10:高度自适应
- 12. Integer to Roman
- Android关键进程与服务与Root原理
- java读取文件并且制定编码
- Java之网络爬虫WebCollector+selenium+phantomjs(三)
- 强制类型转换中“自以为是”的问题
- 问题:如何让HorizontalScrollView中的item能滚动的时候点击居中
- Latex使用技巧1
- Spring AOP四种实现方式Demo详解与相关知识探究
- 为Centos7虚拟机分配固定IP
- usaco第二题稍微有点难。。。结构体就ac
- 浏览器最小字号
- Centos网络配置
- VMware Workstation12Pro 安装linux教程