Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/23: Рейтинг темы: голосов - 23, средняя оценка - 4.78
Гость

не использовать do/while ? бред !

27.08.2007, 13:12. Показов 4542. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
меня возмутила статья
http://www.cyberguru.ru/progra... age67.html
в которой автор рекомендует вместо do {} while (); использовать while () {};
давайте же разберёмся что происходит на самом деле

do { действия } while ( условие );
если это разложить по косточкам выходит следующее
Code
1
2
3
метка:
действия
if (!условие) goto метка
итак на цикл одна метка и на каждую итерацию один прыжок

while ( условие ) { действия };
разложим и это
Code
1
2
3
4
5
метка1:
if (!условие) goto метка2
действия
goto метка1
метка2:
две метки и на 1 больше прыжок, чем в do {} while ();
p.s. если кто сомневается что он устроен именно так вспомните, что возможно while (действие перед каждой проверкой, проверка) { действие };

и ещё разсмотрим конструкцию if (условие) { do { } while (); }; которая особо не понравилась автору, что меня вообще добило хех
Code
1
2
3
4
5
if (!условие) goto метка1
метка2:
действия
if (условие) goto метка2
метка1:
хорошо теперь возьмём массив major размером 4 и заполним его единицами

для do { } while ( ) ;
Code
1
2
3
4
5
int major[4], it (0);
do {
    major[it] = 1;
    ++it;
} while (it < 4);
прошли при it == 0, проверили, прыгнули
прошли при it == 1, проверили, прыгнули
прошли при it == 2, проверили, прыгнули
прошли при it == 3, проверили
всё
действий 4
проверок 4
прыжков 3






для while ( ) { };
Code
1
2
3
4
5
int major[4], it (0);
while (it < 4) {
    major[it] = 1;
++it;
};
проверили, прошли при it == 0, прыгнули
проверили, прошли при it == 1 прыгнули
проверили, прошли при it == 2 прыгнули
проверили, прошли при it == 3 прыгнули
проверили, прыгнули
всё
действий 4
проверок 5
прыжков 6

конструкция if (условие) { do { } while (); };
Code
1
2
3
4
5
6
7
int major[4], it(0);
if (it < 4) {
    do {
        major[it] = 1;
        ++it;
    } while (it < 4);
};
проверили
прошли при it == 0, проверили, прыгнули
прошли при it == 1, проверили, прыгнули
прошли при it == 2, проверили, прыгнули
прошли при it == 3, проверили
всё
действий 4
проверок 5
прыжков 3

я считаю исходя из выше перечисленного что
if (условие) { do { } while (); }; эффективнее while ( ) { }; и именно по этому заявление автора статьи меня так возмутило, он хоть бы попытался чем-то это аргументировать ...
если я где-то ошибся прошу это указать, может я в чём-то и не прав
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.08.2007, 13:12
Ответы с готовыми решениями:

Бред
Захожу сегодня в статистику на один из сайтов, и смотрю что на сайт зашли по запросу &quot;******** проститутки&quot; аж 3 человека. Ввожу...

