While 1 что означает

от admin

Цикл while

Если тело цикла состоит из одного оператора, то цикл, также как и if , можно записать в одну строчку:

Но так лучше не писать из стилистических соображений.

Как он выполняется:

  • Вычисляется значение выражения ‹условие› .
  • Если условие ложное, цикл прерывается, ‹тело цикла› ни разу не выполняется.
  • Если условие истинноое, выполняется ‹тело цикла› .
  • И потом снова вычисляется ‹условие› .
  • Если оно ложное — цикл прерывается, если истинное, снова выполняется ‹тело цикла› .
  • И так далее.

Т.е. пока значение ‹условия› истинное, поочерёдно вычисляется ‹условие› и выполняется тело цикла.

Блок либо выполнится, либо не выполнится.

Блок может выполняться много раз.

Итерация — однократное выполнение тела цикла.

Пример. Просуммировать все числа от 1 до 100.

В переменной i находится очередное число. В начале оно равно 1 , затем на каждой итерации (проходе, витке) цикла оно увеличивается на 1 . В результате на первом витке i равно 1 , на втором — i равно 2 и т.д. Таким образом, в переменной i на входе в цикл находится номер текущей итерации.

Переменная sum изначально равна нулю, на каждом витке цикла её содержимое увеличивается на номер этой итерации цикла (значение переменной i ). В итоге, значение переменной sum после завершения цикла увеличится на сумму чисел от 1 до 100. Начальным её значением было число 0 , поэтому после завершения цикла в ней будет сумма чисел от 0 до 100.

Этот цикл обязательно завершится, т.к. до начала цикла переменная i хранила значение меньше 100 , на каждом проходе цикла переменная i увеличивается и поэтому рано или поздно превысит 100 — условие i <= 100 станет ложным и цикл прервётся.

Этот пример можно записать компактнее:

Здесь мы использовали сокращённую запись операторов присваивания. Вспомним, что запись вида

7.7 – Введение в циклы и инструкции while

А теперь начинается самое интересное – в следующем наборе уроков мы пройдемся по циклам. Циклы – это конструкции управления порядком выполнения программы, которые позволяют фрагменту кода многократно выполняться до тех пор, пока не будет выполнено какое-либо условие. Циклы добавляют в ваш набор инструментов программирования значительную гибкость, позволяя делать многие вещи, которые в противном случае были бы сложными.

Например, предположим, что вы хотите вывести все числа от 1 до 10. Без циклов вы можете попробовать что-то вроде этого:

Хотя это выполнимо, но всё усложняется, когда вы хотите напечатать больше чисел: что, если вы хотите напечатать все числа от 1 до 1000? А это совсем немного! Но такую программу возможно написать, потому что во время компиляции мы знаем, сколько чисел мы хотим напечатать.

Теперь давайте немного изменим требования. Что, если бы мы хотели попросить пользователя ввести число, а затем распечатать все числа от 1 до числа, введенного пользователем? Число, которое введет пользователь, неизвестно во время компиляции. Итак, как мы можем решить эту проблему?

Инструкции while

Инструкция while (также называемая циклом while ) является самым простым из трех типов циклов, предоставляемых C++, и имеет определение, очень похожее на определение оператора if :

Инструкция while объявляется с помощью ключевого слова while . При выполнении инструкции while вычисляется условие. Если условие истинно, выполняется связанная инструкция.

Однако, в отличие от оператора if , после завершения выполнения инструкции управление возвращается в начало оператора while , и процесс повторяется. Это означает, что оператор while будет продолжать цикл до тех пор, пока условие будет истинным.

Давайте посмотрим на простой цикл while , который выводит все числа от 1 до 10:

Эта программа выводит:

Давайте подробнее рассмотрим, что делает эта программа. Сначала счетчик count инициализируется значением 1, которое является первым числом, которое мы напечатаем. Условие count <= 10 истинно, поэтому инструкция выполняется. В этом случае наша инструкция – это блок, поэтому все инструкции в этом блоке будут выполнены. Первая инструкция в блоке печатает 1 и пробел, а вторая увеличивает count до 2. Теперь управление возвращается к началу оператора while , и снова вычисляется условие. 2 <= 10 вычисляется как true , поэтому блок кода выполняется снова. Цикл будет повторяться до тех пор, пока count не станет равен 11, после чего значение 11 <= 10 будет ложным, и инструкция, связанная с циклом, будет пропущена. На этом выполнение цикла заканчивается.

