учебное пособие. Часть1. Информатика
.pdf...............
goto 1;
m: .........
goto loop;
1: ............
goto m;
3.2.6. Пример разветвляющейся программы
Дано вещественное x. Вычислить y=f(x).
f (x) = ln x x −1
При изучении поставленной задачи, приходим к выводу, что необхо-
димо определить область допустимых значений f(x): Деление на 0 может произойти при x − 1 = 0
Логарифм существует только для положительного аргумента x > 0 Схема алгоритма приведена на рис. 10, a программа − в примереpr10.
ln x x −1
Рис. 10. Алгоритм PR10
//Пример pr10 #include <iostream> #include <cmath> using namespace std; int main ()
{
float x, y;
printf ( "\n Введите x:" ); scanf ( "%f", &x);
if (x > 0) if (x != 1)
{ y = log ( x )/( x – 1 ); printf ("\n y =%7.3f", y);
}
else printf("\nДеление на 0");
else printf ("\n Логарифм не положительного числа
не существует");
return 0;
}
181
Контрольные вопросы
1.Для чего служит условный оператор?
2.Как работает условный оператор?
3.Какое значение х будет напечатано в результате работы следующей программы:
int main ()
{
float x = 1, y = 2; int a = 3, b = 4; if ( a<b )
if ( x<y )
x= x/a+ y/x +a/b;
cout<<"x="<< x; return 0;
}
4. Какие ошибки допущены в следующей программе: int main()
{ float x = 1, y = 2; int a=3, b = 4;
if (a<b) x = x+1 else
if (0 <x< y)
x=x/a+ y / x +a/b; printf( "x=%5.3f ", x);
return 0;
}
5. Для следующего фрагмента схемы алгоритма составьте фрагмент программы на языке С++:
6.Что такое истина в С++?
7.Для чего используется оператор множественного выбора?
8.Написать на языке С++ программу, определяющую большее из трех заданных вещественных чисел.
182
9.Когда используется сокращенная форма условного оператора?
10.Может ли условный оператор быть вложенным в другой условный оператор?
11.Сколько операторов может выполняться в ветви else условного оператора?
3.3.Циклические программы
К циклическим программам приводят задачи, в которых часть действий выполняется многократно.
Пусть необходимо протабулировать функцию F(x) на интервале
[a,b] c шагом h (где, F(x)=xsin(x), a<b, h>0) и вывести полученные значения функции и аргумента.
Протабулировать функцию – значит вычислить значения функции F(x) на от-
резке [a,b] в точках a, a+h, a+2h и
т.д. Графическая схема алгоритма приве- дена на рис. 11, программа – в примере pr11.
//Пример pr11 #include <cstdio> #include <cmath>
using namespace std; int main ()
{
float x, y, a, b, h; printf("\nВведите
a,b,h:"); scanf("%f%f%f",&a,&b,&h); x=a;
do
{
y=x*sin(x);
printf("\nx=%7.2f,y=%7.2f",x,y );
|
|
x=x+h; |
|
|
|
||
|
|
} |
(x<=b); |
|
|
||
|
|
while |
|
Рис. 11. Алгоритм PR11 |
return |
0; |
|
|
|
} |
|
183
В этой программе оператор цикла используется для многократного вы- полнения группы операторов, расположенных между словами do while.
Каждый раз в цикле вычисляется значение y, выводятся x и y, задается новое значение х и проверяется, не выходит ли значение х за пределы интервала. В ре- зультате работы этой программы будут напечатаны в два столбика значения x и y.
3.3.1.Оператор цикла с постусловием
Ввышеприведенном примере был использован оператор цикла с по- стусловием. Синтаксис этого оператора следующий:
do <оператор> while( <условие>)
Здесь do ,while – ключевые слова (перев. с англ.: выполнять и пока); <оператор> – любой оператор языка С++, в том числе и составной
(его называют телом цикла); <условие> – условное выражение типа сравнения, используемое для
выхода из цикла.
Оператор работает следующим образом: сначала выполняются операторы, расположенные в теле цикла, затем вычисляется условное выражение и, если по- лучается ложное значение, осуществляется выход из цикла. Если значение выра- жения истинно, то выполнение операторов тела цикла повторяется, а затем снова проверяется условие. Итак, операторы тела цикла выполняются хотя бы раз, а потом все зависит от условия выхода из цикла. Очевидно, один из операторов тела цикла должен влиять на значение условного выражения, поскольку иначе цикл будет повторяться бесконечно.
|
|
Начало |
|
|
|
//Пример pr12 |
||||
|
|
|
|
|
|
|
|
|
|
#include <cstdio> |
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
i:=1 |
|
|
|
||||
|
|
|
|
|
|
int main () |
||||
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Вывод i |
|
|
|
i=1; |
||||
|
|
|
|
|
|
|
|
|
|
do |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
i := i+2 |
|
|
|
printf ("\n%d",i); |
||||
|
|
|
|
|
|
|
|
|
|
i=i+2; |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
i > 10 |
Нет |
while (i <= 10); |
|||||
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
Да |
|
|
|
} |
Конец
Рис. 12. Алгоритм PR12
184
Проиллюстрируем использование оператора цикла с постусловием на примере, в котором выводятся нечетные числа, меньшие 10. Схема ал- горитма приведена на рис. 12, программа в примере – pr12.
Врезультате работы этой программы будут напечатаны в столбик все нечетные числа от 1 до 9.
3.3.2.Оператор цикла с предусловием
Вотличие от оператора цикла с постусловием оператор цикла с преду- словием вычисляет и проверяет условие до выполнения операторов, состав- ляющих тело цикла. Синтаксис этого оператора следующий:
while ( <условие>) <оператор>;
Здесь while – ключевое слово (перев. с англ.: пока); <оператор> – любой оператор языка C++, в том числе и составной (этот оператор называют телом цикла); <условие> – условное выражение типа сравнения, исполь- зуемое для выхода из цикла.
Оператор работает следующим образом: сначала вычисляется условное выражение и, если получается истинное значение, выполняется оператор, яв- ляющийся телом цикла, а затем снова проверяется условие. Если значение условного выражения ложно, то осуществляется выход из цикла. Таким об- разом, если условие было ложно при первом входе в цикл, то операторы тела цикла не выполнятся ни разу. Очевидно, один из операторов тела цикла дол- жен влиять на значение условного выражения, поскольку иначе цикл будет повторяться бесконечно. Например, следующий фрагмент программы будет печатать радостное сообщение бесконечное число раз, так как отсутствуют в цикле конструкции, изменяющие величину i:
i=1;
while(i<5)
printf("Доброе утро!");
Чтобы получить работающий фрагмент программы, добавим в тело цикла оператор, увеличивающий значение i:
i=1;
while (i<5)
{ printf("Доброе утро!"); i=i+1;
}
Проиллюстрируем использование оператора цикла с предусловием на примере pr13, в котором определяется, сколько лет должно пройти, чтобы получить сумму не меньшую S, если известно, что поступила сумма S1, на которую ежегодно начисляется k процентов. Схема алгоритма приведена на рис. 13. Из условия задачи следует, что известны величины S, S1, и k.
185
s1× k
Ежегодный прирост суммы составляет 100 , и эта величина добавляет-
ся в конце года к сумме, имеющейся в начале года.
Начало
Ввод s, s1,k
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n := 0 |
|
|
|
|||
|
|
|
|
|
|
|
|
Нет |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s1< s |
|
|
|
|||
|
|
|
|
|
|
|
|
|||
|
Да |
|
|
|||||||
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s1:= s1+ |
s1× k |
|
Вывод |
|||
|
|
|
|
|
|
|
n |
|||
|
|
|
|
|
100 |
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n := n+1 |
|
Конец |
||||
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 13. Алгоритм PR13 |
|||||||
//Пример pr13 |
|
|
|
|
||||||
#include <iostream> |
|
|
|
|
||||||
using namespace std; |
|
|
|
|
||||||
int main () |
|
|
|
|
|
|
|
|
|
|
{ |
//Начальная сумма |
|
|
|||||||
float s1, |
|
|
||||||||
s, |
//Сумма, которую нужно получить |
|||||||||
k; |
//Начисляемый процент |
|||||||||
int n; |
//Искомое число – число лет |
cout << "Введите начальную и конечную сумму:"; cin >> s1 >> s;
cout << "Введите начисляемый процент:"; cin >> k;
n = 0;
while ( s1 < s )
{
s1 = s1 + s1*k/100; n=n+1;
}
cout << "Через "<< n << ”лет получим сумму” << s; return 0;
}
186
Если перед первым вхождением в цикл s1 окажется больше s, то те- ло цикла не выполнится ни разу, счетчик n останется равным нулю.
3.3.3.Оператор цикла со счетчиком
Вциклах со счетчиком выполнение тела цикла должно повторяться зара- нее определенное число раз. Хотя такой цикл можно организовать с помощью оператора цикла с постусловием или предусловием (они универсальны), в языке С++ имеется специальная конструкция для организации циклов со счетчиком. Синтаксис оператора цикла со счетчиком в общем случае следующий:
for ( <п.ц.> = <н.з>; <условие>; <коррекция п.ц.> )
<оператор>;
Здесь for – ключевое слово (перев. с англ. для); <п.ц.> – перемен- ная цикла, которая может быть только простого типа; <н.ц.> – начальное значение – выражение такого же простого типа, как и переменная цикла; <условие> – выражение типа сравнения, используемое для выхода из цик- ла; <коррекция п.ц.> – оператор присваивания, задающий изменение переменной цикла; <оператор> – любой оператор языка C++, в том числе и составной, являющийся телом цикла.
Оператор работает таким образом: сначала вычисляется выражение, соответствующее начальному значению, и присваивается переменной цикла, потом проверяется условие выхода из цикла и, если получается истинное значение, выполняется оператор, являющийся телом цикла. Затем изменяется переменная цикла и снова проверяется условие и т. д. Если значение выраже- ния ложно, то осуществляется выход из цикла. Если начальное значение пе- ременной цикла больше конечного значения, то операторы тела цикла не выполняются. Можно сказать, что оператор цикла со счетчиком – это опера- тор цикла с предусловием. Следующий оператор не приведет к выполнению каких-либо действий:
for ( i=1; i<0; i++) printf ("i=%d \n", i);
Приведенный ниже оператор распечатает целые числа от 1 до 10: for( i=1; i<10; i++) printf ("i=%d \n", i);
Если нужно выполнить несколько операторов в теле цикла, то пользу- ются составным оператором:
for (i=5; i<= 10; i++)
{k=i*i;
printf("k=%d\n",k);
}
Оператор цикла со счетчиком позволяет [6]:
• Применять операцию уменьшения для счета в порядке убывания for( i=10; i>0; i--)
187
printf("%d секунд!\n",i); printf("Пуск!\n");
• Вести счет двойками, десятками и т. д.
for( i=5; i<100; i+=15) printf("i=%d\n",i);
В этом примере будут напечатаны 5, 20, 35, 50, 65, 80, 95.
• Использовать символов качестве переменной цикла for( ch='a'; ch<'z'; ch++)
printf("Величина кода ASCII для %с равна %d\n", ch, ch);
При выполнении этого оператора будут выведены все буквы от a до z вместе с их кодами ASCII. Символы в памяти размещаются в виде чисел, поэтому в дан- ном фрагменте на самом деле счет ведется с использованием целых чисел.
• Проверять выполнение некоторого произвольного условия, отличного
от условия, налагаемого на число итераций |
i++)printf("i*i*i=%d\n", |
|
for(i=2; |
i*i*i<100; |
|
i*i*i); |
|
|
• Сделать так, чтобы значение некоторой величины возрастало в гео- метрической, а не в арифметической прогрессии
for( debt=100.0; debt<150; debt= debt*1.1) printf("Ваш долг теперь $ %.2f\n",debt);
• В качестве оператора, корректирующего переменную цикла, можно использовать любой правильно составленный оператор. Оно будет выпол- няться при каждой итерации цикла.
y=0;
for( x=1; y<=75; y=5*x++ + 50) printf("x=%d y=%d\n",x,y);
Результат будет выглядеть так:
x = 1 x = 2 x = 3 x = 4 x = 5 x = 6
y = 0 y = 55 y = 60 y = 65 y = 70 y = 75
В последнем примере демонстрируется плохой стиль программирова- ния, так как в управлении оператором цикла участвуют две переменные x и y.
• Пропустить любое из трех выражений в круглых скобках, но при этом нельзя пропустить точку с запятой.
y=2;
for( x=3;y<=25;) y=y*x;
188
При выполнении цикла x остается равной 3. Значение y сначала будет равно 2, потом увеличится до 6, 18, а затем будет получена окончательная величина 54.
Можно опустить все три выражения в круглых скобках:
for( ;;)
printf("Хочу учиться!\n");
Данный оператор будет выполняться бесконечное число раз, поскольку пустое выражение всегда истинно.
• Первое выражение не обязательно должно инициализировать пере- менную. Например, там мог бы стоять оператор printf().
for ( printf( "Введите числа!\n"); num==6; ) scanf ("%d", &num);
В этом фрагменте первое сообщение будет выведено на печать один раз, а затем осуществляется прием чисел, пока не будет введено число 6.
• В круглых скобках первое и третье выражение могут содержать не по одному оператору, а несколько операторов разделенных запятой (говорят: использовать операцию запятая).
for(i=1, f=1 ; i<=10; f = f*i, i++) ;
• В этом случае i = 1, f = 1 выполняется один раз, а f=f*i, i++ в каждой итерации цикла, пока i <= 10.
Большая свобода выбора вида выражений, управляющих работой опе-
ратора цикла for, позволяет с помощью этой конструкции делать гораздо больше, чем просто выполнять фиксированное число итераций.
Пример полной программы рассмотрим на решении задачи нахождения суммы n первых членов ряда:
s = |
10 |
+ |
102 |
+ |
|
103 |
|
+K |
|
1 |
1× 2 |
1× 2 × 3 |
|||||||
|
|
|
|
Схема алгоритма приведена на рис. 14, а программа представлена в примере pr14.
//Пример pr14 #include <iostream> using namespace std; int main ()
{
int i,n;
float sum=0, //сумма ряда
k; //очередной член ряда cout << "Введите число членов pяда:";
189
cin |
>> n; |
k = |
1; |
for |
(i = 1; i <= n; i++) |
|
{ |
k |
= k*10.0/i; |
|
sum = sum+k; |
}
cout <<"Сумма pяда ="<< sum; return 0;
}
Говоря об операторах цикла, нельзя не сказать и о возможностях, позволяющих изменить привычный ход выполнения опе- раторов цикла. Один из таких операторов, а именно оператор break, уже использовал- ся в операторе выбора. Если оператор break встречается в теле цикла, то управ- ление передается следующему за операто- ром цикла оператору, т. е. приводит к дос- рочному выходу из цикла:
for (i=1; i<=n; i++) if(a[i]) k++;
else break;
Выход из цикла произойдет, когда i станет больше n или когда встретится ну-
левое a[i].
Другим оператором, изменяющим обычный ход выполнения оператора цикла, является оператор continue. Этот опера- тор приводит к переходу на новую итера- цию цикла, пропуская ту часть тела цикла,
которая расположена после оператора continue:
for (i=1; i<=1000; i++) {if(i%13) continue ;
printf("i=%d\n",i);
Начало
Ввод n
sum:=0
i:=1
k:= 1
Нет
i <= n
Да
k = k×10/i
sum:=sum+ Вывод
ksum
i := i+1
Конец
} |
Рис. 14. Алгоритм PR14 |
В данном примере будут выведены числа, кратные 13 и меньшие
1000.
190