Когда я был сначала представлен 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()
версия.
В 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'.
Стандарт C99 гласит:
6.8.5.3 Оператор for
Оператор for
for ( clause-1 ; expression-2 ; expression-3 ) statement
ведет себя следующим образом: Выражение expression-2 является управляющим выражением, которое оценивается перед каждым выполнением тела цикла. Выражение выражение-3 оценивается как пустое выражение после каждого выполнения тела цикла. Если пункт-1 является объявлением, то областью видимости любых переменных, объявленных в нем, является остаток объявления и весь цикл, включая два других выражения; она достигается в порядке выполнения до первой оценки управляющего выражения. Если пункт-1 является выражением, то оно оценивается как выражение void перед первой оценкой управляющего выражения.
Первое, что я хотел бы отметить, это то, что вы не должны путать
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;
}
Я неправильно понял, что вы хотите сказать?
Суть вашей путаницы с for
/fgets
в том, что хотя "заключающие скобки управляют областью видимости" - это правильное правило в C в большинстве случаев, в C99 есть другое правило относительно области видимости (заимствованное из C++), которое гласит, что переменная, объявленная в прологе управляющей структуры (т.е. в for
/fgets
), не может быть объявлена в прологе управляющей структуры. for
, while
, if
) находится в области видимости в теле структуры (и не находится в области видимости вне тела).