Хотя эта программа представляет собой немного больше кода, чем набор всех чисел от 1 до 10, подумайте, насколько легко было бы изменить эту программу для печати всех чисел от 1 до 1000: всё, что вам нужно сделать, это изменить count <= 10 на count <= 1000 .

Инструкции while , которые изначально вычисляются как ложные

Обратите внимание, что если условие изначально вычисляется как ложное, связанная инструкция не будет выполняться вообще. Рассмотрим следующую программу:

Условие 15 <= 10 вычисляется как false , поэтому связанная инструкция пропускается. Программа продолжается, и единственное, что будет напечатано – это « done! ».

Бесконечные циклы

И наоборот, если условное выражение всегда истинно, цикл while будет выполняться вечно. Это называется бесконечным циклом. Вот пример бесконечного цикла:

Поскольку в этой программе count никогда не увеличивается, условие count <= 10 всегда будет истинным. Следовательно, цикл никогда не завершится, и программа будет печатать « 1 1 1 1 1 » . всегда.

Преднамеренные бесконечные циклы

Мы можем намеренно объявить бесконечный цикл следующим образом:

Единственный способ выйти из бесконечного цикла – использовать инструкцию return , инструкцию break , инструкцию exit , инструкцию goto , сгенерировать исключение, или пользователю убить программу.

Вот глупый пример, демонстрирующий это:

Эта программа будет непрерывно повторяться до тех пор, пока пользователь не введет n в качестве входных данных, после чего оператор if вычислит значение true ,и связанный с ним return 0; вызовет выход из функции main() , завершив программу.

Такой цикл часто можно увидеть в приложениях веб-серверов, которые работают непрерывно и обслуживают веб-запросы.

Лучшая практика

Для преднамеренных бесконечных циклов используйте while (true) .

Переменные цикла

Часто нам нужно, чтобы цикл выполнялся определенное количество раз. Для этого обычно используется переменная цикла, часто называемая счетчиком. Переменная цикла – это целочисленное значение, которое используется для подсчета количества выполнений цикла. В приведенных выше примерах переменной цикла является переменная count .

Переменным цикла часто дают простые имена, такие как i , j или k . Однако если вы хотите знать, где в вашей программе используется переменная цикла, и вы используете функцию поиска по i , j или k , функция поиска вернет половину вашей программы! По этой причине некоторые разработчики предпочитают использовать такие имена переменных цикла, как iii , jjj или kkk . Поскольку эти имена более уникальны, это значительно упрощает поиск переменных цикла и помогает им выделяться как переменные цикла. Еще лучше – использовать «настоящие» имена переменных, такие как count , или имя, которое дает более подробную информацию о том, что вы подсчитываете (например, userCount ).

Переменные цикла должны быть со знаком

Переменные цикла почти всегда должны быть со знаком, поскольку целые числа без знака могут привести к неожиданным проблемам. Рассмотрим следующий код:

Читать:
Как добавить макрос на панель быстрого доступа excel

Взгляните на приведенный выше пример и посмотрите, сможете ли вы обнаружить ошибку. Она не очень очевидна.

Оказывается, эта программа представляет собой бесконечный цикл. Она начинается, как и предполагалось, с печати 10 9 8 7 6 5 4 3 2 1 blastoff! , но затем сходит с рельсов и начинает обратный отсчет с 4294967295 . Почему? Потому что условие цикла count >= 0 никогда не будет ложным! Когда count равен 0, условие 0 >= 0 истинно. Затем выполняется —count , и count переходит к 4294967295 (предполагается, что int занимает 32 бита). И поскольку 4294967295 >= 0 истинно, программа продолжается. Поскольку count не имеет знака, он никогда не может быть отрицательным, а поскольку он никогда не может быть отрицательным, цикл не завершится.

Лучшая практика

Переменные цикла должны иметь тип ( signed ) int .

Выполнение чего-то при каждой N-ой итерации

Каждый раз, когда цикл выполняется, это называется итерацией.

Часто мы хотим делать что-то на каждой 2-й, 3-й или 4-й итерации, например, выводить символ новой строки. Это легко сделать с помощью оператора взятия остатка от деления для нашего счетчика:

Эта программа дает следующий результат:

Вложенные циклы

Циклы также возможно вкладывать внутрь других циклов. В следующем примере внутренний и внешний циклы имеют свои собственные счетчики. Однако обратите внимание, что условное выражение внутреннего цикла также использует счетчик внешнего цикла!

Эта программа печатает:

Небольшой тест

