Эффект использования запятой вместо точки с запятой в C и c++
Я заметил в ряде случаев при рефакторинге различных частей кода C и C++, что для разделения операторов используется запятая, а не точка с запятой. Что-то вроде этого;
int a = 0, b = 0;
a = 5, b = 5;
где бы я ожидал
int a = 0, b = 0;
a = 5; b = 5;
Я знаю, что C и C++ позволяют использовать запятые для разделения операторов (особенно заголовков циклов), но в чем разница между этими двумя частями кода? Я предполагаю, что запятая была оставлена в результате разреза & вставка, но это ошибка и влияет ли она на выполнение?
5 ответов:
это не имеет значения в коде, который вы опубликовали. В общем случае запятая разделяет выражения так же, как точка с запятой, однако, если вы берете целое как выражение, то оператор запятой означает, что выражение вычисляется до последнего аргумента.
вот пример:
b = (3, 5);оценит 3, затем 5 и назначит последнее b. So
b = 5. Обратите внимание, что скобки здесь важны:b = 3, 5;оценить
b = 3, затем 5 и результат всего выражения равен 5, тем не менееb == 3.оператор запятой особенно полезен в циклах for, когда ваш код итератора не является простым
i++, но вам нужно сделать несколько команд. В этом случае точка с запятой не очень хорошо работает с синтаксисом for-loop.
запятая-это оператор, который возвращает значение, которое всегда является 2-м (правым) аргументом, а точка с запятой просто завершает операторы. Это позволяет оператору запятой использоваться внутри других операторов или объединять несколько операторов в один.
здесь вызывается функция f (x), а затем
x > yвычисляется для оператора if.if( y = f(x), x > y )пример, когда он используется только для того, чтобы избежать необходимости в блоке
if( ... ) x = 2, y = 3; if( ... ) { x = 2; y = 3; }
оператор "запятая" вычисляет операнды слева направо, и результатом является значение последнего операнда.
это в основном полезно в for-loops, если вы хотите сделать несколько действий в части "инкремент", например (реверсирование строки)
for (int lower = 0, upper = s.size() - 1; lower < upper; ++lower, --upper) std::swap(s[lower], s[upper]);другой пример, где это может быть опция (поиск всех вхождений в строку):
#include <string> #include <iostream> int main() { std::string s("abracadabra"); size_t search_position = 0; size_t position = 0; while (position = s.find('a', search_position), position != std::string::npos) { std::cout << position << '\n'; search_position = position + 1; } }в частности, логический и не может использоваться для этого условия, так как оба нуля и ненулевое значение может означать, что символ был найден в строке. С другой стороны, с запятой
position = s.find()вызывается каждый раз, когда условие вычисляется, но результат этой части условие просто игнорируется.естественно есть и другие способы писать петлю:
while ((position = s.find('a', search_position)) != std::string::npos)или просто
while (true) { position = s.find('a', search_position); if (position == std::string::npos) break; ... }
одно использование будет в гольф код:
if (x == 1) y = 2, z = 3; if (x == 1) { y = 2; z = 3; }первая строка короче, но это выглядит слишком запутанным для использования в регулярной разработке.
Как Фрэнк упомянул, как оператор запятая используется в вашем примере не вызывает ошибку. Оператор запятой может сбивать с толку по нескольким причинам:
- это не слишком часто видел, потому что это необходимо только в некоторых особых ситуациях
- есть несколько других синтаксических применений запятой, которые могут выглядеть как оператор запятой - но это не так (запятые, используемые для разделения параметров/аргументов функции, запятые, используемые для разделения переменной объявления или инициализаторы)
поскольку это сбивает с толку и часто не нужно, оператор запятой следует избегать, за исключением некоторых очень специфических ситуаций:
- может быть полезно выполнить несколько операций в одном или нескольких из
forуправляющие выражения оператора- он может использоваться в макросах препроцессора для вычисления более одного выражения в одном операторе. Обычно это делается для того, чтобы макросы могли выполнять несколько действий и все же это одно выражение, поэтому макрос будет "вписываться" в места, которые позволяют только выражение.
оператор запятой является хакерским оператором в значительной степени по определению - это взломать 2 вещи, где разрешено только одно. Это почти всегда уродливо, но иногда это все, что у вас есть. И это единственный раз когда вы должны использовать его, если у вас есть другой вариант, не использовать оператор запятая.
С моей головы я не могу придумать слишком много других причин, чтобы используйте оператор, так как вы можете получить аналогичный эффект, оценивая выражения в отдельных операторах в большинстве других ситуаций (хотя я уверен, что кто-то прокомментирует другое использование, которое я пропустил).
Comments