Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
#1

Как корректно прервать цикл? (нюансы использования циклов, операторов ветвления и оператора break) - C++

10.01.2016, 22:05. Просмотров 1151. Ответов 36
Метки нет (Все метки)

Здравствуйте!
такая форма работает...цикл нормально прерывается
C++
1
2
3
4
for(double i=1; i<=10; i++){
        if(i==8)
        break;
        std::cout<<i;}
а так игнорирует break...
C++
1
2
3
4
for(double i=1.0; i<=10.3; i++){
        if(i==8.1)
        break;
        std::cout<<i;}
Подскажите пожалуйста в чем проблема?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2016, 22:05
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Как корректно прервать цикл? (нюансы использования циклов, операторов ветвления и оператора break) (C++):

Как корректно прервать цикл?
Вот цикл.Я спрашиваю &quot;Добавить еще?&quot;,пользователь жмет y или n и у меня сразу...

Нюансы использования операторов new/delete в деструкторах
Подскажите пожалуйста, в чем проблема у меня в деструкторах? Есть 3...

Нюансы использования оператора sizeof()
Пусть T - это некоторой тип, а t - это переменная типа T. Может ли...

Нюансы использования оператора запятая или что такое UB и с чем его едят
Почему студия и ideone выдают разные значения для a и b? в студии выходит a...

Нюансы работы с оператором ветвления if else: почему программа ведёт себя не так, как ожидается?
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; void...

Нюансы работы с оператором ветвления if else: почему программа ведёт себя не так, как ожидается?
Имеется код: int a; char q; for (;;) { cout &lt;&lt; &quot;Введите число: &quot;; ...

36
Perfilov
264 / 164 / 56
Регистрация: 25.02.2015
Сообщений: 435
10.01.2016, 22:09 #2
Лучший ответ Сообщение было отмечено vikiroy как решение

Решение

поменяйте условие: if(i==8.1)
у вас оно никогда не выполнится, т.к. i++ - это нарашивание на еденицу.
кроме этого, double числа вот так опасно сравнивать из-за особенности представления этих самых чисел. они могут отличатся в черт знает каком знаке после запятой. типа 8.10000000000001 != 8.1
1
yrceus
82 / 82 / 80
Регистрация: 25.08.2013
Сообщений: 330
10.01.2016, 22:10 #3
Лучший ответ Сообщение было отмечено vikiroy как решение

Решение

Переменная i не попадает на 8.1 (i не становится равна 8.1). Инкремент прибавляет же единицу.
1
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
10.01.2016, 22:18  [ТС] #4
Спасибо! ну а если так делать не рекомендуется вообще, как мне быть к примеру если надо остановить число зацикленное вычисление числа пи на определенном этапе?...ну когда оно к примеру 3.14159....и так далее...

Добавлено через 2 минуты
перефразирую вопрос...как мне элегантно прервать бесконечный цикл числа с плавающей точкой?
0
Даценд
Модератор
Эксперт .NET
4044 / 3884 / 2573
Регистрация: 20.04.2015
Сообщений: 7,060
10.01.2016, 22:22 #5
Цитата Сообщение от vikiroy Посмотреть сообщение
как мне элегантно прервать бесконечный цикл числа с плавающей точкой?
C++
1
2
if(abs(i - 8.1) < 1E-7)
   break;
1
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
10.01.2016, 22:26  [ТС] #6
Спасибо! А как без функций?...
0
yrceus
82 / 82 / 80
Регистрация: 25.08.2013
Сообщений: 330
10.01.2016, 22:33 #7
Лучший ответ Сообщение было отмечено vikiroy как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
int main()
{
    double i;
    for (i = 1.0; i < 10.3; i += 0.1)
        if (i > 8.09 && i < 8.11)
            break;
    std::cout << i << std::endl;
    return 0;
}
С областью примерного попадания.
А правда, возможно ли double заставить соблюдать точность? Чтоб если 8.1, то 8.100000000000000...
1
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
10.01.2016, 22:48  [ТС] #8
Да! Спасибо!, наверное это оно! А по поводу точности и дробей - можно ли соблюдать точность , вопрос конечно имеет смысл, но довольно философского характера, по-большей части точность везде может соблюдаться!) просто отсекается все не нужное(лишнее) и получаем точность!

