C 这个程序的输出是什么?它返回到操作系统的是什么?

C 这个程序的输出是什么?它返回到操作系统的是什么?,c,puzzle,C,Puzzle,这是一个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 -

这是一个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;
}
[编辑]
我删除了面试问题标签,因为这似乎是人们反对的首要问题。这是一个很好的小谜题,但正如大家已经指出的,这不是一个很好的面试问题。

这段代码是垃圾,请参阅注释

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;-)

尽管这是一个可怕的面试问题,但它实际上非常有趣:

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语句中涉及的操作符的优先级和关联性。但这确实是一个有趣且富有洞察力的小练习。

这个问题的正确答案是:

此代码不可维护、不稳定,没有任何用途,应删除或重写

其他任何事情都意味着受访者不是以软件工程师的身份思考的

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

unsigned char *p, *q;
这不是很多层面的工作吗?首先,有没有无符号字符?第二,这里我可能错了,所以请不要引用我的话,但是char*p,q不会产生令人讨厌的结果吗?要么就是这样,要么就是它使做字符p,q变得容易,这将是一种糟糕的形式

以下几点更好:

char* p;
char* q;

可怕的面试问题,它的级别太低,除了它不是任何人都想在生产代码中看到的东西之外,它还很模糊。虽然我同意这是一个可怕的面试问题,但对于那些喜欢这类问题的人来说,这是一个很好的小难题,它有一个值得欣赏的简单性,直到你完成它。如果你不想浪费脑细胞去看,请看我的答案;)我不认为有人说这是一个面试问题,除非它被称为面试问题,然后被编辑下来。@dnord,OP使用了面试问题标签,这是每个人都跳出来的,我去掉了这个标签。+1为了慢慢来,我仍然认为这是一个可怕的问题:)*p正在访问未初始化的内存,不管你怎么切it@Steven,再看一次,数组是静态的,这意味着所有元素都初始化为零。我站着(好,坐着)纠正了。但请注意,只有当C编译器是ANSI标准时,这才是正确的(参见K&R第二版,约1988年);我在1985年学习了C(K&R第一版),所以我不知道这些琐事,谢谢!事实上,根据我1978年的K&R 1副本,情况一直如此,参见第37页:“外部和静态变量默认初始化为零,但无论如何声明初始化是一种好的方式。”第82页和第198页再次提到了这一点。您的格式不好(用*s转义),无符号字符*p,*q;很好,在这种情况下char*不起作用,因为可以对char进行签名,这将导致溢出时出现未定义的行为。字符只能用于字符,有符号/无符号字符用于数字。您还可以赢取您的同伴压力徽章并删除此徽章。我已查找了+++*p++:++(*(p++))的优先级。所以它实际上增加了p所指向的值,而不是p+1。然后在那之后,它增加p。不用担心,我也没有记住优先规则:)