最近看了不少关于求职面试的试题,在其中发现了不少有意思的题目。特整理后发表上来与大家一起分享。
为了方便与以后添加的题目区别,每次更新会以A、B……的方式标注。
A-1:如何将a、b的值进行交换,并且不使用任何中间变量?
解析:一般可以选择两种方式:
(1)使用加法运算:a = a+b; b = a-b; a = a-b;
(2)使用异或运算:a = a^b; b = a^b; a = a^b;
其中,如果a、b的值比较大,那么选择第一种方式可能会导致越界,因此,最佳答案是异或方式。
A-2:main主函数执行完毕后,是否可能会再执行一段代码?
解析:回答是肯定的。可以使用atexit()函数注册一个函数,使得主函数在退出前先执行该注册地函数。
A-3:写出下面程序的运行结果
#include <stdlib.h>
#include <time.h>
#define LOOP 1000
int main()
{
int count = 0,i;
int x,y;
srand(time(0));
for(i=0;i<LOOP;i++){
x = rand();
y = rand();
if(x*x+y*y < RAND_MAX*RAND_MAX)
count++;
}
printf("%d\n", count);
return 0;
}
解析:据说这是一个很好的概率题。该题中暗含了一个1/4圆和一个正方形比较大小的问题。其中,RAND_MAX是随机数中的最大值,也就是相当于最大半径R;而x、y值则相当于横纵轴的坐标值,它们的平方和开根号就是原点到该点(x, y)的距离,当然这个距离可能大于R也有可能小于R。
通过上面的分析,该问题则可以蜕化为:随机在正方形里落LOOP个点,落在半径里面的点有多少个。鉴于1/4圆面积是(1/4)*π*R*R,正方形面积是R*R,两者之比为(1/4)*π,所以落点数为LOOP*(1/4)*π个。鉴于题意中LOOP为1000,则可计算出大约为785个点。
然而,我
在Linux ubuntu 2.6.24-22-generic运行该程序得到的结果却是500左右,Why?
A-4:写出下列程序的执行结果:
#include <stdio.h>
int main()
{
printf("%f\n", 5);
printf("%d\n", 5.01);
return 0;
}
解析:首先5为int型,在32平台上会由编译器分配4个字节;当以%f方式输出时,编译器将从该值所在地址上读出8个字节。很显然地,内存访问越界,因此输出结果不确定。同理以%d方式显示浮点数5.01时,结果也将不确定。从实际测试来说,第一个答案往往是0.000000;第二个很可能是大数。
A-5:写出下面程序的执行结果:
#include <iostream>
using namespace std;
union {
unsigned char a;
unsigned int i;
} u;
int main(void)
{
u.i = 0xf0f1f2f3;
cout<<hex<<u.i<<endl;
cout<<hex<<int(u.a)<<endl;
return 0;
}
解析:该程序主要考察内存中数据如何存储。在冯·诺依曼体系中,在内存中数据的低位字节存储在低地址上;而数据的地址则采用它的低地址来表示,具体情况如下所示:
因此该结果将是:f0f1f2f3,f3。
B-1:写出下面程序的执行结果:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "123456789";
char d[] = "123";
strcpy(d,s);
printf("%s, %s\n", d, s);
return 0;
}
解析:这是一个典型的溢出问题。首先数组s被分配了10个字符(包含字符串串尾的空字符),而数组d只被分配了4个字符;所以当使用strcpy()函数进行字符串复制时,数组d会溢出。由于数组s和d都是自动变量,它们存在于stack中,而数组s先被分配在高地址上,而数组d则被分配在后续的低地址上,当数组d越界时,则会造成数组s中的数据被覆盖,原来的“123456789”则被覆盖为“56789\0789”,其中’\0’代表字符串尾的空字符。
因此,该输出应该是123456789,56789。
=====================================================
欢迎访问我的博客:
http://billstone.cublog.cn
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)