本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020
最近发现了几个公司招聘的笔试机试题,虽然是两年前的,但是题目还不错,所以做了做,下面给出自己对一些题的理解。
问题描述:
下面代码中for循环共执行了多少次?
unsigned short i,j;
for(i = 0,j = 2;i != j;i += 5, j+ = 7)()
问题分析:
首先,看到变量i和j都是无符号的整数,我们知道,无符号整数在内存中是以16位表示的,也就是两个字节,所以要想到i和j的所能取到的最大值。
接着,就是看for循环停止条件,可以看出,这里只有一个条件,即当i== j 时,才停止for循环。
最后,就是找出在什么情况下,i和j才能相等,列出等式,解出即可。
解决思路:
i,j为无符号短整型整数,用2个字节表示,即,i和j的取值范围为0-65535,且当i或j为最大值时,即等于65535,在内存中也就是16位全溢出,这时再加1,则在内存中最高位会溢出,取低16位,即这时变成了16位全0,也就是说当无符号整数达到最大值后,如果再加1,则会变成0.
明白了这一点,这个题就简单了,其实这个题就是考查无符号整数的范围及内存溢出的情况,从for循环中可以看出,停止循环的条件只有一个,那就是i == j,但是可以看出j要比i增加的快,也就说当j先增加到最大值后,然后又开始从0开始增加,才有可能和i相等。
当然了,这个从数学的角度考虑,不用考虑这么多,其实就是一个解一元一次方程的问题:
设循环的次数为c,要停止循环,则有以下等式成立
((2+7*c) - (0 + 5*c)) % pow(2,16) = 0
可以解出c = (pow(2,16) - 2) / 2 = 32767 或 c = -1(不合理,舍去),也就是说这个for循环共执行了32767次
最后,可以用程序验证一下,看结果是否正确,如下:
#include <stdio.h>
#include <math.h>
int main(){
unsigned short i = 0,j;
int count = 0;
for(i = 0 ,j = 2;i != j; i+=5,j+=7){
//printf("i = %d\t j = %d\n",i,j);
count++;
}
printf("for循环共执行了%d次\n",count);
}
执行结果:
for循环共执行了32767次
可以看出,上面的思路没错.