Оператор запятая

Задания раздела 4.10
4.31. Программа этого раздела использовала префиксные операторы инкремента и декремента. Объясните, почему были использованы префиксные, а не постфиксные версии? Что следует изменить для использования постфиксных версий? Перепишите программу с использованием постфиксных операторов.
4.32. Объясните следующий цикл:
constexpr int size=5;
int ia[size]={1,2,3,4,5};
for (int *ptr=ia, ix=0; ix !=size&&ptr!=ia+size; ++ix; ++ptr) { /* ... */}
4.33. Используя таблицу раздела 4.12 (приоритет операторов в предыдущей теме), объясните, что делает следующее выражение:
someValue ? ++x, ++y : --x, --y

Оказывается запятая это тоже оператор. Хотя что это я, здесь нет ни одной лишней ноты.

Запятая имеет левосторонний порядок. Левое выражение обрабатывается а его результат отбрасывается. Результат выражения запятая - это значение правого выражения. Результатом является l-значением, если правый операнд -  l-значение.
Оператор запятая используется часто в цикле for:
vector<int>::size_type cnt=ivec.size();
for (vector<int>::size_type ix=0; ix != ivec.size();++ix,--cnt)
ivec[ix]=cnt;
А сама программа выглядит так:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> ivec(10, 10);
std::vector<int>::size_type cnt=ivec.size();
for (std::vector<int>::size_type ix=0; ix != ivec.size();++ix,--cnt)
ivec[ix]=cnt;
for (auto i: ivec) std::cout << i << " ";
return(0);
}

4.31. Программа этого раздела использовала префиксные операторы инкремента и декремента. Объясните, почему были использованы префиксные, а не постфиксные версии? Что следует изменить для использования постфиксных версий? Перепишите программу с использованием постфиксных операторов.

Программа этого раздела (она выше):
td::vector<int>::size_type cnt=ivec.size();
for (std::vector<int>::size_type ix=0; ix != ivec.size();++ix,--cnt)
ivec[ix]=cnt;
В данном случае ничего не поменяется, кроме того что программа будет хранить первоначальные значения переменных ix и cnt.
Что следует изменить? Ничего, просто переставить знаки за переменную.
for (std::vector<int>::size_type ix=0; ix != ivec.size(); ix++, cnt--) и все.

4.32. Объясните следующий цикл:
constexpr int size=5;
int ia[size]={1,2,3,4,5};
for (int *ptr=ia, ix=0; ix !=size&&ptr!=ia+size; ++ix; ++ptr) { /* ... */}

Цикл проверяет, не равен ли текущий элемент последнему и не указывает ли указатель на элемент за последним, если все это вранье, то увеличивает контрольную переменную на 1 и подвигает итератор на следующую позицию.

4.33. Используя таблицу раздела 4.12 (приоритет операторов в предыдущей теме), объясните, что делает следующее выражение:
someValue ? ++x, ++y : --x, --y

У оператора запятая самый низкий приоритет, порядок левосторонний.
У условного оператора чуть выше запятой, порядок правосторонний.
Самый высокий у префиксного инкремента и декремента, порядок правосторонний.
#include <iostream>
int main()
{
int x=0, y=0, z=0;
std::cin >> z;
z ? ++x, ++y : --x, --y;
std::cout << x << " " << y;
return(0);
}
Вот программа для проверки.
Если z !=0 то вывод 1 0
Если z = 0, то вывод -1 -1
Очевидно, что если условие true, то переменная x увеличивается на 1, а переменная y - увеличивается и сразу же уменьшается. Почему я так подумал? Если огородить скобками второе выражение, которое  срабатывает, если значение условия false - вот так -  z ? ++x, ++y : (--x, --y);
то вывод становится 1 1 при введении значения не равного нулю.
А если условие ложно, то обе переменные изменяются. Я все это постараюсь запомнить, но к запятой надо отнестись осторожно. Она опасна.
И да, я не понимаю почему это происходит. Возможно я плохо читал эти три строчки.
И! Я сварил макарошки, отвлекся и понял. Думаю, происходит вот что. Условие проверяется, если верно, то выполняется ++x, ++y, оператор условия считает что после двоеточия --x это то что нужно сделать в случае false, а --y стоит особняком и выполняется вне условия. Так что --y выполняется всегда вне условия, в случае правильности условия или его ложности. Но при чем здесь запятая?

Добавить комментарий