Каков результат работы этой программы и что она возвращает в операционную систему?

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

  •  07-07-2019
  •  | 
  •  

Вопрос

Это что-то вроде головоломки на букву "С".Вы должны сообщить, завершила ли программа свое выполнение, если да, то сколько времени требуется для запуска и что она возвращает операционной системе.

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

[РЕДАКТИРОВАТЬ] Я удалил тег interview-questions, поскольку, похоже, это основное, против чего люди возражают.Это отличная маленькая головоломка, но, как все уже отметили, не лучший вопрос для интервью.

Это было полезно?

Решение

Несмотря на то, что это ужасный вопрос для интервью, на самом деле он довольно интересный:

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 (при условии, что 8-битные байты) и 256 цифрами, программа завершит работу, когда весь счетчик "перевернется".

Причина, по которой это интересно, заключается в том, что код на самом деле является полностью легальным 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 ++, и меня это не волнует настолько, чтобы искать его

если это действительно вопрос для собеседования, мой ответ таков: "если вы ожидаете, что я буду работать с таким кодом, то мне не нужна эта работа".

Редактировать:спасибо Роберту Гэмблу за напоминание мне, что статические массивы автоматически инициализируются нулем, так что код не является полным мусором - но я все равно не хотел бы поддерживать его или работать с психом, который его написал ;-)

Правильный ответ на этот вопрос таков:

Этот код не поддерживается, не поддается проверке, не служит никакой цели и должен быть удален или переписан заново.

Все остальное означает, что интервьюируемый мыслит не как инженер-программист.

Опять же, возможно, вы не проходите собеседование на должность инженера.

unsigned char *p, *q;

Разве это не плохо на многих уровнях?Прежде всего, существует ли такая вещь, как неподписанный символ char?Во-вторых, и здесь я могу ошибаться, так что не цитируйте меня, но не выделяет * p, вопрос: дают обалденные результаты?Либо это так, либо это упрощает выполнение char p, q, что было бы дурным тоном.

Следующее намного лучше:

char* p;
char* q;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top