質問
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;
}
[編集] インタビューの質問タグは、人々が異議を唱えている主なものであるように思われるため、削除しました。これは素晴らしい小さなパズルですが、誰もがすでに指摘しているように、面接での素晴らしい質問ではありません。
解決
これはひどい面接の質問であるという事実にもかかわらず、実際には非常に興味深いものです。
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 ステートメントに含まれる演算子の優先順位と結合性を覚えている人がいるとは思えないからです。しかし、それは楽しくて洞察力に富んだ小さな演習にはなります。
他のヒント
このコードはゴミです。コメントを参照してください
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に感謝します。そのため、コードは完全なゴミではありません。 / p>
この質問に対する正しい答えは:
このコードは、維持できず、テストできず、目的を果たさないため、削除または書き換える必要があります。
その他は、インタビュー対象者がソフトウェアエンジニアとして考えていないことを意味します。
もう一度、エンジニアリングの地位について面接しているわけではありません。
unsigned char *p, *q;
これは多くのレベルで着用されていませんか?まず、unsigned charのようなものはありますか?第二に、私はここで間違っているかもしれないので、引用しないでくださいが、char * p、 qはファンキーな結果を生成しませんか?それか、char、p、qを簡単に実行できるかのいずれかです。これは悪い形式です。
次の方がはるかに優れています。
char* p;
char* q;