2016-12-11 4 views
4

Один из моих преподавателей в университете предлагает использовать макросы для уменьшения повторения в коде c99, как это.для стиля кодирования макросов петли

#define foreach(a, b, c) for (int a = b; a < c; a++) 
#define for_i foreach(i, 0, n) 
#define for_j foreach(j, 0, n) 
#define for_ij for_i for_j 

который может быть использован, как это:

for_ij { /*do stuff*/; } 
for_i { /*do stuff*/; } 

Другой преподаватель с промышленным фоном отбивает его использование, утверждая, что это было расценено как анти-паттерна у своего бывшего работодателя (но он не знает, причина этого). Фактически, используя grepping через исходный код больших проектов, редко можно найти эти конструкции за пределами коротких академических примеров.

Мой вопрос: почему эта конструкция так редко используется на практике? Это опасно в какой-то степени?

+1

Вы фактически создаете свой собственный диалект, используя препроцессор. Доиг так всегда чреват опасностью и препятствует пониманию кого-либо еще (или самого себя позже). В любом случае, это вопрос больше для [programers.se], а не SO. – Deduplicator

+1

Как аналог, представьте себе книгу, в которой в предисловии говорилось, что «SR» заменит «Роберт» и «TND» заменит «На следующий день». Вы могли бы это прочитать, но было бы странно сказать наименьшее. –

+0

Когда я учился C (время назад), я был умнее вашего первого преподавателя и делал '#define forloop for (int i = 0; i rodrigo

ответ

5

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

Чтобы ответить на ваш вопрос: НЕТ этот вид строительства является не используется на практике, и это рискованно, как она скрывает информацию, используя скрытые переменные и условия.

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

  • что верхняя граница? Это не так очевидно, это должно быть n.
  • Каков фактический диапазон для i?
  • это 0 на основе?
  • Включает ли он n или останавливается раньше?

Программисты очень хороши при чтении идиоматических конструкций, таких как

for (int i = 0; i < n; i++) { 
    ... 
} 

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

Возможно, вам стоит проявить осторожность с преподавателем университета, который хочет использовать эти сокращения, возможно, ностальгический APL и избегать конфликтов. Вы можете играть в некоторых code golfing с ним, есть stack exchange dedicated to that и он будет любить, как люди тратят огромное количество времени бритья байт из их исходных кодов ...

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

3

Проблема в том, что сокращение повторения (и, следовательно, улучшение удобочитаемости) довольно тривиально. Вы уменьшаете

for (int i = 0; i < n; i++) 
    for (int j = 0; j < n; j++) 

в

for_ij 

, который не так много улучшений, как имена переменных i, j и n все короткие так повторять их не проблема.

В то же время, вы прячетесь параметр n - последний цикл неявно зависит от n, даже если n не появляется нигде в for_ij или (скорее всего) в теле для цикла либо. Скрытие важной информации делает код чтения более сложным - для того, чтобы прочитать это, вам нужно знать критическую важность n, которую вы можете увидеть только путем поиска по двум уровням макронапряжения.

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