Подтвердить что ты не робот

В С++ почему я не могу написать цикл for() следующим образом: for (int я = 1, double i2 = 0;

или "Объявление нескольких переменных в цикле for ist verboten"?!

Мой исходный код был

 for( int i = 1, int i2 = 1; 
      i2 < mid;
      i++, i2 = i * i ) {

Я хотел пропустить первый так много квадратов и хотел как числа, так и его квадрата, а условие остановки зависело от квадрата. Этот код кажется самым чистым выражением намерения, но он недействителен. Я могу думать о дюжине способов обойти это, поэтому я не ищу лучшей альтернативы, но для более глубокого понимания того, почему это недействительно. Немного языковой адвокации, если хотите.

Я достаточно взрослый, чтобы помнить, когда вам приходилось объявлять все свои переменные в начале функции, поэтому я ценю

for( int i = 0; ....

синтаксис. Чтение вокруг этого похоже, что вы можете иметь только одно объявление типа в первом разделе инструкции for(). Таким образом, вы можете сделать

for( int i=0, j=0; ...

или даже немного барокко

for( int i=0, *j=&i; ...

но не для разумного

for( int i=0, double x=0.0; ...

Кто-нибудь знает, почему? Это ограничение для()? Или ограничение на списки запятой, например "первый элемент списка запятой может объявлять тип, но не другой? Являются ли следующие виды использования запятых различными синтаксическими элементами С++?

(А)

for( int i=0, j=0; ...

(В)

int i = 0, j = 0;

(С)

 int z;
 z = 1, 3, 4;

Любые гуру?

=============================================== =====

Основываясь на хороших ответах, которые я получил, я думаю, что могу заострить вопрос:

В инструкции for

for( X; Y; Z;) {..... }

что такое X, Y и Z?

Мой вопрос был о С++, но у меня нет отличного С++ refrence. В моей ссылке C (Harbison and Steele 4th ed, 1995) все три выражения , и мой gcc требует использования режима C99 для (int я = 0;

В Stroustrup, с. 6.3, синтаксис for for задается как

for (for-init-statement; condition; expression) statements

Итак, у С++ есть специальный синтаксический оператор, посвященный первому предложению for(), и мы можем предположить, что у них есть специальные правила, отличные от тех, которые используются для выражения. Правильно ли это звучит?

4b9b3361

Ответ 1

int i = 1, double i2 = 0; не является допустимым объявлением, поэтому он не может использоваться внутри оператора for. Если оператор не может стоять отдельно вне for, то он не может использоваться внутри оператора for.

Edit: Что касается ваших вопросов о операторах с запятой, опции "A" и "B" идентичны и являются действительными. Опция "C" также действительна, но, вероятно, не будет делать то, что вы ожидаете. z будет присвоен 1, а операторы 3 и 4 фактически ничего не делают (ваш компилятор, вероятно, предупредит вас о "операторах без эффекта" и оптимизирует их).

Update: Чтобы ответить на вопросы в вашем редактировании, вот как спецификация С++ (раздел 6.5) определяет for:

for ( for-init-statement condition(opt) ; expression(opt) ) statement

Далее он определяет for-init-statement как либо expression-statement, либо simple-declaration. Оба condition и expression являются необязательными.

for-init-statement может быть любым действительным expression-statement (например, i = 0;) или simple-declaration (например, int i = 0;). Оператор int i = 1, double i2 = 0; не является допустимым simple-declaration по спецификации, поэтому он недействителен для использования с for. Для справки, a simple-declaration определяется (в разделе 7) как:

attribute-specifier(opt) decl-specifier-seq(opt) init-declarator-list(opt) ;

где decl-specifier-seq будет типом данных плюс ключевые слова, такие как static или extern, а init-declarator-list будет разделенным запятыми списком деклараторов и их необязательными инициализаторами. Попытка помещать более одного типа данных в один и тот же simple-declaration по существу ставит a decl-specifier-seq, где компилятор ожидает init-declarator-list. Увидев этот элемент неуместным, компилятор обрабатывает линию как плохо сформированную.

Спецификация также отмечает, что цикл for эквивалентен:

{
    for-init-statement
    while ( condition ) {
        statement
        expression ;
    }
}

где condition по умолчанию используется значение "true", если оно опущено. Размышление об этой "расширенной" форме может быть полезно при определении того, может ли данный синтаксис использоваться с циклом for.

Ответ 2

Если вам нужно использовать несколько переменных различного типа для цикла, вы можете использовать структуры следующим образом:

for( struct {int i; long i2;} x = {1, 1}; x.i2 < mid; x.i++, x.i2 = x.i * x.i )
{
  cout << x.i2 << endl;
}

поэтому это не ограничение, просто используйте немного другой синтаксис.

Ответ 3

На самом деле это ограничение заявлений декларации:

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;

Ответ 4

До тех пор, пока вы можете написать действительный оператор с помощью запятой ,, это приемлемо.

Ответ 5

С++ (также C и Java) не допускают объявления более чем одного типа переменных в области цикла for. В грамматике это потому, что в этом контексте запятая не запускает новое утверждение. Фактически, внутри оператора for(;;) допускается только одно объявление. Обоснование заключается в том, что это требование довольно необычно, и вы можете получить его только с чуть более подробной конструкцией.

Ответ 6

Ну, я сделал еще несколько поисковых запросов, и я думаю, что ответ для С++ - это выражения 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. ] 

Итак, спецификация синтаксиса С++. специально взломан, так что в первом слоте допускается только один spec-spec (т.е. тип). Похоже, наши попытки утверждать из основных принципов обречены. Спасибо за все ответы.

Ответ 7

Я вижу, почему вы надеетесь, что это сработает, но... учитывая, что даже с использованием довольно простого умного инструмента обучения, который

for (i=0; i<max; i++){
   ...
}

эквивалентно

i=0;
while (i<max){
   ...
   i++;
}

Синтаксис не работает --- Я не понимаю, почему вы ожидали, что это произойдет. EAch бит должен быть действительным.