Вопрос 1

Почему в приведенной выше программе переменная inner объявляется внутри блока while , а не сразу после объявления outer ?

Переменная inner объявляется внутри блока while , поэтому она создается (и повторно инициализируется значением 1) каждый раз при выполнении внешнего цикла. Если бы переменная inner была объявлена перед внешним циклом while , ее значение никогда не было бы сброшено до 1, или нам пришлось бы делать это с помощью оператора присваивания. Кроме того, поскольку переменная inner используется только внутри блока внешнего цикла while , имеет смысл объявить ее там. Помните, что мы объявляем переменные в минимально возможной области видимости!

Вопрос 2

Напишите программу, которая печатает буквы от a до z вместе с их кодами ASCII.

Чтобы напечатать символы как целые числа, вы должны использовать static_cast .

Цикл с предусловием WHILE¶

Этот вид оператора цикла называют цикл с предусловием.

../../../_images/06_02.png ../../../_images/06_03.png

Пример_WHILE01:

../../../_images/06_04.png

Пример_WHILE02: Суммирование произвольных чисел, больших 0, вводимых склавиатуы. Выполнение суммирование должно прерваться при вводе отрицательного значения.

Для выхода из бесконечного цикла (условие true никогда не станет false) используется оператор break

Пример_WHILE03: Вывести на экран таблицу значений функции.

../../../_images/06_05.png

Вывод осуществить в два столбца

../../../_images/lec_while_03.png

Листинг WHILE03

Пример_WHILE04: Составить программу для вычисления зачения функции.

../../../_images/06_06.png

Математическая модель

Необходимо составить рекуррентную формулу, в которой каждый последующий член ряда вычисляется при помощи предыдущего. Из формулы видно, что шаг изменения знаменателя равен 2. (1!, 3!,5!,…). Обозначим nm! — знаменатель m-го члена ряда, имеем:

Purpose of while(1); statement in C

What purpose does while(1); serve ? I am aware while(1) (no semicolon) loops infinitely and is similar to a spinlock situation. However I do not see where while(1); could be used ?

Sample code

Note: This is not a case of do — while() or plain while(1) .

12 Answers 12

Please note that all valid statements of the language do not have to serve a purpose. They are valid per the grammar of the language. One can build many similar «useless» statements, such as if (1); . I see such statements as the conjunction of a conditional ( if , while , etc.) and the empty statement ; (which is also a valid statement although it obviously serves no specific purpose).

That being said, I encountered while (1); in security code. When the user does something very bad with an embedded device, it can be good to block them from trying anything else. With while (1); , we can unconditionally block a device until an accredited operator manually reboots it.

while(1); can also be part of the implementation of a kernel panic, although a for(;;) <> loop seems to be a more common way of expressing the infinite loop, and there might be a non-empty body (for instance to panic_blink() ).

If you dig down to assembly, (this is easier to grasp from an embedded systems point of view, or if you tried to program a bootloader)

you will realize that a while loop is just a jmp instruction . ie

Lets explain how this works, the processor will keep executing instructions sequentially . no matter what. So the moment it enters this loop it will add register bx to ax and store in ax, add register cx to ax and store to ax, cmp ax, dx (this means subtract dx from ax) the jz instruction means jump to (another address location) if the zero flag is set (which is a bit in the flag register that will be set if the result of the above subtraction is zero), then jmp to starting loop address (pretty straight forward) and redo the whole thing.

The reason I bothered you with all this assembly is to show you that this would translate in C to

So imagine the senario in assembly if you just had a very long list of instructions that didn’t end with a jmp (the while loop) to repeat some section or load a new program or do something . Eventually the processor will reach the last instruction and then load the following instruction to find nothing (it will then freeze or triple fault or something).

That is exactly why, when you want the program to do nothing until an event is triggered, you have to use a while(1) loop, so that the processor keeps jumping in its place and not reach that empty instruction address. When the event is triggered, it jumps to the event handler instructions address, executes it, clears the interrupt and goes back to your while(1) loop just jumping in its place awaiting further interrupts. Btw the while(1) is called a superloop if you want to read more about it . Just for whoever that is insanely itching to argue and comment negatively at this point, this is not an assembly tutorial or a lecture or anything. It’s just plain English explanation that is as simple as possible, overlooking a lot of underlying details like pointers and stacks and whatnot and at some instance over simplifying things to get a point across. No one is looking for documentation accuracy over here and I know this C code won’t compile like this, but this is only for Demo !!

Похожие статьи