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