2

Cパズルのようなものです。プログラムが実行を終了したかどうか、終了した場合は実行にどれくらいの時間がかかり、OS に何を返すかを知る必要があります。

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

[編集] インタビューの質問のタグを削除しました。これは人々が反対しているように思われるためです。これはすばらしい小さなパズルですが、誰もがすでに指摘しているように、インタビューの質問としては適切ではありません。

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;

これは多くのレベルで摩耗していませんか?まず、unsignedcharのようなものはありますか?第二に、私はここで間違っているかもしれないので、私を引用しないでください、しかしchar * p、qはファンキーな結果を生み出しませんか?それか、char p、qを実行するのが簡単になりますが、これは悪い形式になります。

以下ははるかに優れています:

char* p;
char* q;
于 2008-11-11T04:44:00.227 に答える