Frage

Es ist so eine Art C-Puzzle. Sie haben zu sagen, ob das Programm seine Ausführung beenden, wenn ja, wie viel Zeit es braucht, zu laufen und was es kehrt in die 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;
}

[EDIT] Ich entfernte das Interview-Fragen-Tag da, dass die primäre Sache, die Menschen zu wehren sich gegen zu sein scheint. Dies ist ein großartiges kleines Puzzle, aber wie jeder hat bereits darauf hingewiesen, kein großes Interview Frage.

War es hilfreich?

Lösung

Trotz der Tatsache, dass dies eine schreckliche Interview-Frage, es ist eigentlich ganz interessant:

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 */
}

Im Wesentlichen ist dies eine Basis-256 (unter der Annahme, 8-Bit-Bytes) Zähler mit 256 Ziffern, wird das Programm beendet, wenn der gesamte Zähler „rollt“.

Der Grund dafür ist interessant, weil der Code tatsächlich völlig legal C (kein undefiniertes oder Implementierung definiert Verhalten, das Sie in der Regel in dieser Art von Fragen finden) ist, und es ist tatsächlich ein legitimes Algorithmus Problem, wenn auch ein wenig versteckt, in dem mischen. Der Grund, es ist eine schreckliche Interview-Frage, weil ich nicht, dass jemand den Vorrang und Assoziativität der Operatoren in der while-Anweisung beteiligt zu erinnern, erwarten würde. Aber es macht für einen Spaß und interessante kleine Übung.

Andere Tipps

Dieser Code ist Müll, siehe Kommentare

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
}

könnte es beenden, könnte es nicht; die while-Schleife abtastet wesentlichen einen nicht initialisierten Puffer, so dass es eine Zugriffsverletzung werfen könnte statt; Ich erinnere mich nicht die Bindung Vorrang ++ * p ++, noch habe ich genug interessieren, um es nachzuschlagen

, ob dies wirklich ein Interview Frage ist, ist meine Antwort „wenn dies die Art von Code ist, dass Sie erwarten, dass ich mit arbeiten, ich will nicht den Job“

EDIT: Dank Robert Gamble für mich daran erinnern, dass statische Arrays automatisch auf Null initialisiert werden, so dass der Code ist nicht vollständig Müll - aber ich möchte noch nicht halten oder mit dem nutjob arbeiten, die es geschrieben hat; -)

Die richtige Antwort auf diese Frage lautet:

  

Dieser Code ist wartbaren, untestable, dient keinem Zweck und sollte entfernt oder neu geschrieben werden.

Alles, was bedeutet, dass sonst der Interviewte nicht als Software-Ingenieur denkt.

Dann wieder, könnte man nicht für technische Position werden interviewen.

unsigned char *p, *q;

Ist das nicht worng auf vielen Ebenen? Zunächst einmal ist es so etwas wie ein unsigned char? Zweitens, und ich hier falsch sein kann, so zitieren Sie mich nicht, aber char nicht * p q produzieren flippige Ergebnisse? Es ist entweder das, oder es macht es einfach char p, q zu tun, die schlechte Form sein würde.

Hier finden Sie viel besser:

char* p;
char* q;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top