微软 2004-11-13 笔试题解析

本文对微软2004年11月13日的笔试题进行解析。第一题考查结构体的内存使用,分析程序运行时出现访问非法内存错误的原因,还给出VC解析的汇编代码;第二题是数字推理题,根据条件确定ABCDEF的值,给出了多位热心朋友提供的不同解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


笔试题

微软 2004-11-13 笔试题解析


  者:杨延庆
E-mail
blankmanATtomDOTcom
  处:http://blog.youkuaiyun.com/blankman/archive/2004/11/14/WE_MS_20041113.aspx


(微软2004-11-13的笔试题解析,如果有侵犯微软版权的话请来信告知,立即删除)


1、下面的程序运行时哪里会出现错误:

struct S

{

    int i;

    int * p;

};

 

int main()

{

    S s;

    int * p = &s.i;

    p[0] = 4;

    p[1] = 3;

    s.p = p;

    s.p[1] = 1;

    s.p[0] = 2;

 

    return 0;

}

【题目解析】

这道题考的是对结构体内存使用情况的理解。在32位的操作系统中,int和指针类型的变量占用空间都是4个字节。在本题中 &s.i的值实际就是 &s的值,所以“int * p = &s.i”也就相当于把p指向了结构体s的地址的起始位置。如图1所示。


1

假设 &s的值为0x12300,p的值也是0x12300p[0]指的是从0x12300开始的连续4个字节的空间,p[1]指的是从0x12304注意!不是0x12301)开始的连续4个字节的空间。这样,p[0]也就相当于s.ip[1]也就相当于s.p,分析到这一步,可以确定程序运行到“s.p=p;”这里不会出错。继续往下看。

在进行了“s.p=p;”的赋值之后,s.p指向的是s的首地址,此时s.p[0]相当于s.is.p[1]相当于s.p

下一句“s.p[1]= 1 执行过之后,此时s.p的值为1,也就是指向内存的0x00001处,隐患出现了。在执行“s.p[0]= 2 的时候,实际上是向内存0x00001起始的连续四个字节写入0x00000002,而那块内存不属于这个程序,会出现访问非法内存的错误。

VC解析的汇编代码如下(部分),有兴趣的可以参考一下。
;   14:       S s;
;   15:       int * p = &s.i;

00401028    lea         eax,[ebp-8]
0040102B    mov         dword ptr [ebp-0Ch],eax
;   16:       p[0] = 4;
0040102E    mov         ecx,dword ptr [ebp-0Ch]
00401031    mov         dword ptr [ecx],4
;   17:       p[1] = 3;
00401037    mov         edx,dword ptr [ebp-0Ch]
0040103A    mov         dword ptr [edx+4],3
;   18:       s.p = p;
00401041    mov         eax,dword ptr [ebp-0Ch]
00401044    mov         dword ptr [ebp-4],eax
;   19:       s.p[1] = 1;
00401047    mov         ecx,dword ptr [ebp-4]
0040104A    mov         dword ptr [ecx+4],1
;   20:       s.p[0] = 2;
00401051    mov         edx,dword ptr [ebp-4]
00401054    mov         dword ptr [edx],2


2、ABCDEF各是一个0~9的数字,根据下面的条件确定A~F的值
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD

【题目解析】
以下答案由winion提供
ABCDEF各是一个0~9的数字,根据下面的条件确定A~F的值
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD
一看到题目,我立即就想到了1/7,它正好满足这个数字的性质。所以答案是142857.
......
1/7=0.142857
2/7=0.285714
3/7=0.428571
4/7=0.571428
5/7=0.714285
6/7=0.857142
然后是循环,注意到没有,都是142857这六个数字。
以下答案由大辉提供
ABCDEF*2 = CDEFAB
CDEFAB*2 = EFABCD

2*AB = CD
2*EF = 1AB
2*CD+1 = EF

8AB+2 = 100+AB

AB = 14
以下答案dawangzi16
提供
1. E>2C>4A;==>a=1or2;

2. 因为EF*2=AB ,结合式子1得:(if A=2 then E=8 or 9 此时不成立) 所以 A=1; E=5;
同时得出F大于5; 此时:1BCD5F*2=CD5F1B;CD5F1B*2=5F1BCD;

3。因为1B*2=CD 所以推出:c=3或2; 又由CD*2=5F; 推出C=2 ; D>5;
此时:1B2D5F*2=2D5F1B;2D5F1B*2=5F1B2D;

4。因为1B*2 = 2D 而且D>5,推出B<5 ;当 B=3时 D=6;B=4时D=8;
又因为5F*2=1B 所以 B为偶数。 从而 B=4 ,D=8;
此时 14285F*2=285F14;285F14*2=5F1428;

5。不难看出 F=7;
从而得解

以下答案由 xiahui 提供
令AB=x, CDEF=y;
则(10000x+y)*2 = 100y+x;
19999x = 98y
2857*7x = 7*14y

故得AB=14,CDEF=2857
 
(以上答案均为热心朋友提供,除winion外没有提供个人主页链接,故文章中只有其链接)

(补充中......)

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值