Очевидно, что все пишут так:
for(int i =0; i < 5;i++){
//...
}
Но встретил мнение, что такая конструкция абсолютно неправильна и является лишь происками разработчиков компиляторов. Соответственно, надо так:
int i=0;
for(;i < 5;i++){
//...
}
Что в действительности «правильно» по стандарту?
Язык си вплоть до версии C99 не позволяет объявлять переменные в выражении инициализации цикла for. То есть в выражении до первой точки с запятой между круглыми скобками после for (...)
. Кроме того, в языке си версии ниже C99 запрещены однострочные комментарии, начинающиеся с двух наклонных чёрточек (слешей), имеются только многострочные /* ... */
.
Таким образом, оба ваших примера кода являются верными с точки зрения С (но начиная с версии С99 и выше), а также в C++ (любой версии).
Но тем не менее, эти кусочки немного различаются семантически. В первом случае после окончания цикла вы не сможете получить доступ к его счётчику — переменной i
, так как она объявляется в области видимости цикла. Во втором случае после окончания цикла i
будет равно 5 (если не будет инструкций перехода). И переменную можно будет использовать далее, например, что-нибудь присвоить ей. Однако не стоит этим заниматься — это считается признаком плохого стиля, и первый вариант предпочтительнее.
Во-первых, выбор первого или второго варианта как в С++, так и в современном С, делается на основе того, необходимо ли вам продлить область видимости переменной 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)
...
но как правило оно того не стоит.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Здравствуйте! Насколько правильна данная функция по получению имени пользователя с точки зрения выделения и чистки памяти? Нужно ли чистить...
Здравствуйте, нужно переделать данную функцию, так, что б вместо подпоследовательности char, она проверяла подпоследовательность int:
Есть приложение UWP (C#),которое отображает текущую погоду и ее прогноз, с самым простым функционалом