Я почти уверен, что самый быстрый и ясный способ сделать это - использовать явный тест:
int has_zero = !a || !b || !c || !d || !e ...;
Поскольку ||
и &&
- это операторы замыкания в C, оценка прекращается, как только становится известен окончательный результат, поэтому, если (например) переменная b
равна нулю, это удовлетворяет выражению как истинное и перестает оценивать остальные.
@ AbhayAravinda предположил, что !(a && b && c && d ...)
может быть более эффективным, но я так не думаю; поскольку это не столько явное выполнение операции not, сколько низкоуровневый тест против нуля, это действительно простой тест для надежного выполнения практически любой архитектуры. Я быстро взглянул на оптимизированный ассемблер для обеих версий, и не было явного победителя по производительности, но я думаю, что первая версия более ясна.
Если каждый цикл имеет значение, проверьте обе версии на своей платформе, но в моей 64-битной системе Intel и g cc, и clang фактически генерируют одну и ту же сборку для обеих версий (с включенной оптимизацией).
Простой тестовый код:
int a, b, c, d, e, f;
int test_or()
{
return !a || !b || !c || !d || !e || !f;
}
int test_and()
{
return ! (a && b && c && d && e && f);
}
int main()
{
return test_or() | test_and();
}
Скомпилируйте это с помощью gcc -S -O testfile.c
и посмотрите на получившийся файл .s
.