29
Цикл for
Категория: Культура кода Автор: Дмитрий Ляпин Опубликовано: 29-08-2010
Метки: break, continue, for, return, while, бесконечный цикл, цикл
Примеры в статье приведены на языке Си
Достаточно давно мы опубликовали статью о тернарном операторе. Еще один шедевр, пришедший из языка Си, – цикл for.

Это мощнейшая конструкция, позволяющая организовать любой цикл. Например, можно обойтись без привычного while:
while (<условие>)
{
}эквивалентно
for (; <условие>;)
{
}Вот самый обычный пример, вывод на экран чисел от 1 до 100:
for (int i = 1; i <= 100; i++) { printf("%d\r\n", i); }
А вот пример сложнее (просьба не пугаться тем, кто не знаком с языком Си):
for (node_t* i = get_first(); i != NULL; i = get_next(i)) { printf("%d\r\n", get_value(i)); }
Это обход списка с помощью функций get_first(), get_next() и get_value().
- get_first() – получить первый элемент списка; функция возвращает NULL, если список пуст
- get_next(i) – получить элемент, следующий в списке за i; функция возвращает NULL, если i – последний элемент
- get_value(i) – получить значение элемента i (в данном примере значение каждого элемента – целое число)
- node_t – структура, описывающая элемент списка
Общий вид
for (A; B; C) D;
Конструкция for состоит из четырех частей:
- Инициализация (A)
- Условие (B)
- Действие после очередной итерации (C)
- Тело цикла (D)
Алгоритм
Шаг 1. Инициализация.
Шаг 2. Проверка условия; если истинно – переход к шагу 3; иначе – выход из цикла.
Шаг 3. Выполнения тела цикла.
Шаг 4. Выполнение действия после очередной итерации; переход к шагу 2.
Из Википедии я взял хорошую схему, иллюстрирующую написанный выше текст:

Зачем?
Может возникнуть вопрос – для чего нужен такой цикл? Ведь то же самое можно сделать с помощью более простой конструкции – цикла while:
for (A; B; C) D;
эквивалентно
A; while (B) { D; C; }
Ответ лежит в сути циклического процесса. Чаще всего для организации цикла требуется специальная переменная, в самом простом случае – счетчик. Эту переменную нужно инициализировать и производить над ней действия после каждой итерации (например, увеличивать на единицу). Также, конечно, должно быть условие выхода из цикла. Оно может быть связано с этой самой специальной переменной, а может опираться и на другие факторы. Ну и, наконец, что-то нужно делать в самом цикле, то есть выполнять те самые полезные действия, ради которых программисту и потребовалась циклическая конструкция.
Например, если нам нужно вывести на экран числа от 1 до 100, то полезная операция – сам вывод; в то время, как увеличение счетчика на единицу – внутренняя операция организации цикла.
Цикл for позволяет отделить всю служебную часть цикла от самого повторяющегося процесса; резульат – естественность и легкость восприятия, чтения кода, ну и краткость (сестра таланта).
break, continue, return
Эти два оператора позволяют управлять циклическим процессом из самого тела цикла. break влечет мгновенный выход из цикла, continue – переход к следующей итерации (то есть к шагу 4). Кроме того, находясь внутри функции, можно выйти из цикла (равно, как и из самой функции) с помощью оператора return.
Эти возможности могут показаться удобными и в некоторых случаях это действительно так. Но злоупотреблять этим не стоит, лучше правильно продумать условие цикла.
Когда я учился в университете, на лабараторках по Си преподаватель строго запрещал использовать break, continue и return в теле цикла. Это заставляет лучше продумывать алгоритм, сам цикл.
Бесконечный цикл
Запись
for ( ; ; ) { D; }
эквивалентна
for ( ; true; ) { D; }

