Quel est le résultat de ce programme et que retourne-t-il au système d'exploitation?

StackOverflow https://stackoverflow.com/questions/279837

  •  07-07-2019
  •  | 
  •  

Question

C'est une sorte de casse-tête en C. Vous devez savoir si le programme termine son exécution, le cas échéant, combien de temps il faut pour exécuter et ce qu’il retourne au système d’exploitation.

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] J'ai supprimé la balise interview-questions car cela semble être la principale chose à laquelle les gens s'opposent. C’est un bon petit casse-tête mais, comme tout le monde l’a déjà souligné, ce n’est pas une bonne question d’entrevue.

Était-ce utile?

La solution

Malgré le fait qu’il s’agisse d’une question d’entrevue horrible, c’est en fait assez intéressant:

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

Il s’agit essentiellement d’un compteur base-256 (en supposant des octets de 8 bits) avec 256 chiffres, le programme se ferme lorsque tout le compteur "bascule".

La raison en est que c’est parce que le code est en fait complètement légal C (aucun comportement indéfini ou défini par la mise en œuvre que vous trouvez habituellement dans ces types de questions) et qu’il existe en réalité un problème légitime d’algorithme, bien que légèrement caché, dans mélanger. La raison pour laquelle il s'agit d'une question d'entretien horrible est que je ne m'attendrais pas à ce que quelqu'un se souvienne de la priorité et de l'associativité des opérateurs impliqués dans la déclaration while. Mais cela en fait un petit exercice amusant et perspicace.

Autres conseils

ce code est un déchet, voir les commentaires

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
}

il pourrait se terminer, il ne pourrait pas; la boucle while analyse essentiellement un tampon non initialisé afin de générer une violation d'accès à la place; Je ne me souviens pas de la priorité de liaison de ++ * p ++, je ne me soucie pas assez de le rechercher

s’il s’agit vraiment d’une question d’entrevue, ma réponse est "si c’est le genre de code avec lequel vous attendez de moi que je travaille, je ne veux pas du travail"

EDIT: merci à Robert Gamble de m'avoir rappelé que les tableaux statiques sont automatiquement initialisés à zéro, le code n'est donc pas complet - mais je ne voudrais toujours pas le maintenir ni travailler avec le nutjob qui l'a écrit; -)

La bonne réponse à cette question est:

  

Ce code est non maintenable, non vérifiable, ne sert à rien et doit être supprimé ou réécrit.

N'importe quoi d'autre signifie que l'interviewé ne pense pas en tant qu'ingénieur en logiciel.

Encore une fois, vous n’êtes peut-être pas en train d’interviewer pour un poste d’ingénieur.

unsigned char *p, *q;

Cela n’at-il pas été porté à plusieurs niveaux? Tout d’abord, existe-t-il un personnage non signé? Deuxièmement, et je me trompe peut-être ici, alors ne me citez pas, mais char * p, q ne donne-t-il pas des résultats géniaux? C’est ça, ou ça facilite la tâche char p, q, ce qui serait mauvais.

Ce qui suit est bien meilleur:

char* p;
char* q;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top