Я хотел бы увеличить две переменные в состоянии for
-loop вместо одного.
Так что-то вроде:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
Каков синтаксис для этого?
Я хотел бы увеличить две переменные в состоянии for
-loop вместо одного.
Так что-то вроде:
for (int i = 0; i != 5; ++i and ++j)
do_something(i, j);
Каков синтаксис для этого?
Общей идиомой является использование оператора который оценивает оба операнда и возвращает второй операнд. Таким образом:
for(int i = 0; i != 5; ++i,++j)
do_something(i,j);
Теперь, написав это, комментатор предположил, что на самом деле это был какой-то особый синтаксический сахар в инструкции for, а не как оператор запятой. Я проверил это в GCC следующим образом:
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. Я получил это
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 = я ++, a ++ эффективно анализируется как (x = я ++), a ++
Спасибо за все комментарии, это был интересный опыт обучения, и я много лет использую C!
Попробуйте это
for(int i = 0; i != 5; ++i, ++j)
do_something(i,j);
Старайтесь не делать этого!
Из http://www.research.att.com/~bs/JSF-AV-rules.pdf:
Правило AV 199
Выражение приращения в цикле for не будет выполнять никаких действий, кроме как изменить один loop для следующего значения для цикла.Обоснование: читаемость.
for (int i = 0; i != 5; ++i, ++j)
do_something(i, j);
Я пришел сюда, чтобы напомнить себе, как закодировать второй индекс в предложение increment цикла FOR, который, как я знал, может быть сделан главным образом из наблюдения за ним в образце, который я включил в другой проект, написанный на С++.
Сегодня я работаю на С#, но я был уверен, что он будет подчиняться тем же правилам в этом отношении, поскольку оператор FOR является одной из старейших структур управления во всем программировании. К счастью, недавно я провел несколько дней, точно документируя поведение цикла FOR в одной из моих старых программ на C, и я быстро понял, что в этих исследованиях были уроки, которые применимы к сегодняшней проблеме С#, в частности, к поведению второй индексной переменной.
Для неосторожного ниже приведено резюме моих наблюдений. Все, что я видел сегодня, тщательно наблюдая переменные в окне "Локали", подтвердило мое ожидание того, что оператор С# FOR ведет себя точно так же, как оператор C или С++ FOR.
Если любая из ваших индексных переменных остается в области действия, когда цикл завершается, их значение будет на один выше порога, который останавливает цикл, в случае истинной индексной переменной. Аналогично, если, например, вторая переменная инициализируется до нуля до ввода цикла, ее значение в конце будет счетчиком итераций, предполагая, что это инкремент (++), а не декремент, и что ничего в тело цикла меняет свое значение.
Я согласен с податливостью. Увеличение двух переменных связано с ошибкой, особенно если вы проверяете только один из них.
Это читаемый способ сделать это:
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 main(){
int i=0;
int a=0;
for(i;i<5;i++,a++){
printf("%d %d\n",a,i);
}
}
Используйте математику. Если две операции математически зависят от итерации цикла, почему бы не выполнить математику?
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);
Особенно, если вы переходите к функции по значению, то вы должны получить то, что делает именно то, что вы хотите.