关于微软 2012 暑期实习题第 5 题

简介:     本文中提到的题目来自于这篇文章:《2012微软暑期实习笔试题及答案》 中的第五题。这道题目是这样的:   5. What is output if you compile and execute the following code?void main() {     int ...

    本文中提到的题目来自于这篇文章:《2012微软暑期实习笔试题及答案》 中的第五题。这道题目是这样的:

 

5. What is output if you compile and execute the following code?

void main()
{
    int i = 11;
    int const *p = &i;
    p++;
    printf( "%d", *p);
}

(A) 11;  (B) 12;  (C) Garbage value;  (D) Compile error;  (E) None of above.

 

    首先,很显然这道题目第一要考察 const 的写法,也就是这个代码中 const 修饰的是指针变量 p 还是被 p 指向的整数。简单的记忆的方法就是 const 修饰的是最靠近它的东西,左侧优先。因此这句话中 const 修饰的是左侧的 int,即相当于 const int* p; 所以通常采用后者这种写法,因为后者更符合阅读(pointer to const int),不容易引发认知错误。因此,上面的代码能通过编译,即答案 (D)首先可以被排除。

 

    p++ 使 p 向高地址移动了一个 int 的距离(对于win32,4 bytes),移动后指向了什么位置呢?显然依然是一个栈上地址。但这道题目是不是就应该选(C)Gargage Value 呢?所以这道题目比较有趣,它涉及到了函数调用时 stack frame 的细节。因此我们还需要更明确的分析 stack 上的存储内容,明确 p 指向了什么,然后才能给出结论。

 

    我们先给出一个基本结论,p 被初始化指向 i (因为 i 是第一个出现的临时变量,所以 i 是最靠近返回值地址的(savedPC)),这时继续让 p 的指向向 savedPC 的方向移动一个 int 元素跨度。【注意减小 sp 相当于在栈上开辟空间,增加 sp 相当于释放栈上空间,p++ 使得向栈内方向而不是栈外方向移动,正是这种移动方向导致这道题的答案带有了争议性。我们非常希望 int 不是第一个临时变量,假设它前面还有其他变量,那么我们就可以更明确的指出 p 会指向在 i 之前出现的临时变量。可惜 i 就是第一个临时变量。假如编译器分配空间时,让 i 和 savedPC 紧邻,则这会导致 p 指向 savedPC。但幸运的是,在后面的分析中可以看到编译器竟然会在 i 和 savedPC 可能会预留出垃圾数据。】

 

    首先把上面的代码用 VC6.0 做一个实验,编译配置是 Win32 Debug,把最后一句替换成 printf("%08X\n", *p); 发现输出结果是:0012FFC0。

    然后使用 IDA 反汇编分析可执行文件。

    首先,main 函数的返回值类型和参数列表(本题目中为 void main ( void ); )不重要,不会影响生成的代码。生成的 main 函数实际上是三个参数,汇编代码对应的原型是:

 

    int main(int argc, char* argv[], char* environ[]);

 

    其中 environ 是一个废弃参数,类似 argv 它也是一个字符串数组,以 NULL 元素为截止标志,是一些"key = value"形式的系统环境变量之类的字符串。

 

    使用 VC6 debug (注意:不同编译器,不同编译选项结果不同,参考补充部分),main 函数的汇编代码如下:

 

 main            proc near               ; CODE XREF: j_main
目录
相关文章
|
6天前
|
Java Go 开发者
2023年终总结-一名23届毕业生的风雨秋招路
人生如巧克力,充满未知。23届大学生经历网课、封校后迎来秋招寒冬,笔者投递三百多家公司,最终收到三个Offer。签约中厂后,享受短暂的轻松时光。热爱编程,参加字节青训营,获技术提升与人脉积累。毕业旅行至云南时突遇毁约,但家人支持下继续前行。重新求职后选择深圳工作,入职半年收获良多。展望2024,立下多个目标,愿新的一年实现愿望。
19 4
|
8月前
|
机器学习/深度学习
2021牛客暑期多校训练营1(补题)
2021牛客暑期多校训练营1(补题)
47 0
|
消息中间件 前端开发 NoSQL
末流院校24届秋招逆袭之路!
末流院校24届秋招逆袭之路!
72 0
末流院校24届秋招逆袭之路!
|
消息中间件 缓存 架构师
P5直升P7!“阿里爸爸”最新出品年薪30W~120WJava架构师学习路线
2022年是对程序员极不友好的一年,像往年这个时间段一般是程序员跳槽涨薪的黄金期,是很多程序员集体往大厂冲刺的时间段;但由于上一季度国内疫情反复,各大厂纷纷裁员,整得整个互联网行业人心惶惶,纷纷质疑:大厂还值得去吗?程序员这个行业是不是不行了?我还有必要继续学习吗?
|
数据采集 人工智能 算法
|
JavaScript 前端开发 jenkins
我的暑期生活
我是一名在校大二学生,目前就读于计算机网络专业,经常游走于各大论坛,学习各种计算机知识,目前对服务器相关知识也是非常痴迷,想着在假期也弄一下服务器,把自己做的网页放在服务器上,然后通过阿里云首页了解到“飞天加速计划·高校学生在家实践”活动,于是就试着申请了一下,接下来就给大家展示一下我的成果。
我的暑期生活
|
存储 人工智能 分布式计算
想当程序员吗?这11所大学计算机专业堪称国内顶级,高考考生千万不要错过
为大家盘点一下目前国内计算机专业比较好的大学。
329 1
|
域名解析 弹性计算 前端开发
|
Arthas NoSQL 算法
二本院校学弟大二开始实习,大三收割阿里、腾讯实习offer
二本院校学弟大二开始实习,大三收割阿里、腾讯实习offer
二本院校学弟大二开始实习,大三收割阿里、腾讯实习offer
|
iOS开发
听说过“史蒂夫·乔布斯”公司吗?
苹果公司前任CEO和创始人之一,史蒂夫·乔布斯(Steve Jobs),应该是很多果粉,乃至整个科技圈和企业圈很多人的偶像。他于2011年10月去世后,到现在还是有很多人在缅怀这位电脑业界与娱乐业界的标志性奇才。
210 0
听说过“史蒂夫·乔布斯”公司吗?