Много алгоритмов выражаются более легко, если можно перейти через два цикла (или цикл, содержащий оператор переключения). Не плохо себя чувствуйте об этом. С другой стороны, это может указать на чрезмерно сложное решение. Поэтому отступите и посмотрите на проблему.
Некоторые люди предпочитают "однократный въезд, единственный выход" подход ко всем циклам. То есть предотвращение повреждения (и продолжаются) и рано возвращается для циклов в целом. Это может привести к некоторому дублирующему коду.
то, Что я сильно постарался бы не делать, представляет auxilary переменные. Сокрытие потока управления в состоянии добавляет к беспорядку.
маркированные циклы Разделения в два метода могут быть трудными. Исключения, вероятно, слишком тяжелы. Попробуйте однократный въезд, единственный подход выхода.
Вы могли записать свой собственный макрос, который обеспечивает то же использование _Static_assert(expr, msg)
:
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
/*
* void assert_msg(bool expr, const char *msg);
*/
#if !defined(NDEBUG)
#define assert_msg(expr, msg) do \
{ \
const bool e_ = expr; \
\
if (!e_) { \
fputs(msg, stderr); \
fputc('\n', stderr); \
assert(e_); \
} \
} while (0)
#else
#define assert_msg(expr, msg) do \
{ \
\
if (!(expr)) \
warn_bug(msg); \
} while (0)
#endif
у меня также есть макрос warn_bug()
, который печатает название программы, файл, строка, функция, значение errno и строка, и пользовательское сообщение, даже если утверждает, отключен. Причина позади него состоит в том, что это не повредит программу, но это предупредит, что ошибка будет, вероятно, присутствовать. Вы могли просто определить assert_msg
, чтобы быть пустыми если defined(NDEBUG)
, все же.
По традиции, (void)
связывается с компилятором, что Вы сознательно игнорируете выражение:
/* picard.c, TNG S6E11. */
#define assertmsg(x, msg) assert(((void) msg, x))
assertmsg(2+2==5, "There! are! four! lights!");