Где я могу юридически объявить переменную в C99?
Когда я впервые познакомился с C, мне сказали всегда объявлять мои переменные в верхней части функции. Теперь, когда у меня есть сильное понимание языка, я фокусирую свои усилия на стиле кодирования, особенно ограничивая область моих переменных. Я прочитал о преимуществах, ограничивающих сферу охвата, и я наткнулся на интересный пример. По-видимому, C99 позволяет вам это делать...
for (int i = 0; i < 10; i++)
{
puts("hello");
}
Я думал, что область переменных ограничена внутренними наиболее близкими фигурными фигурными скобками { }
, но в приведенном выше примере int i
оказывается ограниченным по объему фигурными скобками цикла for, хотя это объявляется вне их.
Я попытался расширить приведенный выше пример с помощью fgets()
, чтобы сделать то, что, как я думал, было чем-то похожим, но оба из них дали мне синтаксическую ошибку.
fgets(char fpath[80], 80, stdin);
* См. примечание **
fgets(char* fpath = malloc(80), 80, stdin);
Итак, где именно законно объявлять переменные в C99? Был ли пример for-loop исключением из правила? Это относится также к циклам while
и do while
?
* Примечание **: Я даже не уверен, что это будет синтаксически корректно, даже если я могу объявить массив char, так как fgets()
ищет указатель на char не указатель на массив 80 из char. Вот почему я попробовал версию malloc()
.
Ответы
Ответ 1
В C99 вы можете объявить свои переменные там, где они вам нужны, так же, как С++ позволяет это сделать.
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++) /* New in C99 */
-
Вы не можете объявить переменную в контрольной части цикла while или оператора if.
- Вы не можете объявить переменную в вызове функции.
- Очевидно, вы можете (и всегда можете) объявлять переменные в блоке после любого цикла или оператора if.
В стандарте C99 говорится:
6.8.5.3 Оператор for
Утверждение
for ( clause-1 ; expression-2 ; expression-3 ) statement
ведет себя следующим образом: выражение expression-2 является управляющим выражением, которое оценивается перед каждым исполнением тела цикла. Выражение выражение-3 оценивается как выражение void после каждого выполнения тела цикла. Если предложение-1 является объявление, объем любых переменных, которые он объявляет, является остатком декларации и весь цикл, включая два других выражения; это достигается в порядке исполнения перед первой оценкой контролирующего выражения. Если выражение-1 является выражением, оно оценивается как выражение void перед первой оценкой контролирующего выражения.
Ответ 2
Первое, что я хотел бы отметить, это то, что вы не должны путать
for (int i = 0; i < 10; i++) {
puts("hello");
}
и
fgets(char* fpath = malloc(80), 80, stdin);
Первая - это структура управления, а вторая - вызов функции. Структура управления оценивает текст внутри него parens() по-разному, как это делает вызов функции.
Во-вторых, я не понимаю, что вы пытаетесь сказать:
компилятор незамедлительно даст вам ошибку, если вы попытаетесь использовать я внутри тела for-loop.
Код, который вы указали для цикла for, является очень распространенной структурой в C, и переменная "i" должна, действительно, быть доступна внутри тела цикла for. То есть должно работать следующее:
int n = 0;
for (int i = 0; i < 10; i++) {
n += i;
}
Я неправильно понимаю, что вы говорите?
Ответ 3
Нижняя строка в отношении вашей путаницы for
/fgets
заключается в том, что, хотя "охватывающая область управления фигурными записями" является правильным правилом в C большую часть времени, существует другое правило относительно области действия в C99 (заимствованное из С++), который говорит, что переменная, объявленная в прологе структуры управления (т.е. for
, while
, if
), находится в области видимости в теле структуры (и не находится в области вне тела).