2013-05-06 3 views
12

Я купил эту книгу под названием «Написание твердого кода».О «NULL» в этом конкретном коде

В первой главе, есть этот код:

while(*pchTo++ = *pchFrom++) 
    NULL; 

Я действительно не понимаю, что это NULL делает в этом цикле.

+1

Отделяет точку с запятой от условия цикла. (Это мертвый код.) –

+21

И такая книга называется «Написание твердого кода»? – duDE

+11

Является ли такая практика желательной, открыта для обсуждения, но книга, которая использует такую ​​конструкцию, не посвящая хотя бы короткий абзац объяснению мотивации, кажется мне не такой хорошей книгой ... –

ответ

3

Этот цикл копирует строку. NULL находится здесь, чтобы обеспечить тело петли.

+2

Это просто так запутанно ... особенно для справочника. Он мог бы просто оставить тело пустым с двумя фигурными фигурными скобками: 'while (...) {}'. Или даже сделать реальную вещь: 'while (* pchFrom) {* pchTo ++ = * pchFrom ++; } '. Это более понятно. – Gui13

+1

@xgbi: Это не копирует нулевой ограничитель. – Joren

+0

Wooops, я позволю читателю исправить эту проблему ... – Gui13

6

Автор мог написать совершенно пустой пучок while так же, как вы можете написать цикл for без тела. Это выглядело бы как:

while (*pchTo++ = *pchFrom++); 

/* or */ 

while (*pchTo++ = *pchFrom++) 
    ; 

Оба из которых может показаться запутанным для некоторых людей, чтобы они добавили NULL, чтобы дать ему тело и сделать его менее запутанной.

Редактировать

Примечание вы можете сделать то же самое с цикл:

for (head = list->head; head->next; head = head->next); 
/* or */ 
for (head = list->head; head->next; head = head->next) 
    ; 
/* or */ 
for (head = list->head; head->next; head = head->next) 
    NULL; 

И все, что будет делать это обойти список, перейдя к следующему элементу, а следующий элемент не является NULL

+3

Я не вижу, как это «менее запутанно».Наличие выражения, значение которого не используется и которое не имеет побочных эффектов, кажется намного более запутанным. Мои доказательства? Тот факт, что ОП должен был задать этот вопрос. –

+0

Он менее запутан для людей, которые ожидают тело и никогда не видели петлю без одного, или, по крайней мере, я предполагаю, что именно здесь был помещен «NULL». Это действительно выглядит уродливо для меня, и когда у меня есть объект списка (например, выше), у которого нет члена 'tail', у меня обычно есть функция удобства, которая использует цикл for, который я продемонстрировал выше, только чтобы получить его. В редакционной заметке: люди, которые не включают член 'tail' в своей структуре, действительно должны пересмотреть свой дизайн. –

+0

Любой, кто (намеренно) помещает ';' в ту же строку, что и оператор 'for' или' while', заслуживает (по крайней мере) твердого удара по голове. [Ответ Кита] (http://stackoverflow.com/a/16401457/1711796) кратко затрагивает возможную путаницу. На стороне примечания другой вариант, который предпочитают многие, заключается в использовании фигурных скобок ('{}') в той или иной форме. – Dukeling

2

Эта конструкция обеспечивает хороший способ размещения точки останова при работе с отладчиком. Некоторые IDE не позволяли мне помещать точку останова на петлю, и у меня были петли с пустыми телами. Если у вас есть оператор в вашем теге цикла, проще разместить на нем точку останова, даже если это утверждение бесполезно.

В противном случае, как уже было сказано, он должен делать то же самое, что и тело с пустым телом.

3

Это, вероятно, навеяно синтаксисом нулевому заявления Ады:

while condition loop 
    null; 
end loop; 

Ад использует ключевое слово null как для нулевой константы указателя и для нулевого оператора (и несколько других вещей).

У этого есть некоторые преимущества по сравнению с оператором null, который является точкой с запятой. В частности, это гораздо более четко. Довольно распространенная ошибка в коде C, чтобы вставить случайное заявление нуль, добавив точку с запятой, особенно среди неопытных программистов C, которые еще не работали, где точка с запятой необходимы и где они не являются:

while (condition); 
{ 
    /* statements */ 
} 

Без точка с запятой, операторы управляются циклом while. При этом тело цикла while пустое, и цикл, вероятно, будет бесконечным, если условие не имеет побочных эффектов.

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

В C NULL - это макрос, который расширяется до константы нулевого указателя, определяемой реализацией.Автор использует его здесь:

while(*pchTo++ = *pchFrom++) 
    NULL; 

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

while(*pchTo++ = *pchFrom++) 
    ; 

Другой эквивалентной форме:

while(*pchTo++ = *pchFrom++) 
    42; 

На мой взгляд, это хорошо, но предназначена плохая идея. Это легко узнаваемо для тех немногих из нас, кто знаком с C и Ada, но большинство опытных программистов C будут смотреть на него и задаться вопросом, что там делает эта константа нулевого указателя.

Это не совсем так плохо, как определение набора макросов, чтобы сделать C выглядеть синтаксис другого языка:

#define IF if (
#define THEN) 
#define BEGIN { 
#define END } 
#define ELSE } else { 

, но это в том же духе.

Мой совет: Не делайте этого. Если вы хотите, чтобы ваш код C был легко понятен читателями, знающими C, напишите идиоматический код C; не изобретать умные трюки, чтобы сделать его похожим на что-то другое. Нулевые утверждения могут вводить в заблуждение, заставляя читателя задаться вопросом, случайно ли что-то было исключено. Лучшее решение, которое, IMHO, должно использовать комментарий:

while(*pchTo++ = *pchFrom++) { 
    /* empty body */ 
} 
+1

Я нахожу 'while (* pchTo ++ = * pchFrom ++) {}' одинаково ясно. Пустой блок, не содержащий даже места, чтобы что-то там помещать, сигнализирует «ничего не делать», намеренно. –

Смежные вопросы