Описание переменной цикла for

402
14 июля 2017, 05:14

Очевидно, что все пишут так:

for(int i =0; i < 5;i++){
   //...
}

Но встретил мнение, что такая конструкция абсолютно неправильна и является лишь происками разработчиков компиляторов. Соответственно, надо так:

int i=0;
for(;i < 5;i++){
   //...
} 

Что в действительности «правильно» по стандарту?

Answer 1

Язык си вплоть до версии C99 не позволяет объявлять переменные в выражении инициализации цикла for. То есть в выражении до первой точки с запятой между круглыми скобками после for (...). Кроме того, в языке си версии ниже C99 запрещены однострочные комментарии, начинающиеся с двух наклонных чёрточек (слешей), имеются только многострочные /* ... */.

Таким образом, оба ваших примера кода являются верными с точки зрения С (но начиная с версии С99 и выше), а также в C++ (любой версии).

Но тем не менее, эти кусочки немного различаются семантически. В первом случае после окончания цикла вы не сможете получить доступ к его счётчику — переменной i, так как она объявляется в области видимости цикла. Во втором случае после окончания цикла i будет равно 5 (если не будет инструкций перехода). И переменную можно будет использовать далее, например, что-нибудь присвоить ей. Однако не стоит этим заниматься — это считается признаком плохого стиля, и первый вариант предпочтительнее.

Answer 2

Во-первых, выбор первого или второго варианта как в С++, так и в современном С, делается на основе того, необходимо ли вам продлить область видимости переменной i за пределы цикла. Поэтому вне контекста ни первый, ни второй вариант в общем случае не могут рассматриваться как однозначно предпочтительные. Вопрос в том, что именно вам нужно в данном месте кода.

Во-вторых, заголовок цикла for допускает только одну декларацию. Это означает, что если у вас процесс итерации обслуживается несколькими переменными, требующими разных decl-specifier-seq, то хочешь-не хочешь, но некоторые из них придется объявить перед циклом

unsigned i = 0;
for (double *it = container; i < n; ++i, ++it)
  ...

Это ограничение можно обойти способами вроде

for (struct { unsigned i; double *it; } i = { 0, container }; i.i < n; ++i.i, ++i.it)
  ...

но как правило оно того не стоит.

READ ALSO
Насколько правильна эта функция?

Насколько правильна эта функция?

Здравствуйте! Насколько правильна данная функция по получению имени пользователя с точки зрения выделения и чистки памяти? Нужно ли чистить...

276
Как сделать программу-фильтр для потока видео?

Как сделать программу-фильтр для потока видео?

Есть поток видеоТо есть, бесконечный

245
Переделать char функцию под int

Переделать char функцию под int

Здравствуйте, нужно переделать данную функцию, так, что б вместо подпоследовательности char, она проверяла подпоследовательность int:

317
Создать 2D анимацию для приложения UWP с привязкой DirectX

Создать 2D анимацию для приложения UWP с привязкой DirectX

Есть приложение UWP (C#),которое отображает текущую погоду и ее прогноз, с самым простым функционалом

240