Как поместить два оператора increment в цикл C++ 'for'?
Я хотел бы увеличить две переменные в for
-условие цикла вместо одного.
что-то вроде:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
каков синтаксис для этого?
8 ответов
обычной практикой является использование оператор запятая, который вычисляет оба операнда и возвращает значение второго операнда. Таким образом:
for(int i = 0; i != 5; ++i,++j)
do_something(i,j);
но действительно ли это оператор запятой?
int i=0;
int a=5;
int x=0;
for(i; i<5; x=i++,a++){
printf("i=%d a=%d x=%d\n",i,a,x);
}
Я ожидал, что x подберет исходное значение a, поэтому он должен иметь отображается 5,6,7.. для X. Я получил вот что!--7-->
i=0 a=5 x=0
i=1 a=6 x=0
i=2 a=7 x=1
i=3 a=8 x=2
i=4 a=9 x=3
однако, если я заключил выражение в скобки, чтобы заставить парсер действительно видеть оператор запятой, я получаю это
int main(){
int i=0;
int a=5;
int x=0;
for(i=0; i<5; x=(i++,a++)){
printf("i=%d a=%d x=%d\n",i,a,x);
}
}
i=0 a=5 x=0
i=1 a=6 x=5
i=2 a=7 x=6
i=3 a=8 x=7
i=4 a=9 x=8
Первоначально я думал, что это показало, что он вообще не ведет себя как оператор запятой, но, как оказалось, это просто проблема приоритета - оператор запятой имеет минимально возможный приоритет, поэтому выражение x=i++, a++ эффективно анализируется как (x=i++), a++
Спасибо за все замечания, это был интересный опыт, и я использую C в течение многих лет!
постарайтесь не делать этого!
от http://www.research.att.com / ~BS / JSF-AV-rules.pdf:
AV правило 199
Выражение инкремента в цикле будет выполнять никаких действий, кроме изменения одного параметр loop к следующему значению для цикла.Обоснование: Читабельность.
Я пришел сюда, чтобы напомнить себе, как закодировать второй индекс в предложение инкремента цикла FOR, что, как я знал, можно сделать в основном из наблюдения за ним в образце, который я включил в другой проект, написанный на C++.
сегодня я работаю на C#, но я был уверен, что он будет подчиняться тем же правилам в этом отношении, поскольку оператор FOR является одной из старейших структур управления во всем программировании. К счастью, недавно я провел несколько дней, точно документируя поведение цикла FOR в одной из моих старых программ на C, и я быстро понял, что эти исследования провели уроки, которые применимы к сегодняшней проблеме C#, в частности к поведению второй переменной индекса.
для неосторожных ниже приводится резюме моих наблюдений. Все, что я видел сегодня, тщательно наблюдая за переменными в окне Locals, подтвердило мое ожидание, что оператор C# FOR ведет себя точно так же, как C или C++ для заявление.
- при первом выполнении цикла FOR предложение increment (третье из трех) пропускается. В Visual C и c++ инкремент генерируется в виде трех машинных инструкций в середине блока, реализующего цикл, так что начальный проход выполняет код инициализации только один раз, а затем перескакивает через блок инкремента для выполнения теста завершения. Это реализует функцию, которую цикл FOR выполняет ноль или более раз, в зависимости от состояния индексные и предельные переменные.
- если тело цикла выполняется, его последний оператор является переходом к первой из трех инструкций приращения, которые были пропущены первой итерацией. После их выполнения элемент управления естественным образом попадает в тестовый код limit, реализующий предложение middle. Результат этого теста определяет, выполняется ли тело цикла FOR или передается ли управление следующей инструкции после перехода в нижней части его области.
- С передача управления из нижней части блока цикла FOR в блок инкремента, переменная индекса увеличивается перед выполнением теста. Это поведение не только объясняет, почему вы должны кодировать свои предельные предложения так, как вы узнали, но и влияет на любое дополнительное приращение, которое вы добавляете через оператор запятой, потому что оно становится частью третьего предложения. Следовательно, он не изменяется на первой итерации, но он находится на последней итерации, которая никогда не выполняет тело.
Если какая-либо из ваших переменных индекса остается в области видимости, когда цикл заканчивается, их значение будет выше порога, который останавливает цикл, в случае переменной true index. Аналогично, если, например, вторая переменная инициализируется до нуля до ввода цикла, ее значение в конце будет числом итераций, предполагая, что это инкремент ( ++ ), а не декремент, и что ничто в теле цикла не изменяет его значение.
Я согласен со сквлартом. Увеличение двух переменных подвержено ошибкам, особенно если вы тестируете только одну из них.
это читаемый способ сделать это:
for(int i = 0; i < 5; ++i) {
++j;
do_something(i, j);
}
For
петли предназначены для случаев, когда ваш цикл работает на одной переменной увеличения/уменьшения. Для любой другой переменной измените ее в цикле.
Если вам нужно j
быть привязанным к i
, Почему бы не оставить оригинальную переменную как есть и добавить i
?
for(int i = 0; i < 5; ++i) {
do_something(i,a+i);
}
если ваш логика сложнее (например, вам нужно фактически контролировать более одной переменной), я бы использовал while
петли.
Использовать Математику. Если две операции математически зависят от итерации цикла, почему бы не сделать математику?
int i, j;//That have some meaningful values in them?
for( int counter = 0; counter < count_max; ++counter )
do_something (counter+i, counter+j);
или, более конкретно, ссылаясь на пример OP:
for(int i = 0; i != 5; ++i)
do_something(i, j+i);
особенно если вы переходите в функцию по значению, то вы должны получить что-то, что делает именно то, что вы хотите.