Такой цикл будет выполняться бесконечно, ну или пока вы не прервете его с помощью break или return. Иногда бывает удобно использовать и такой вид.
Примеры
В завершение приведу несколько примеров на разных си-подобных языках.
JavaScript:
for ( ; ; ) { alert('Вам нравится моя домашняя страничка?'); }
Это бесконечный цикл, вряд ли вы посетите такую страничку снова.
PHP:
for ($i = 0; $i < count($pathes); $i++) { if (file_exists($pathes[$i] . $fileName)) return $pathes[$i] . $fileName; }
Поиск файла по всем возможным путям (указанным в массиве $pathes). Удачный пример с выходом из цикла с помощью оператора return.
C#:
for (IEnumerator<int> it = list.GetEnumerator(); it.MoveNext(); ) { Console.WriteLine(it.Current); }
Пример работы с итератором. Что это такое? Представьте, что в качестве счетчика используется не целочисленная переменная, а целый объект, обладающий набором свойств, имеющий определенное состояние. Так вот, это итератор. Подробнее напишу в другой статье.
А как вы используете цикл for?






for (A; B; C)
D;
эквивалентно
A;
while (B)
{
D;
C;
}
o_O
что, всегда?
не знал что есть – return/
> просьба не пугаться тем, кто не знаком с языком Си
поздно, уже испугался ). а такие функции в РНР есть?
не в тему:
у меня через 3 дня будит 2 недели. если не успею, можно будет продлить на пару дней? не хочу просто торопиться и в слепую делать д/з. паралельно я другую лит-ру читаю, время отнимает.
> что, всегда?
Ну да. Есть тонкости с областью видимости переменной, которую можно объявить в A, но лишь в некоторых языках и это не слишком принципиально.
> а такие функции в РНР есть?
Это не стандартные функции. Если их написать (то есть реализовать работу со списками таким образом) – будут и в PHP.
> у меня через 3 дня будит 2 недели
на p2w нет ограничений по срокам
> на p2w нет ограничений по срокам
это хорошо. а то у чеба преврашается в быстое выполнение д/з )
щас я на 6-ом уроке. идея вроде не сложная, понятная.
но не могу собраться что ли. только не смейтесь, не пойму разницу м/у куками и сессиями, оба делают ондо и то же (запоминают инфу). укажите пожалста четкую грань м/у ними.
я тут подумал, такую же работу (отправка формы, запоминание) делает и $_POST. можно так или не правильно думаю??
>>но не могу собраться что ли. только не смейтесь, не пойму разницу м/у куками и сессиями
Куки действуют срок, определеннй Вами (5 минут или год, к примеру), а сессии – только время работы браузера. Браузер закрыли – сессия удалилась.
>Ну да. Есть тонкости с областью видимости переменной, которую можно объявить в A, но лишь в некоторых языках и это не слишком принципиально.
for ($i = 0; $i < 5; $i++)
{
echo $i;
continue;
}
$i = 0;
while($i < 5)
{
echo $i;
continue;
++$i;
}
o_O
учите матчасть
> Куки действуют срок, определеннй Вами (5 минут или год, к примеру), а сессии – только время работы браузера. Браузер закрыли – сессия удалилась.
Это верно, но основное отличие лежит в самом принципе.
Cookies – это информация, которая хранится на компьютере пользователя (то есть НА КЛИЕНТЕ) и передается при каждом запросе на сервер.
Сессия – это хранилище данных для каждого подключенного пользователя НА СЕРВЕРЕ. Для этого выделяется специальный файл на каждую сессию (в случае PHP). Как сервер понимает, какой файл брать при каждом запросе? Для этого как раз может испозьзоваться идентификатор сессии, переданный через COOKIES.
> я тут подумал, такую же работу (отправка формы, запоминание) делает и $_POST
Нет, POST ничего не запоминает. Там находятся данные переданные при текущей отправке формы.
> учите матчасть
Уважаемый Индус! Вы, вероятно, хотели поделиться особенностью continue и отличием применения оператора в двух разных циклах? Что же, как это работает в for, было написано в статье. Я не заметил никаких противоречий, так что высказывание «учите матчасть» неадекватно. Дальнейшие комментарии в таком духе будут удалены.
>Я не заметил никаких противоречий
for (A; B; C)
D;
эквивалентно
A;
while (B)
{
D;
C;
}
for ($i = 0; $i < 5; $i++)
{
echo $i;
continue;
}
$i = 0;
while($i < 5)
{
echo $i;
continue;
++$i;
}
разве не видно что циклы не эквивалентны?
В примере, приведенным выше, внутри D содержится инструкция, управляющая ходом цикла. Согласен, что результат будет разный в таком случае.
а то вырастет балшой
* хотя комментарий по существу
> Как сервер понимает, какой файл брать при каждом запросе? Для этого как раз может испозьзоваться идентификатор сессии, переданный через COOKIES.
а если я не сохранил в куках ничего?
напр. , открываю Яндекс, сервер посылает мне его главную страницу с формой почты (т.е HTTP с предложением сохранить данные в куках («запомнить меня»)). но я же могу заполнить форму и без куков (т.е отправлю запрос методом POST) и откроется моя почта, т.е новая сессия.
другими словами вся инфа обо мне сохраняется на сервере ($_SESSION), а связь через POST.
а куки причем?? )
ребята, наберитесь терпения, туплю страшно, объясниете пожалста на примере того же Яндекса. )
(желательно с кодом, где указано где и для чего используются куки и сессии (и можно ли было без них))
> а куки причем?? )
Ты заполняешь форму, вводя логин и пароль. Далее это передается, как ты правильно заметил, методом POST на сервер.
Сервер проверяют логин/пароль и выделяет тебе идентификатор сессии (открывает сеанс работы с тобой таким образом). Далее сервер в ответ добавляет заголовок, в котором говорит: «Браузер, запомни, пожалуйста, одну куку. Назови ее SessionID и положи в нее значение 2f78ae789ab3″.
Браузер получает ответ, видит заголовок Set-Cookie и запоминает куку. Далее при каждом запросе (GET/POST) он будет посылать на сервер заголовок, в котором сообщает: «У меня есть кука SessionID, ее значение = 2f78ae789ab3″.
Вот и все.
вижу свет ).
все непонятные моменты попунктно пердаю вам методом ПОСТ ):
1. Посылаю запрос, напр. prog-school.ru приходит ваша главная страница (в этом ответе сревера нет просьбы запомнить куки). теперь заполнил форму – отправил, приходит ответ на те страница и + Куки (т.е сохранить твои логин и пароль?). правильно думаю?
2. Сервер мне предлагает сохранить Куки или делает за меня автоматически?
3.1. если я не поставлю галочку в «запомнить меня» сохранится ли инфа обо мне в Куках?
я думаю нет! Сервер просто дальше работает со мной по идент-му номеру (началась сессия). Я брожу теперь по сайту и сервер понимает что это один пользователь только по номеру (куки тут не причем). получается в вашем примере можно обойтись без сохранения куков, т.е без этого:
setcookie(‘username’, $username, time() + 3600 * 24 * 7);
потому что ставлю я там галочку или нет сервер реагирует одинаково, непонятно зачем она нужна (галочка) (3.1.1).
3.2 Но есть подозрение, что если я НЕ ставлю галочку, Сервер все равно заносит инфу в куки , но на период сессии. так?
вот такие вопросы. инет магазин пытаюсь сделать (без БД конечно), поэтому хочу понять что к чему. )
P.S. еще раз про сохранение куков. пример с вашим сайтом.:
если сервер только предлагает мне сохранить куки, то почему когда я захожу сюда мои имя и мыло уже сохранены у вас?? (меня никто не спрашивал сохранять или нет).
получается сервер заставил браузер их запомнить (а не попросил)??
1. Верно.
2. Говорит браузеру сохранить и он сам сохраняет, без спроса.
3.1 Зависит от того, что делает сервер. Обычно при постановке галочки вызывается что-то типа:
setcookie(‘username’, $username, time() + 3600 * 24 * 7);
Но это специфика обработки запроса твоим скриптом, а не самих куков. Галочка – для скрипта.
3.2 Зависит от способа работы сессии, либо через куки, либо через PHPSESSIONID.
спасибо Дима, многое прояснилось.
теперь попытаюсь че-нить написать )
Здесь собрались ужасно умные ,а я, пока ещё , очень тупой и неграмотный, объясните толком ,какую работу производят все эти действия в браузере,конкретно?
for (A; B; C)
D;
эквивалентно
A;
while (B)
{
D;
C;
}
for ($i = 0; $i < 5; $i++)
{
echo $i;
continue;
}
$i = 0;
while($i < 5)
{
echo $i;
continue;
++$i;
}