这是一种C拼图。您必须判断程序是否完成执行,如果是,运行所需的时间以及返回操作系统的内容。
static unsigned char buffer[256];
int main(void)
{
unsigned char *p, *q;
q = (p = buffer) + sizeof(buffer);
while (q - p)
{
p = buffer;
while (!++*p++);
}
return p - q;
}
[编辑] 我删除了面试问题标签,因为这似乎是人们反对的主要内容。这是一个很棒的小谜题,但正如大家已经指出的那样,这不是一个很好的面试问题。
答案 0 :(得分:13)
尽管这是一个可怕的采访问题,但实际上非常有趣:
static unsigned char buffer[256];
int main(void)
{
unsigned char *p, *q;
q = (p = buffer) + sizeof(buffer);
/* This statement will set p to point to the beginning of buffer and will
set q to point to one past the last element of buffer (this is legal) */
while (q - p)
/* q - p will start out being 256 and will decrease at an inversely
exponential rate: */
{
p = buffer;
while (!++*p++);
/* This is where the interesting part comes in; the prefix increment,
dereference, and logical negation operators all have the same
precedence and are evaluated **right-to-left**. The postfix
operator has a higher precedence. *p starts out at zero, is
incremented to 1 by the prefix, and is negated by !.
p is incremented by the postfix operator, the condition
evaluates to false and the loop terminates with buffer[0] = 1.
p is then set to point to buffer[0] again and the loop continues
until buffer[0] = 255. This time, the loop succeeds when *p is
incremented, becomes 0 and is negated. This causes the loop to
run again immediately after p is incremented to point to buffer[1],
which is increased to 1. The value 1 is of course negated,
p is incremented which doesn't matter because the loop terminates
and p is reset to point to buffer[0] again.
This process will continue to increment buffer[0] every time,
increasing buffer[1] every 256 runs. After 256*255 runs,
buffer[0] and buffer[1] will both be 255, the loop will succeed
*twice* and buffer[2] will be incremented once, etc.
The loop will terminate after about 256^256 runs when all the values
in the buffer array are 255 allowing p to be incremented to the end
of the array. This will happen sometime after the universe ends,
maybe a little sooner on the new Intels ;)
*/
}
return p - q;
/* Returns 0 as p == q now */
}
本质上这是256位(假设8位字节)计数器,256位数,当整个计数器“翻转”时,程序将退出。
这很有趣的原因是因为代码实际上是完全合法的C(在这些类型的问题中通常没有找到未定义的或实现定义的行为)并且实际上存在合法的算法问题,尽管有点隐藏在混合。这是一个可怕的面试问题的原因是因为我不希望任何人记住while语句中涉及的运算符的优先级和关联性。但它确实可以带来有趣且富有洞察力的小练习。
答案 1 :(得分:12)
此代码是垃圾,请参阅注释
static unsigned char buffer[256];
int main(void)
{
unsigned char *p, *q;
q = (p = buffer) + sizeof(buffer); //p=buffer, q=buffer+256
while (q - p) //q-p = 256 on first iteration
{
p = buffer; //p=buffer again
while (!++*p++); //increment the value pointed at by p+1 and check for !0
}
return p - q; //will return zero if loop ever terminates
}
可能会终止,也可能不会; while循环实质上是扫描未初始化的缓冲区,因此它可能会抛出访问冲突;我不记得++ * p ++的绑定优先级,我也不在乎查找它
如果这真的是一个面试问题,我的回答是“如果这是你希望我合作的那种代码,我不想要这份工作”
编辑:感谢Robert Gamble提醒我静态数组自动初始化为零,因此代码不是完全垃圾 - 但我仍然不想维护它或使用编写它的nutjob; - )< / p>答案 2 :(得分:4)
这个问题的正确答案是:
此代码不可维护,不可测试,无用,应删除或重写。
其他任何事情都意味着受访者不会将其视为软件工程师。
再一次,你可能不会接受工程职位的面试。
答案 3 :(得分:-5)
unsigned char *p, *q;
这个问题在很多层面都不是吗?首先,是否存在无符号字符?第二,我可能在这里错了,所以不要引用我,但不是char * p, q产生时髦的结果?就是这样,或者它很容易做char p,q,这将是不好的形式。
以下情况要好得多:
char* p;
char* q;