Я ожидаю, что смогу сделать что-то вроде этого:
int i = 0;
until (i == 2){
printf("yes\n");
i++;
}
Не говоря подробно о том, что делает until, я уверен, что читатель знает, что такое алгоритм из кода выше. Да, я знаю, что могу просто использовать while(!condition){}.
Вывод будет:
yes
yes
Так возможно ли, что я могу достичь своей цели?
Я чувствую, что макрос может сделать это с помощью define или чего-то еще. Но мне не хватает знаний о синтаксисе директив предварительной обработки в C
#define until <what should I fill here>
Редактировать: То, что я делаю, вызвало у многих людей триггер. Извините, если я беспокою вас, ребята. Не волнуйтесь, этот синтаксис предназначен только для меня. Так что я надеюсь, что не побеспокою читателя кода, который случайно прочитал мой код или священника C.





Я не знаю, почему вы это сделали, until — ключевое слово, которое чаще всего забрасывают по какой-то причине. Но это должно работать:
#define until(cond) while (!(cond))
В своем ответе вы написали: "until is a mostly abandoned keyword" -- На мой взгляд, эта формулировка вводит в заблуждение. Токен until не является ключевым словом в C.
@AndreasWenzel Я имел в виду языки программирования в целом.
Вы можете отредактировать свой ответ, чтобы прояснить это.
Да, вы можете использовать define для этого. См. следующий пример для определения макроса
#include <stdio.h>
#define until(x) while(!(x))
int main() {
int i = 0;
until (i == 2){
printf("iteration %d\n", i);
i++;
}
return 0;
}
Если вы запустите его, вывод будет
iteration 0
iteration 1
Прежде всего, и я не могу не подчеркнуть этого: создание собственного секретного, частного языка с использованием макросов, подобных функциям, является смертным грехом в C. Возможно, это худшее, что вы можете сделать.
Почему? Потому что ожидается, что другие люди, читающие ваш код, знают C. Однако они не должны знать ваш секретный частный язык макросов. Кроме того, они совершенно не заинтересованы в изучении вашего секретного частного макроязыка.
Поэтому, пожалуйста, никогда не делайте подобных вещей в реальных программах.
При этом вы уже почти сами ответили на вопрос:
#define until(condition) while(!(condition))
Обратите внимание, что condition, будучи параметром макроса, похожим на функцию, должен быть помещен в круглые скобки. Это предотвращает случайные ошибки приоритета операторов. Например, если вызывающий абонент передает until(i + 1), вы хотите, чтобы он зациклился while(!(i+1)), а не while(!i + 1).
Я предлагаю использовать __VA_ARG__ на случай, если кто-то решит поставить в условиях запятую ,. Это случается время от времени. #define until(...) while(!(__VA_ARGS__))
@Lundin, BITD, я имел дело с большой базой кода, которая использовала #define begin { int i; и использовала while (cond) begin ... f(i); ... } -> непревзойденные {}, загадочные i и не могла автоматически форматировать. Фу.
@tstanisl Если это так, им лучше с ошибкой компилятора, чем молчаливым принятием.
@chux-ReinstateMonica Похоже, какой-то сварливый программист на Паскале в какой-то момент отвечал за кодовую базу :)
Я легко могу представить, как кто-то пишет until(c = getchar(), c == EOF) { ... }.
@tstanisl C известен своим интенсивным использованием кармы. Если вы будете писать такой код на C, вселенная найдет способы наказать вас за это.
Из экспертного программирования C:
Использование макросов лучше всего ограничивается именованием литеральных констант, сокращение для нескольких хорошо выбранных конструкций. Определите имя макроса all заглавными буквами, чтобы при использовании сразу было понятно, что это не функция вызов. Избегайте любого использования препроцессора C, который изменяет базовый язык, чтобы он больше не был C.
Re: «Я уверен, что читатель знает, что такое алгоритм из приведенного выше кода».
Нет, это еще больше запутает, поскольку ключевое слово until не является частью языка C. Чтобы ввести несколько дополнительных символов, не требуется много времени.
При этом вы можете сделать:
#define until(condition) while(!(condition))
Скомпилируйте свою программу с помощью:
gcc -E -nostdinc main.c
чтобы увидеть, какие изменения сделал препроцессор.
Но это все равно было бы мерзостью, а не чем-то, что можно было бы оправдать.
Использование until полезно в некоторых случаях.
Иногда в определении алгоритма или программного контракта используется значение «до тех пор», поэтому хорошо видеть это совпадение в коде.
Тем не менее, переписывание семантики языка добавляет путаницы и затрат на обслуживание.
Учитывайте комментарий, когда не требуется.
int i = 0;
// until (i == 2) {
while (i != 2) {
printf("yes\n");
i++;
}
Почему вы хотите сделать что-то подобное? ИМХО, это только запутает людей, которые читают ваш код.