Добавлено через 5 минут
Кстати не работает с областью примерного попадания(

Добавлено через 2 минуты
Есть еще у кого варианты?
0
Perfilov
264 / 164 / 56
Регистрация: 25.02.2015
Сообщений: 435
10.01.2016, 22:57 #9
в каком месте не работает?
тут например ок: http://ideone.com/zdCZQe
0
yrceus
82 / 82 / 80
Регистрация: 25.08.2013
Сообщений: 330
10.01.2016, 23:12 #10
Возможно в другом диапазоне не работает) Можно попробовать вот так уточнить.
C++
1
2
3
    long double i;
    for (i = 1.0L; i < 10.3L; i += 0.1L)
        if (i > 8.09L && i < 8.11L)
1
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 21:47  [ТС] #11
с обычными числами с плавающей точкой работает! С числом пи, скорее всего нужно прописывать очень большое количество разрядов, там тысячи знаков, чтоб в точку попасть))) Спасибо!
0
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 22:00  [ТС] #12
Здравствуйте! Есть такой типа код...
где лучше, правильнее влепить
C++
1
2
if(salary==-1)
    break;
в самом while или в switch? оно работает что так что этак, но как нужно?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
while(salary!=-1)
    {
    std::cout<<"Ââåäèòå Г*îìåð Г°Г*áî÷åé ãðóïïû(1-ìåГ*åäæåð, 2-ïî÷Г*ñîâûå Г°Г*áîòГ*ГЁГЄГЁ, 3-êîìèññèîГ*Г№ГЁГЄГЁ, 4-ñäåëüùèêè): ";
    std::cin>>salary;
    if(salary==-1)
    break;
    switch(salary)
    {
        case 1:
            {
            std::cout<<"ÎÒÄÅË ÌÅÍÅÄÆÅÐÛ";
            std::cout<<std::endl;
            std::cout<<"ÔèêñèðîâГ*Г*Г*ûé Г*åäåëüГ*ûé îêëГ*Г¤.";
            std::cout<<std::endl;
            numberOfHoursWorked=800;
            std::cout<<"$"<<numberOfHoursWorked;
            }
            break;
        case 2:{
            std::cout<<"ÃðóïïГ* ïî÷Г*ñîâûå Г°Г*áî÷èå";
            std::cout<<std::endl;
                while(numberOfHoursWorked!=-1)
                {
                    numberOfHoursWorked=1;
                std::cout<<"Ââåäèòå êîëè÷åñòâî îòðГ*áîòГ*Г*Г*ûõ Г·Г*ñîâ(-1 äëÿ âûõîäГ*): ";
                std::cin>>numberOfHoursWorked;
                    if(numberOfHoursWorked<=40)
                    {
                    numberOfHoursWorked*=5;
                    std::cout<<numberOfHoursWorked;
                    }
                    if(numberOfHoursWorked>40)
                    {
                    numberOfHoursWorked*=5;
                    numberOfHoursWorked*=5+(5/2);
                    std::cout<<numberOfHoursWorked;}
                }
            }
            break;
        default:
            {
                //if(salary==-1)
                //break;
                //else
                //{
                std::cout<<"ГЌГҐГЇГ°Г*âèëüГ*ûé ââîä!";
                std::cout<<std::endl;
                //}
            }
    }
    }
//------------------------------------------------------------------
    return 0;
}
0
Даценд
Модератор
Эксперт .NET
4044 / 3884 / 2573
Регистрация: 20.04.2015
Сообщений: 7,060
11.01.2016, 22:09 #13
Цитата Сообщение от vikiroy Посмотреть сообщение
С числом пи, скорее всего нужно прописывать очень большое количество разрядов, там тысячи знаков, чтоб в точку попасть)))
При таких циклических вычислениях хранится предыдущее значение (неважно чего: корня уравнения, значения интеграла, числа Пи) и текущее значение. Цикл прерывается, когда разница между этими значениями становится меньше заданной точности.
Примерно так, как я показывал в сообщении #5:
C++
1
2
if (abs(pi1-pi2)<1E-10) //с точностью до 0.0000000001
   break;