Бред с ГД
Написал функцию function cap() { session_start(); header('content-type: image/jpeg'); $img = imagecreatetruecolor(60,15); ...

С# и бред на С++
Ребят, гляньте задачку. Нашел вариант решения её на С++(походу не правильный), но не получается сделать её на С#, помогите пожалуйста, а...

3
118 / 12 / 3
Регистрация: 21.08.2007
Сообщений: 222
27.08.2007, 19:02
it (0)
По всей видимости опечатка, т.к. нужно it = 0

Теперь к делу:
C++
1
2
3
4
5
int major[4], it (0);
do {
    major[it] = 1;
    ++it;
} while ( it < 4 );
Плохой код. Для таких дел есть цикл for():
C++
1
for( it = 0; it < 4 && (major[it] = 1); ++it );
Результат тот же, но повышается удобочитаемость, т.к. все операторы инициализации и вся управляющая информация локализована в одном месте. Конечно, код, инициализирующий четыре элемента массива достаточно удобочитаем и при использовании цикла do - while, ну а если он разрастётся в что-то серьёзное? Проблема цикла do в том, что программист, увидев блок операторов цикла, не знает условий, при которых цикл должен закончиться(ну если цикл не 4 строчки, как в нашем случае). Это затрудняет читаемость кода.

Теперь конкретно ко времени исполнения программы(ну, предварительно, заставим исполняться этот код 10000000 раз):
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main( void ) {
 
int i = 0;
int major[4];
int j = 0;
do {
 
do {
    major[i++] = 1;
        } while ( i < 4 );
++j;
        } while( j < 10000000 );
Такой код исполняется у меня на системе 0.200 сек

Теперь мой вариант(результат тот же):
C++
1
2
3
4
5
6
7
8
9
10
int main( void ) {
 
int j = 0;
int major[4], i = 0;
 
for( ; j < 10000000; ++j ) {
 
    for( ; i < 4 && ( major[i] = 1 ); ++i );
        
}
Такой код исполняется 0.040сек, т.е. в 5 раз быстрее. (Надо сказать, что если инициализацию переменных поместить в заголовки for(), код выполняется 0.250сек - что вполне логично - в цикле лишние присваивания). Тест проводился на компиляторе gcc-4.1.2 с уровнем оптимизации 0.

Что, касается цикла while, то всё вышесказанное применимо и к нему, т.к. его отличие лишь в том, что условие проверяется сразу => цикл может быть не выполнен ни разу.

Что касается if () do {} while() - вообще глупо и неоптимально, т.к. сразу в таком коде
C++
1
2
3
4
5
6
if ( it < 4 ) {
    do {
        major[it] = 1;
        ++it;
    } while ( it < 4 );
};
налицо избыточность - двойная проверка.

Резюмируя вышесказанное, применение цикла for() выгоднее в данных случаях и с точки зрения быстродействия, и с точки зрения удобочитаемости.

Что касается статьи, то автор скорее всего хотел сказать, что в программировании нечасто встречаются ситуации, в которых использование циклов do-while является самым оптимальным решением. Но это не значит, что их нельзя использовать!

P.S. Ну всё, что я тут нагородил, конечно, результат моих собственных изысканий и не является аксиомой.
0
Гость
28.08.2007, 00:11
да этот ответ меня действительно поразил на некоторое время, а именно проверка указанных тестов, спасибо
кстати it (0) это выполнение конструктора при инициализации, раз Вы пользуетесь компилятором gcc, то я могу сделать предположение что в C нету конструкторов из за отсутствия классов (если я не ошибаюсь) - далее я использую компилятор g++ 4.1.2 и чтож пусть будет it = 0, теперь к делу )

меня действительно поразило то, что указанные времена почти совпали, но я не мог понять как такое может быть, если цикл for это тот же while только с другим синтаксисом

сразу замечу что зачастую я выбираю цикл while если ситуация того требует, а не if { do { } while (); }; , но если я пишу программу не спеша я её маниакально пытаюсь ускорить во времени но в любом случае в первую очередь - выше скорости стоит чёткая и стабильная робота программы, и я никогда бы не написал бы так
C++
1
for( it = 0; [b]it < 4 && (major[it] = 1)[/b]; ++it );
что выполниться первым ? 4 И то что в скобках или сравнение с it ? несмотря на что, что якобы это можно определить по приоритетам операций я всегда стараюсь такого избегать после всех испытанных различий компиляторов в таких тонких моментах

и ещё - в первом варианте инкремент i постфиксный, в другом префиксный, по моему мнению префиксный инкремент лучше - он быстрее и возвращает указатель, потому использую его

затем мне бросилось в глаза вот что - после итераций в внутреннем цикле Вы не онуляете переменную i - ведь далее с её помощью будет попытка доступа к несуществующим элементам 5, 6, 7 .. 39999999

таким образом я внёс некоторые правки в код - я добавил скобки к (it < 4) а также добавил онуление i, изменил i++ на ++i и как - то более структурно записал всё, иначе для меня код просто нечитабельный
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main( void ) {
   int i = 0, j = 0, major[4];
#ifdef TEST
   do {
      i = 0;
      do {
         major[i] = 1;
     ++i;
      } while ( i < 4 );
      ++j;
   } while( j < 10000000 );
#else
   for( ; j < 10000000; ++j ) {
      for( i = 0; (i < 4) && ( major[i] = 1 ); ++i );
   };
#endif
   return 0;
};
пробую теперь
g++ sol.cpp -o sol && time ./sol = 0.23s
g++ sol.cpp -o sol -D TEST && time ./sol = 0.20s

хм...
всётаки for медленнее ...
чтоже так затормозило его ? скобки или онуление i ?

ах да насчёт двойной проверки - это да, я просто хотел показать что условие копируется в обе части кода и работает структура так же как while

я конечно не спорю что это всё не актуально при олимпиадном программировании, или при написании курсовых робот, но для больших проектов ... написанный код будет выполняться миллионы раз и экономия миллисекунды даст ведь о себе знать
хехе снять розовые очки ?
118 / 12 / 3
Регистрация: 21.08.2007
Сообщений: 222
28.08.2007, 16:02
g++ sol.cpp -o sol && time ./sol = 0.23s
g++ sol.cpp -o sol -D TEST && time ./sol = 0.20s
Ну да, я забыл обнулять переменную, вследствие чего и получил результат 0.040сек - внутренний for() исполнялся всего один раз.

for() действительно медленнее - но засчёт чего, мне стало очевидно только после анализа асемблерного листинга.

Вся работа for( i = 0; i < 4 && (major[i] = 1); ++i) заключается в семи машинных командах:
Assembler
1
2
3
4
5
6
7
8
    movl    $0, -12(%ebp)                    
.L4
    cmpl    $3, -12(%ebp)                    
    [B]jg   .L5[/B]                              
    movl    -12(%ebp), %eax                
    movl    $1, -28(%ebp,%eax,4)
    incl    -12(%ebp)
    jmp .L4
Вся работа do { major[i++] = 1} while( i < 4 )заключается в шести машинных командах:
Assembler
1
2
3
4
5
6
7
           movl      $0, -12(%ebp)
.L3:
    movl    -12(%ebp), %eax
    movl    $1, -28(%ebp,%eax,4)
    incl    -12(%ebp)
    cmpl    $3, -12(%ebp)    
    jle .L3
Выводы делаем сами...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.08.2007, 16:02
Помогаю со студенческими работами здесь

какой то бред!
не могу понять что за цирк.. #include &lt;math.h&gt; #include &lt;iostream.h&gt; #include &lt;iomanip.h&gt; main() { double a,d,n; ...

бред в результате
ничего не могу понять! нужно посчитать v, для этого просим ввести пользователя h и s, в результате получается какой-то бред!!! ввожу 3 и 2,...

Бред Яндекса
Господа Профи помогите, пожалуйста, разобраться. Вот к примеру, оптимизируется страница под ключевик «магазин платьев». Вроде все по науке...

Яндекс-бред
http://images.yandex.ru/yandsearch?text=WE...amp;stype=image :P

Что за бред?
Вот у меня ноут samsung r60 plus, пару лет назад был 7 виндовс всё работало хорошо. далее накрылся виндовс поставили тоже 7 типо всё...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru