Где я могу по закону объявить переменную в C99?

Когда я был сначала представлен C, мне сказали всегда объявить мои переменные во главе функции. Теперь, когда у меня есть сильное схватывание языка, я фокусирую свои усилия на стиле кодирования, особенно ограничивая объем моих переменных. Я читал о преимуществах для ограничения объема, и я столкнулся с интересным примером. По-видимому, C99 позволяет Вам делать это...

for (int i = 0; i < 10; i++)
{
   puts("hello");
}

Я думал, что объем переменных был ограничен самыми внутренними окружающими фигурными скобками { }, но в вышеупомянутом примере int i кажется, ограничен в объеме фигурными скобками для цикла даже при том, что он объявляется за пределами них.

Я пытался расширить вышеупомянутый пример с помощью fgets() сделать, что я думал, было чем-то подобным, но оба из них дали мне синтаксическую ошибку.

fgets(char fpath[80], 80, stdin); *См. Примечание **

fgets(char* fpath = malloc(80), 80, stdin);

Так, где точно действительно ли законно объявить переменные в C99? Действительно ли примером для цикла было исключение из правила? Делает это относится while и do while циклы также?

*Примечание **: я даже не уверен, что это было бы синтаксически корректно, даже если я мог бы объявить массив символов там с тех пор fgets() ищет указатель для обугливания не указателя для выстраивания 80 из символа. Поэтому я попробовал malloc() версия.

34
задан jefe2000 30 May 2014 в 15:35
поделиться

3 ответа

В C99 вы можете объявлять свои переменные там, где они вам нужны, точно так же, как это позволяет делать C++.

void somefunc(char *arg)
{
    char *ptr = "xyz";
    if (strcmp(arg, ptr) == 0)
    {
        int abc = 0;    /* Always could declare variables at a block start */

        somefunc(arg, &ptr, &abc);

        int def = another_func(abc, arg);   /* New in C99 */
        ...other code using def, presumably...
    }
}
  • Вы можете объявить переменную в управляющей части цикла 'for':

    for (int x = 0; x < 10; x++) /* Новое в C99 */
    
  • Нельзя объявить переменную в управляющей части цикла 'while' или оператора 'if'.

  • Вы не можете объявить переменную в вызове функции.
  • Очевидно, что вы можете (и всегда могли) объявлять переменные в блоке после любого цикла или оператора 'if'.

Стандарт C99 гласит:

6.8.5.3 Оператор for

Оператор for

for ( clause-1 ; expression-2 ; expression-3 ) statement

ведет себя следующим образом: Выражение expression-2 является управляющим выражением, которое оценивается перед каждым выполнением тела цикла. Выражение выражение-3 оценивается как пустое выражение после каждого выполнения тела цикла. Если пункт-1 является объявлением, то областью видимости любых переменных, объявленных в нем, является остаток объявления и весь цикл, включая два других выражения; она достигается в порядке выполнения до первой оценки управляющего выражения. Если пункт-1 является выражением, то оно оценивается как выражение void перед первой оценкой управляющего выражения.

36
ответ дан 27 November 2019 в 17:03
поделиться

Первое, что я хотел бы отметить, это то, что вы не должны путать

for (int i = 0; i < 10; i++) {
    puts("hello");
}

и

fgets(char* fpath = malloc(80), 80, stdin);

Первое - это управляющая структура, а второе - вызов функции. Управляющая структура оценивает текст внутри parens() совсем не так, как это делает вызов функции.

Вторая вещь... Я не понимаю, что вы хотите сказать:

компилятор немедленно выдаст вам ошибку, если вы попытаетесь использовать i внутри тела цикла for.

Код, который вы привели для цикла for, является очень распространенной структурой в Си, и переменная "i" действительно должна быть доступна внутри тела цикла for. То есть, должно работать следующее:

int n = 0;
for (int i = 0; i < 10; i++) {
    n += i;
}

Я неправильно понял, что вы хотите сказать?

8
ответ дан 27 November 2019 в 17:03
поделиться

Суть вашей путаницы с for/fgets в том, что хотя "заключающие скобки управляют областью видимости" - это правильное правило в C в большинстве случаев, в C99 есть другое правило относительно области видимости (заимствованное из C++), которое гласит, что переменная, объявленная в прологе управляющей структуры (т.е. в for/fgets), не может быть объявлена в прологе управляющей структуры. for, while, if) находится в области видимости в теле структуры (и не находится в области видимости вне тела).

2
ответ дан 27 November 2019 в 17:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: