или, "Объявляя несколько переменных в для цикла ist verboten"?!
Мой исходный код был
for( int i = 1, int i2 = 1;
i2 < mid;
i++, i2 = i * i ) {
Я хотел циклично выполнить через первое столько квадратов и хотел и число и его квадрат, и условие остановки зависело от квадрата. Этот код, кажется, самое чистое выражение намерения, но это недопустимо. Я могу думать о дюжине способов работать вокруг этого, таким образом, я не ищу лучшую альтернативу, но для более глубокого понимания того, почему это недопустимо. Немного языка lawyering, если Вы будете.
Я являюсь достаточно взрослым для запоминания, когда необходимо было объявить все переменные в начале функции, таким образом, я ценю
for( int i = 0; ....
синтаксис. Чтение вокруг этого похоже на Вас, может только иметь одно описание типа в первом разделе для () оператор. Таким образом, можно сделать
for( int i=0, j=0; ...
или даже немного барочное
for( int i=0, *j=&i; ...
но не to-me-sensible
for( int i=0, double x=0.0; ...
Кто-либо знает почему? Действительно ли это - ограничение для ()? Или ограничение на списки запятой, как "первый элемент списка запятой может объявить тип, но не другой? Является следующее использование запятых отличными синтаксическими элементами C++?
(A)
for( int i=0, j=0; ...
(B)
int i = 0, j = 0;
(C)
int z;
z = 1, 3, 4;
Какие-либо гуру там?
На основе хороших ответов я добрался, я думаю, что могу увеличить резкость вопроса:
В для оператора
for( X; Y; Z;) {..... }
что X, Y и Z?
Мой вопрос был о C++, но у меня нет большой ссылки C++. В моей ссылке C (Harbison и Steele 4-й редактор, 1995), они - все три выражения, и мой gcc требует, чтобы режим C99 использовал для (интервал i = 0;
В Stroustrup секунда 6.3, для синтаксиса оператора дана как
для (for-init-statement;состояние; выражение) операторы
Таким образом, C++ имеет специальный синтаксический оператор, выделенный первому пункту в для (), и мы можем предположить, что у них есть специальные правила вне тех, которые для выражения. Это звучит допустимым?
int i = 1, double i2 = 0;
не является допустимым оператором объявления, поэтому его нельзя использовать внутри оператора for
. Если оператор не может стоять отдельно за пределами для
, то его нельзя использовать внутри оператора для
.
Изменить:
Что касается ваших вопросов об операторах запятой, варианты «A» и «B» идентичны и оба действительны. Вариант "C" также действителен, но, вероятно, не будет делать того, чего вы ожидаете. z
будет присвоено 1
, а операторы 3
и 4
на самом деле ничего не делают (ваш компилятор, вероятно, предупредит вас о «заявления без эффекта» и оптимизировать их).
Обновление:
Чтобы ответить на вопросы в вашей редакции, вот как спецификация C ++ (раздел 6.5) определяет для
:
for ( for-init-statement condition(opt) ; expression(opt) ) statement
Далее он определяет for-init-statement
как выражение-выражение
или простое объявление
. Оба условия
и выражение
являются необязательными.
for-init-statement
может быть любым действительным выражением-оператором
(например, i = 0;
) или простым -объявление
(например, int i = 0;
). Оператор int i = 1, double i2 = 0;
не является допустимым простым объявлением
в соответствии со спецификацией, поэтому его нельзя использовать с для
]. Для справки, простое объявление
определяется (в Разделе 7) как:
attribute-specifier(opt) decl-specifier-seq(opt) init-declarator-list(opt) ;
где decl-спецификатор-seq
будет типом данных плюс такие ключевые слова, как static
или extern
и init-declarator-list
будет списком деклараторов и их необязательных инициализаторов, разделенных запятыми. Попытка поместить более одного типа данных в одно и то же простое объявление
по существу помещает decl-спецификатор-seq
там, где компилятор ожидает init-declarator-list
. Видя этот элемент не на своем месте, компилятор считает строку неверно сформированной.
В спецификации также отмечается, что цикл for
эквивалентен:
{
for-init-statement
while ( condition ) {
statement
expression ;
}
}
где условие
по умолчанию принимает значение «истина», если оно опущено. Обдумывание этой «расширенной» формы может помочь определить, можно ли использовать данный синтаксис с циклом for
.
На самом деле это ограничение деклараций:
int i=0, j=0, *k=&i; // legal
int i=0, double x=0.0; // illegel
Итак, в основном, ответ на ваш последний вопрос: (A) и (B) одинаковы. (C) отличается.
Как указывает bta:
z = 1,3,4;
то же самое, что и
z = 1;
Однако это потому, что =
имеет более высокий приоритет, чем ,
. Если бы он был записан как:
z = (1,3,4);
, то это было бы так же, как:
z = 4;
C ++ (также C и Java) не разрешает объявление более одного типа переменных в области цикла for. . В грамматике это потому, что запятая не начинает новый оператор в этом контексте. Фактически, внутри оператора for (;;)
допускается только одно объявление. Обоснование состоит в том, что это требование довольно необычно, и вы можете получить его только с немного более подробной конструкцией.
Я понимаю, почему вы надеетесь , что это сработает, но --- учитывая, что даже при использовании довольно простого обучающего инструмента, который
for (i=0; i<max; i++){
...
}
эквивалентен
i=0;
while (i<max){
...
i++;
}
у вас не работает синтаксис - я не понимаю, почему вы ожидали , что это произойдет. Единица битов должна быть действительной.
Ну, я еще погуглил, и я думаю, что ответ для C ++ - «операторы for () - это особые места» Ick.
Выдержка из спецификации ISO:
for ( for-init-statement conditionopt ; expressionopt ) statement
где
for-init-statement:
expression-statement
simple-declaration
и они должны указать это
[Note: a for-init-statement ends with a semicolon. ]
Итак, спецификация синтаксиса C ++. специально взломан, так что в первом слоте допускается только одна декларация (т. е. тип). Похоже, наши попытки аргументировать основные принципы были обречены. Спасибо за все ответы.
Если вам нужно использовать несколько переменных разного типа в for-loop, то вы можете использовать структуры следующим образом:
for( struct {int i; long i2;} x = {1, 1}; x.i2 < mid; x.i++, x.i2 = x.i * x.i )
{
cout << x.i2 << endl;
}
так что это не ограничение, просто используйте немного другой синтаксис.
Если вы можете написать действительный оператор с помощью оператора запятой ,
, это приемлемо.