?

Log in

No account? Create an account
Программистское - Логово программиста
February 1st, 2005
01:25 pm

[Link]

Previous Entry Share Next Entry
Программистское
(Не знающим C/C++ можно не читать)

Мне всегда казалось, что я умею правильно писать циклы for. Например так:

int i, first, last;
first = ...;
last = ...;
for (i = first; i <= last; i++)
{
...
}


Но оказывается, что я не нюхавший пороха щенок. Делать надо так (взято из исходника одной из
свободно распространяемых программ):

int i, first, last, count;
first = ...;
last = ...;
count = last - first + 1;
for (i = first; count; i++, count--)
{
...
}


Оно, конечно, такой цикл имеет одно важное преимущество. Он будет корректно работать, если last окажется равен максимальному целому. Но выглядит это спесифисски.

(8 comments | Leave a comment)

Comments
 
[User Picture]
From:m_greg_1975
Date:February 1st, 2005 11:14 am (UTC)
(Link)
Чего то не вижу разницы. I++ в обоих случаях присутсвует. Вот если бы он во втором примере был первым оператором цикла... (или я не так все понимаю?)
[User Picture]
From:d_byzero
Date:February 1st, 2005 11:29 am (UTC)
(Link)
Ну как же нет разницы? Будем считать, что все переменные unsigned char (чтоб длинные цифры не писать), first = 254, last = 255, count = 2.

Пример 1.
Шаг 1. i = 254, проверка 254 <= 255 ? -- да, цикл выполняется, i++ ...
Шаг 2. i = 255, проверка 255 <= 255 ? -- да, цикл выполняется, i++ ...
Шаг 3. i = 0 (!!!), проверка 0 <= 255 ? -- да...

То есть количество повторений бесконечно.

Пример 2.
Шаг 1. i = 254, count = 2. count != 0 ? -- да, цикл выполняется, i++, count --
Шаг 2. i = 255, count = 1. count != 0 ? -- да, цикл выполняется, i++, count --
Шаг 3. i = 0, count = 0. count != 0 ? -- нет. Выход из цикла.
[User Picture]
From:m_greg_1975
Date:February 1st, 2005 11:35 am (UTC)
(Link)
Ну, это то я понял. Просто у меня была мысль, что i++ на MaxInt вызовет ошибку.
[User Picture]
From:d_byzero
Date:February 1st, 2005 11:47 am (UTC)
(Link)
Ну, по крайней мере, под моим линухом ошибки нет.
[User Picture]
From:zloy_homyak
Date:February 1st, 2005 11:38 am (UTC)
(Link)
хмм, логика конечно в этом есть, но, как вы верно заметили, выглядит спессфисски :-))
т.е. именно в качестве иллюстрации для изучающих язык я бы этот код и использовал - типа "когда организовываешь цикл, думай об overrun"
читабельность кода на мой взгляд падает.
[User Picture]
From:d_byzero
Date:February 1st, 2005 11:46 am (UTC)
(Link)
Только не первым, а последним. Иначе ты получаешь сдвиг индекса на 1.
[User Picture]
From:dgemima
Date:February 2nd, 2005 07:23 am (UTC)
(Link)
Пример конечно показательный.... Вот только вопрос: сколько раз читающим это программистам за всю их карьеру приходилось писать циклы, которые могут достигать максимального целого значения для используемого типа? Кроме того, приведенный пример изначально написан не по Сишному, потому что стандартный Сишный цикл выглядит так:

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

Как видите, сравнение на "строго меньше", поэтому описанный глюк с MAX_INT невозможен.
[User Picture]
From:d_byzero
Date:February 2nd, 2005 08:14 am (UTC)
(Link)
Во-первых, в том примере достижение максимума действиельно могло быть (правда, только если int 16-битный).
Во-вторых, в твоем примере i будет только счетчиком повторений. Соответственно, если в теле цикла нужно многократно использовать что-то типа first + i, то под это стоит завести лишнюю переменную. И, наконец, мой пример именно "сишный", а твой -- "сиплюсплюсный", поскольку в простом C нельзя писать for (int i....) :-)

Powered by LiveJournal.com