Но чаще всего используются другие циклы - while и do...while:
C++
1
2
3
4
5
6
7
8
do
{
   pi1=pi2;
   //меняем параметры вычисления pi2
   pi2=...
}
while (abs(pi1-pi2)>1E-10);
cout << pi2;
И без функции abs сложно это реализовать.
Хотя можно так:
C++
1
2
3
4
5
6
7
8
9
do
{
   pi1=pi2;
   //меняем параметры вычисления pi2
   pi2=...
   d=(pi1>=pi2)?pi1-pi2:pi2-pi1;
}
while (d>1E-10);
cout << pi2;
2
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 22:22  [ТС] #14
Я Вас понял!, спасибо вам большое! ну а, почему спрашивал чтоб без функции, просто по книге функции как-бы еще не учил, но сказано что обычными приемами логических операций и циклов можно все-равно решить любую задачу, хотя некоторые вещи очень сложно, ну вот и решал упражнение

А вот есть ещё такой код...
где лучше, правильнее влепить
C++
1
2
if(salary==-1)
    break;
в самом while или в switch? оно работает что так что этак, но как нужно?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
while(salary!=-1)
    {
    std::cout<<"Ââåäèòå Г*îìåð Г°Г*áî÷åé ãðóïïû(1-ìåГ*åäæåð, 2-ïî÷Г*ñîâûå Г°Г*áîòГ*ГЁГЄГЁ, 3-êîìèññèîГ*Г№ГЁГЄГЁ, 4-ñäåëüùèêè): ";
    std::cin>>salary;
    if(salary==-1)
    break;
    switch(salary)
    {
        case 1:
            {
            std::cout<<"ÎÒÄÅË ÌÅÍÅÄÆÅÐÛ";
            std::cout<<std::endl;
            std::cout<<"ÔèêñèðîâГ*Г*Г*ûé Г*åäåëüГ*ûé îêëГ*Г¤.";
            std::cout<<std::endl;
            numberOfHoursWorked=800;
            std::cout<<"$"<<numberOfHoursWorked;
            }
            break;
        case 2:{
            std::cout<<"ÃðóïïГ* ïî÷Г*ñîâûå Г°Г*áî÷èå";
            std::cout<<std::endl;
                while(numberOfHoursWorked!=-1)
                {
                    numberOfHoursWorked=1;
                std::cout<<"Ââåäèòå êîëè÷åñòâî îòðГ*áîòГ*Г*Г*ûõ Г·Г*ñîâ(-1 äëÿ âûõîäГ*): ";
                std::cin>>numberOfHoursWorked;
                    if(numberOfHoursWorked<=40)
                    {
                    numberOfHoursWorked*=5;
                    std::cout<<numberOfHoursWorked;
                    }
                    if(numberOfHoursWorked>40)
                    {
                    numberOfHoursWorked*=5;
                    numberOfHoursWorked*=5+(5/2);
                    std::cout<<numberOfHoursWorked;}
                }
            }
            break;
        default:
            {
                //if(salary==-1)
                //break;
                //else
                //{
                std::cout<<"ГЌГҐГЇГ°Г*âèëüГ*ûé ââîä!";
                std::cout<<std::endl;
                //}
            }
    }
    }
//------------------------------------------------------------------
    return 0;
}
0
Perfilov
264 / 164 / 56
Регистрация: 25.02.2015
Сообщений: 435
11.01.2016, 22:31 #15
оно работает потому что вам повезло. брейк из кейса - это брейк из свитча, от этого цикл не прерывается. он у вас прерывается потому, что в while еще проверка стоит. правильно ставить сразу после ввода вашего значения, так много понятнее читающему, при каких там условиях цикл завершается. ну и while в этом случае без условий. бесконечный. так тоже будет понятнее опытному читающему.
0
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 22:37  [ТС] #16
Спасибо! очень четкий ответ! все понятно!

Добавлено через 3 минуты
...еще такой вопрос как дополнение можно? вот по условию
C++
1
while(i!=-1){..........}
Почему нужно вставлять после этого
C++
1
if(i==-1)break
? Ведь и так вроде должен заканчиваться цикл если будет -1???
0
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 22:37  [ТС] #17
Да я вставил, потому-что бывали случаи когда почему-то while(i!=-1) не срабатывало, я до сих пор не понимаю почему

