2

这是一个 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;
}

[编辑] 我删除了 interview-questions 标签,因为这似乎是人们反对的主要内容。这是一个很好的小难题,但正如每个人都已经指出的那样,这不是一个很好的面试问题。

4

4 回答 4

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 位的 base-256(假设为 8 位字节)计数器,当整个计数器“翻转”时,程序将退出。

这很有趣的原因是因为代码实际上是完全合法的 C(没有您通常在这些类型的问题中发现的未定义或实现定义的行为)并且实际上存在合法的算法问题,尽管有点隐藏,在混合中。这是一个可怕的面试问题的原因是因为我不希望任何人记住 while 语句中涉及的运算符的优先级和关联性。但它确实是一个有趣和有见地的小练习。

于 2008-11-11T03:50:16.433 回答
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 ;-)

于 2008-11-11T02:41:32.127 回答
4

这个问题的正确答案是:

此代码不可维护、不可测试、无用,应删除或重​​写。

其他任何事情都意味着受访者没有像软件工程师一样思考。

再说一次,你可能不是在面试工程职位。

于 2008-11-11T03:50:41.270 回答
-6
unsigned char *p, *q;

这不是在很多层面上都磨损了吗?首先,有没有 unsigned char 这样的东西?其次,我在这里可能错了,所以不要引用我的话,但是 char *p, q 不会产生时髦的结果吗?要么就是这样,要么它可以很容易地做 char p, q,这将是不好的形式。

以下要好得多:

char* p;
char* q;
于 2008-11-11T04:44:00.227 回答