Определить пользовательский синтаксис «до» в C

Я ожидаю, что смогу сделать что-то вроде этого:

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.

Почему вы хотите сделать что-то подобное? ИМХО, это только запутает людей, которые читают ваш код.

wohlstad 05.01.2023 13:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
185
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я не знаю, почему вы это сделали, until — ключевое слово, которое чаще всего забрасывают по какой-то причине. Но это должно работать:

#define until(cond) while (!(cond))

В своем ответе вы написали: "until is a mostly abandoned keyword" -- На мой взгляд, эта формулировка вводит в заблуждение. Токен until не является ключевым словом в C.

Andreas Wenzel 05.01.2023 14:58

@AndreasWenzel Я имел в виду языки программирования в целом.

Verpous 05.01.2023 16:07

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

Andreas Wenzel 05.01.2023 16:08
Ответ принят как подходящий

Да, вы можете использовать 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__))

tstanisl 05.01.2023 13:53

@Lundin, BITD, я имел дело с большой базой кода, которая использовала #define begin { int i; и использовала while (cond) begin ... f(i); ... } -> непревзойденные {}, загадочные i и не могла автоматически форматировать. Фу.

chux - Reinstate Monica 05.01.2023 14:26

@tstanisl Если это так, им лучше с ошибкой компилятора, чем молчаливым принятием.

Lundin 05.01.2023 14:35

@chux-ReinstateMonica Похоже, какой-то сварливый программист на Паскале в какой-то момент отвечал за кодовую базу :)

Lundin 05.01.2023 14:36

Я легко могу представить, как кто-то пишет until(c = getchar(), c == EOF) { ... }.

tstanisl 05.01.2023 14:54

@tstanisl C известен своим интенсивным использованием кармы. Если вы будете писать такой код на C, вселенная найдет способы наказать вас за это.

Lundin 05.01.2023 15:00

Из экспертного программирования 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++;
}

Другие вопросы по теме