Добавлено через 3 минуты
а сейчас я скажу зачем тут вставил, если без
C++
1
if(i==-1)
то после нажатия -1
C++
1
while
конечно прерывается, но и одновременно вылазит исключение из
C++
1
default
!
0
Perfilov
264 / 164 / 56
Регистрация: 25.02.2015
Сообщений: 435
11.01.2016, 22:37 #18
Кто вам сказал что нужно? Вообще, вы вставили зачем-то вот сами и отвечайте, зачем так сделали, если это вроде бы и не нужно.
Зависит от конкретного случая. покажите код, тогда будет понятнее почему там у вас что-то не работало.
0
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
11.01.2016, 22:43  [ТС] #19
а сейчас я скажу зачем тут вставил, если без
if(i==-1)
то после нажатия -1
while
конечно прерывается, но и одновременно вылазит исключение из
default
!

вот как раз на примере этого кода оно и получается так

Добавлено через 4 минуты
получается в
C++
1
default
нужно поместить или в
C++
1
while
C++
1
if(i==-1)break
0
vikiroy
13 / 5 / 3
Регистрация: 30.11.2015
Сообщений: 170
12.01.2016, 00:02  [ТС] #20
И ещё раз, здравствуйте!

У меня первые шаги в программировании...ниже код где я создал цикл в
C++
1
switch
в
C++
1
case: 2
чтоб выйти из него нужно ввести -1, но чтоб потом опять войти в
C++
1
case: 2
мне пришлось обнулить переменную
C++
1
numberOfHoursWorked=0
и записать ее перед
C++
1
switch
оно конечно все работает, но иногда мне кажется что чтоб добиться нужного результата приходиться извращать код,
вопрос такой это я действительно по незнанию его извращаю или так и должно быть? если есть более правильный способ это сделать какой?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
while(salary!=-1)
    {
    std::cout<<"Ââåäèòå Г*îìåð Г°Г*áî÷åé ãðóïïû(1-ìåГ*åäæåð, 2-ïî÷Г*ñîâûå Г°Г*áîòГ*ГЁГЄГЁ, 3-êîìèññèîГ*Г№ГЁГЄГЁ, 4-ñäåëüùèêè): ";
    std::cin>>salary;
    numberOfHoursWorked=0;
    switch(salary)
    {
        case 1:
            {
            std::cout<<"ÎÒÄÅË ÌÅÍÅÄÆÅÐÛ";
            std::cout<<std::endl;
            std::cout<<"ÔèêñèðîâГ*Г*Г*ûé Г*åäåëüГ*ûé îêëГ*Г¤.";
            std::cout<<std::endl;
            numberOfHoursWorked=800;
            std::cout<<"$"<<numberOfHoursWorked;
            }
            break;
        case 2:
            {
                std::cout<<"ÃðóïïГ* ïî÷Г*ñîâûå Г°Г*áî÷èå";
                while(numberOfHoursWorked!=-1)
                {
                std::cout<<std::endl;
                std::cin>>numberOfHoursWorked;
                }
            }
            break;
        default:
            {
                if(salary==-1)
                break;
                else
                {
                std::cout<<"ГЌГҐГЇГ°Г*âèëüГ*ûé ââîä!";
                std::cout<<std::endl;
                }
            }
    }
    }
0
12.01.2016, 00:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.01.2016, 00:02
Привет! Вот еще темы с решениями:

Задача с использованием логических операторов и операторов ветвления
Вот вам задачка, чтоб голову поломать :D Вася работает программистом и...

Оператор break выходит из цикла и ветвления?
Например код: for(int j=0; j&lt;10; j++) { if(j&lt;10) cout&lt;&lt;&quot;Выход!&quot;;break;...

Нюансы синтаксиса: как сравнить каждый элемент массива с переменной в условии оператора if ?
Привет всем дорогие друзья с толкнулся с такой проблемой, начал ходить на...

Как прервать цикл используя условия ?
Есть цикл for(double i=1;i&lt;=?;i++) { s+=pow(((2*i)+1),4.0); }Мне...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru