Я хотів би збільшити дві змінні в 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 ++
Дякую за всі коментарі, це був цікавий досвід навчання, і я використовую С вже багато років!
Спробуйте це
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 AV
. Вираз збільшення в циклі for не виконуватиме жодної дії, крім зміни параметра одного циклу на наступне значення для циклу.Обґрунтування: читабельність.
Я прийшов сюди, щоб нагадати собі, як кодувати другий індекс у речення збільшення цикла FOR, що, як я знав, можна зробити головним чином, спостерігаючи його у зразку, який я включив до іншого проекту, написаного на C ++.
Сьогодні я працюю в C #, але я був впевнений, що він буде підкорятися тим самим правилам у цьому відношенні, оскільки оператор FOR є однією з найдавніших структур управління у всьому програмуванні. На щастя, нещодавно я провів кілька днів, точно документуючи поведінку циклу FOR в одній зі своїх старих програм C, і швидко зрозумів, що ці дослідження проводили уроки, які стосуються сьогоднішньої проблеми C #, зокрема поведінки другої змінної індексу .
Для обережних далі подається короткий зміст моїх спостережень. Все, що я бачив, що відбувалося сьогодні, уважно спостерігаючи за змінними у вікні Locals, підтвердило моє сподівання, що оператор C # FOR поводиться точно так само, як оператор C або C ++ FOR.
Якщо будь-яка з ваших змінних індексу залишається в області дії, коли цикл закінчується, їх значення буде на одне вище порога, який зупиняє цикл, у випадку істинної змінної індексу. Подібним чином, якщо, наприклад, друга змінна ініціалізується нулем до введення циклу, її значення в кінці буде підраховувати кількість ітерацій, припускаючи, що це приріст (++), а не зменшення, і що нічого в тіло циклу змінює своє значення.
Я погоджуюся з віскатом. Збільшення двох змінних схильне до помилок, особливо якщо ви перевіряєте лише одну з них.
Це можна прочитати так:
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);
Особливо якщо ви переходите до функції за значенням, тоді ви повинні отримати щось, що робить саме те, що ви хочете.