使用C++,还是了解点底层比较好~:)
来源:互联网 发布:万能数据恢复软件下载 编辑:程序博客网 时间:2024/05/01 13:29
工作闲暇的时候,同事跑来问我做一道关于C++的笔试题目,题目是这样的:
int szNum[5] = { 1, 2, 3, 4, 5 };
int *ptrA = (int*)(&szNum+1);
int *ptrB = (int*)((int)szNum + 1);
std::cout << ptrA[-1] << *ptrB << std::endl;
问打印结果是什么?
拿到题当然不能上机拿结果了:),不然就没有思考的乐趣了,首先就得自己分析一下了,对于ptrA,看到等式的右边就不难发现是考察的指针算术的概念,就是说对指针做算术不是简单的加一或者减一,而是要看其指针类型来做决定,这里szNum是一个指向整型数组第一个元素的指针,则其做取地址的操作的时候得到的是指向含有5个元素的整型数组的数组指针,也就是说其+1的时候数组指针应该会向后移动1个含有5个int元素的数组单位,也就是就是指向移动5个int单位之后的那个地方,而要打印的结果是ptrA[-1],表示是要回退一个int单位,所以结果应该是指向5的,应此ptrA[-1]打印的结果就应当是5,后面一个ptrB指向的答应结果又是什么呢,我们接下来继续分析,首先把数组的首地址转换成int类型,而后再加1,这里的加1就和上面的那个不一样了,这里考察的是Address Arithmetic(地址算术),这次的对象变成了一个首地址值,因此加一的话,应该是意味着加上一个字节,也就是说,这个首地址+1个字节的offset(偏移量),该地址里面存的结果又该是多少呢?这里我想到了一个叫做Big Endian&Little Endian的问题,也就是说
Big endian machine: It thinks the first byte it reads is the biggest.
大尾端机器:认为其读的第一个字节为最大的那位上的数。
Little endian machine: It thinks the first byte it reads is the littlest
小尾端机器:认为其读的第一个字节为最小的那位上的数。
而X86系列的机器据我所知都是Little endian的机器,因此在其存储的过程中就应当是如下的图景:(为了说明问题,地址乃自己构造的,内容是数组首地址指向的元素值,以及第二个元素值)
0X0001 : 01
0X0002 : 00
0X0003 : 00
0X0004 : 00
0X0005 : 02
0X0006 : 00
0X0007 : 00
0X0008 : 00
(int)szNum + 1 因此这个结果就为0X0002了,而其指向的结果是一个int型的元素,大小为四个字节,因此按照little endian机器的读法就是02 00 00 00了,结果的十六进制数就是0X2000000,转换为十进制数就为33554432,因此整个题目的打印结果是533554432。
OK,现在可以在电脑上去验证一下了:
int szNum[5] = { 1, 2, 3, 4, 5 };
004124BE mov dword ptr [ebp-18h],1
004124C5 mov dword ptr [ebp-14h],2
004124CC mov dword ptr [ebp-10h],3
004124D3 mov dword ptr [ebp-0Ch],4
004124DA mov dword ptr [ebp-8],5
首先是这个数组初始化后5个元素所存储的位置,可以发现这里int型占四个字节,
int *ptrA = (int*)(&szNum+1);
004124E1 lea eax,[ebp-4] //加载移动后地址里的数据到EAX(好奇的人会问移动之前是那个地方呢?其实算一算就知道了(不用算也知道哈哈,肯定是首地址的位置,为了证实一下算一算熟悉过程),移动以后是ebp-4,移动了5个int元素的空间也就是20个字节,20 == 0X14h,那么移动前就是ebp-4h-14h == ebp - 18h)
004124E4 mov dword ptr [ebp-24h] //把指向int元素的指针地址赋给ptrA
int *ptrB = (int*)((int)szNum + 1);
004124E7 lea eax,[ebp-17h] //地址算术原来是ebp-18h移动一个字节后变成ebp-17h
004124EA mov dword ptr [ebp-30h],eax // 赋值
好了分析完毕了,我想说的是在c++编程过程中还是了解点底层好,特别是汇编,这样很容易分析出结果,对于指针的一些复杂操作通过对底层的了解,看看汇编出来的结果就很容易理解了,有空的时候我会分析一下 ++ptr和ptr++以及 A+=B 是否真的是 A = A + B的问题(我记得上学的时候就有人讲过不过不幸的是误导居多),以及c++程序的汇编结构问题,这些问题同样是通过汇编看底层很容易理解的。
- 使用C++,还是了解点底层比较好~:)
- 使用C++,还是了解点底层比较好~:)[续1]
- 还是努力点好
- 还是这个好点
- 在C++里面使用++i 还是i++比较好???
- 网络发送同步请求——(开发中一般不会使用,但是还是了解的好)
- 比较好点的博客
- 是C语言、VB、VF还是哪个 我想问一下全国计算机二级考哪个比较好
- 写简历,还是实在点好!!!
- 人还是要有点城府的好。
- 性价比还是Arduino Duemilanove 2009比较好
- 大文件中,还是sax比较好
- 嗯,还是写一篇博客比较好!
- 控制菜单的比较麻烦的一种思路(不推荐使用),后面还有较为好点的
- Web开发中使用全局类还是application\sesstion比较好?
- objective-c代码转c++代码,了解底层实现机制
- 如何使用笔记本电池比较好
- 先学C语言好还是先学JAVA好
- 多线程,多在那呢?
- Becky!使用集要(0516版)
- 指向const对象的指针和const指针
- Becky!经典使用问题集(0516版)
- 爱,请在来得及的时候说出口
- 使用C++,还是了解点底层比较好~:)
- SQL Server连接中常见错误解决方法
- Shell十三问
- .net 2.0(c#)下简单的FTP应用程序
- [转]使用FileConnection访问文件系统
- html相关的一些规范(转转)
- 监控系统故障的解决方法
- 800-15000的过程(转转)
- Java Bean 中使用JDBC方式进行事务处理