Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Прикладное программирование на CC++ с нуля до мультимедийных и сетевых приложений

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
Выражения присваивания и ввод данных в программу 21
что в результате «каскадного» присваивания типа à=b=ñ=3.1415927 все три переменные будут иметь значение пифагорова числа. Подчеркнем, что при­сваивание здесь будет выполняться справа налево. Сначала ñ получит значе­ние этой константы, затем b примет значение, равное величине переменной ñ, а затем и à не останется обойденной вниманием. Для любопытных дадим по­вод к размышлению. А что будет, если переменные в «каскадном» присваива­нии имеют разные типы? Тут, как говорится, возможны варианты.
Кроме обычного выражения присваивания в языке С реализованы слож­ные присваивания, имеющие вид:
Имя< операция> =Выражение;
Имя — имя переменной. В качестве конструкции <операция> может сто­ять любой знак арифметического действия или операции сдвига +, –, *, /, %, >>, <<. Такое сложное присваивание дает тот же результат, что и про-
стое присваивание в виде Имя=Имя<операция> Выражение, однако сложное присваивание, использованное там, где оно может заменить простое, выпол­няется быстрее. В этой связи в оптимально написанной программе обычно широко используются сложные присваивания. Типы данных, допустимые в этих выражениях, зависят от типов операций. Выражение à*=r эквивалентно выражению à=à*r и допустимо для любых типов данных. Выражение à%=b присваивает переменной à новое значение, равное остатку от целочисленно­го деления старого значения à íà b, и применимо, очевидно, к целым. Цело­численным является и выражение à>>=2, результат которого — новое значе­ние à есть старое значение à, целочисленно деленное на 4. Разумеется, такое присвоение выполняется существенно быстрее, нежели выражения à=à/4.
Как уже говорилось, придание переменным значений с помощью при­сваивания не решает проблему ввода данных в программу в целом. Если вы хотите многократно использовать одну программу с различными входными данными, то вам поможет функция scanf. Продемонстрируем ее работу в сле­дующей программе:
#include<stdio.h>
#include<math.h>
#include<conio.h>
viod main()
{ double a.b,c,xl,x2;
clrscr();
printf ("a="); scanf ("%lf ",&a);
printf ("b="); scanf ("%lf ",&b);
printf ("c=") ; scanf("%lf" ,&c) ;
xl=(-b+(c=sqrt(b*b-4.0*a*c)))/(a+a);
x2=(-b-c)/(a+a);
printf ("xl=%f\n",xl);
printf ("x2=%f\n",x2);
getch(); }
22 Глава 1. Язык программирования С
Функция scanf в какой-то степени напоминает по своей структуре функ­цию printf, но по своему назначению скорее противоположна ей, поскольку предназначена для придания переменным значений, вводимых с консоли. Структура функции такова:
Scanf("строка", Указатель!, Указатель2,...);
В строке в кавычках мы рекомендуем начинающим писать только фор­матные выражения, полностью аналогичные форматным выражениям в функ­ции printf. Количество форматных выражений, которые советуем писать под­ряд, через разделители, например, запятые, должно быть равным количеству элементов в конструкции после закрывающих строку кавычек и запятой. Функция устроена так, что в ней перечисляются (через запятую) не сами име­на переменных, которым нужно придать значения, а так называемые указате­ли на имена или адреса этих переменных. Разговор об указателях отложим до более подходящего момента, ограничившись пока тем пояснением, что адрес переменной r (указатель на r) записывается как &r, что мы и видим в примере программы. Важнейшим обстоятельством является то, что вы, как програм­мист, должны очень строго следить за совпадением типа вводимой перемен­ной с типом соответствующего форматного выражения. Так, если в функции printf вы печатаете переменную типа double по формату %f, то значение выве­дется на экран правильно, однако, если вы по этому формату попытаетесь ввести переменную типа double функцией scanf, то результат будет плачевным, вплоть до полного «зависания» системы — для типа double строго требуется формат %lf. Сочетание букв соответствует типу long float, ÷òî è åñòü double. Можно ли между знаком % и форматными буквами писать что-нибудь типа
6.3? Да, можно. Однако извольте и число, вводимое с клавиатуры, задавать именно в такой форме: две позиции в целой части, десятичная точка, три по­зиции в дробной части. Для полного согласования типов вводимых значений и типов форматных выражений автор настоятельно советует читателю еще раз обратиться к справочной системе TURBO Ñ, вызвав справку по функции scanf. Отметим также еще раз, что если функция printf может печатать значе­ние переменной, значение выражения, значение, возвращаемое какой-либо функцией, то функция scanf только присваивает переменной значение, вводи­мое с клавиатуры. Если ввод осуществляется выражением:
scanf("%lf,%lf,%lf",&a,&b,&c);
то нужно ввести на экран первое число, затем запятую, затем второе число, затем запятую, затем третье число и только потом нажать клавишу ввода Enter. В примере программы ввод организован иначе. Сначала печатается «подсказка» à=. Теперь курсор ввода находится правее знака равенства, и вы должны напечатать вводимое число и нажать Enter. Все. Первая функция вво­да проработала, и переменная à получила введенное значение. Функция scanf, закончив работать, всегда осуществляет переход на новую строку так, что сле­дующая подсказка будет уже на новой строке, и все повторяется теперь для переменной b, а затем и для ñ.
Условные выражения 23
Читатель уже понял, что программа вычисляет корни квадратного уравне­ния ax
2
+bõ+ñ=0. Здесь могут возникнуть неприятности, если a = 0 или
если дискриминант отрицателен. Будем считать, что коэффициенты введены такими, что неприятностей не возникнет. Далее в программе реализованы расчетные формулы для корней. Здесь снова продемонстрирована интересная новинка. Обратите внимания на то, что прямо внутри арифметического выра­жения помещено выражение присваивания: c=sqrt(b*b-4.0*a*c), что вполне допустимо. Тогда переменная ñ получает новое значение, вычисленное с ис­пользованием ее старого значения. Разумеется, это старое значение после та­кого присваивания исчезает, но в данном примере оно уже в дальнейшем и не понадобится, что и позволило сэкономить немного машинной памяти, обой­тись без введения и описания новой переменной. Если бы мы не присвоили переменной ñ значения корня из дискриминанта, в следующем выражении нам снова пришлось бы вычислять этот корень. Поскольку именно вычисле­ние значений математических функций занимает наибольшее процессорное время, здесь мы оптимизировали программу по быстродействию. И еще один момент. В последних выражениях программы мы снова пишем à+à вместо 2*à, заменяя медленную операцию умножения быстрой операцией сложения.
Условные выражения
До сих пор мы жили в скучном мире, где программы выполнялись после­довательно, выражение за выражением от начала до конца, не задавая себе вопросов, а значит, и не пытаясь находить ответы. Да простит нам читатель такое «очеловечивание» программы, но суть материала данного раздела дейст­вительно связана с тем, что в программе могут анализироваться те или иные условия, и в зависимости от того, выполняются ли эти условия, программа работает по разному. Таким образом, реализуются разветвляющиеся алгорит­мы — сценарий работы может развиваться по одному из нескольких вариан­тов в зависимости от условий. Мы рассмотрим лишь некоторые средства язы­ка С, позволяющие программировать разветвляющиеся алгоритмы. Хотя дру­гие средства могут оказаться весьма удобными для какой-то конкретной задачи, мы остановимся только на условных выражениях, которые, впрочем, полностью решают задачу организации разветвлений.
Начнем сразу с примера программы:
#include<stdio.h>
void main()
{ int a,b;
printf ("ВВЕДИ A="); scanf("%d",&a);
printf ("ВВЕЛИ В="); scanf("%d",&b);
if(a%b==0) рrintf("Число %d делится на %d нацело\п",а,b);
else
{printf ("Число %d не делится на %d нацело\п",а,b);
printf ("Остаток деления %d на %d равен %d\n",a,b,a%b);
}}
24 Глава 1. Язык программирования С
Программа делает простые вещи. Принимает с консоли два целых числа и проверяет, делится ли первое число на второе нацело. В первом случае на эк­ран выводится одно сообщение, во втором — два других.
Условные выражения, обеспечивающие альтернативные пути выполне­ния программы, могут быть двух типов. Простое условное выражение имеет структуру
if(Выраженне1) Выражение2;
Само служебное слово if означает ЕСЛИ. Если Выражение1 имеет значе­ние 0, то Выражение2 пропускается, и программа выполняется дальше. Если Выражение1 не равно 0, то выполняется Выражение2, и только после этого программа работает дальше. Сложное условное выражение имеет вид:
If(Выражение1) Выраженпе2; else ВыражениеЗ;
Служебное слово else означает ИНАЧЕ. Если Выражение1 имеет значение отличное от нуля, то выполняется Выражение2, пропускается ВыражениеЗ,и программа выполняется дальше. Если же Выражение1 имеет значение 0, то, наоборот, пропускается Выражение2, выполняется ВыражениеЗ, программа работает дальше. Любое из выражений может, в свою очередь, быть условным выражением. Необходимо только следить за тем, чтобы служебное слово if не оказалось «оторванным» от своего else. Это значит, что между if è else фор­мально должно стоять только одно выражение.
А что делать, если необходимо, чтобы в качестве Выражения2 èëè Âûðà- женияЗ выполнялась целая группа действий? В этом случае вам нужно «обма­нуть» систему, замаскировать группу выражений под одно выражение. Делает­ся это очень просто. Группу выражений объединяют в так называемое состав­ное выражение — заключают эту группу в фигурные скобки {}. Тогда группа в фигурных скобках и в условных выражениях и в других специальных конст­рукциях будет восприниматься как одно выражение.
Теперь, очевидно, нам никак не обойтись без введения в программу таких понятий, как «больше», «не равно» и так далее. Выражения, содержащие та­кого сорта сравнения, естественно назвать выражениями отношений. Сразу отметим, что выражения отношений имеют целый, беззнаковый числовой тип. Более того, отношения могут принимать только одно из двух возможных значений: 0 или 1. Первое можно рассматривать как «ЛОЖЬ», а второе как «ИСТИНА», хотя такая трактовка чужда языку С.
В языке допустимы следующие знаки сравнения:
= — равно;
< — меньше;
!= — не равно;
>= — не меньше;
> — больше;
<= — не больше.
Условные выражения 25
Смысл обозначений совершенно ясен и не требует пояснений. Приведем примеры. Значение выражения 3<=7 имеет значение 1, поскольку «ЭТО ПРАВИЛЬНО», а выражение 0.2<.0 равно нулю, поскольку «ЭТО НЕПРАВ­ДА». Выражение à!=b равно нулю, если à è b имеют равные значения. В про­тивном случае выражение имеет значение 1. При этом можно сравнивать не только числовые значения, но и, например, символьные переменные. Самое интересное заключается в том, что во многих случаях вы имеете право срав­нивать значения разных типов. Так, переменная à может быть целой, a b сим­вольной. Догадываетесь, что сравнивается в этой ситуации?
Важную роль в условных выражениях играют логические операции. Таких операций три. Логическое отрицание !à имеет значение 1, если à равно нулю и имеет значение 0 при любых других значениях à. Логическое умножение À&&Â имеет значение 1 в том и только том случае, когда и À è Â не равны нулю, и имеет значение 0, когда либо À, ëèáî B, ëèáî è À è Â равны пулю. Логическое сложение P||Q имеет значение 0 в том и только том случае, когда и Ð è Q равны нулю, и имеет значение 1 при любых других вариантах.
В сложных логических выражениях надо ориентироваться на приоритеты операций. В первую очередь выполняются операции отрицания, во вторую очередь — логические умножения и в последнюю — логические сложения. Во избежание неприятностей рекомендуется пользоваться круглыми скобками. Читателю предлагается убедиться в том, что
(3==7)||(2!=4) åñòü 1;
(!(2!=0)||((!2)==5) åñòü 0;
!(4.5>1.0)&&(3!=3) åñòü 0;
(!(1&&2))||((3>2) åñòü 1.
Теперь вернемся к нашей последней программе. Здесь в условии после if вычисляется остаток от деления a íà b и результат сравнивается с нулем. Если остаток от деления равен нулю — если à делится на b нацело, то выполняется выражение после if(). В противном случае выполняется составное выражение в фигурных скобках, следующее за else. Цель достигнута, но не самым луч­шим способом. Действительно, для достижения этой же цели в скобках после if достаточно было бы написать !(à%b). А можно было бы поступить и еще проще. В скобках пишем просто à%b и выражения перед и после else меняем местами.
Äëÿ
закрепления усвоенного составим еще одну программу, которая сно­ва решает квадратное уравнение, но предварительно страхует нас от случая комплексных корней, когда дискриминант отрицателен:
#include<stdio.h> #include<math.h> void main() {double a,b,c;
printf("ВВЕДИТЕ a,b,c\n"); scanf("%lf,%lf,%lf",&а,&Ь,&с);
if((c=b*b-4.0*a*c)<0.) printf("НЕТ РЕШЕНИЯ");
26 Глава 1. Язык программирования С
else
{printf ("x1=%f\n",(-b+(c=sqrt (c) ) ) /a+=a) ;
printf ("x2=%f\n",(-b-c)/a); } }
В программе снова применены некоторые маленькие хитрости, обеспечи­вающие оптимизацию вычислений. Поскольку уважаемый читатель стал уже достаточно опытным, предоставим ему возможность самостоятельно разо­браться с ними.
Циклические выражения
Циклические выражения, или просто циклы, предназначены для много­кратного выполнения однотипных действий. В С используются три типа цик­лов. Рассмотрим первый из них, называемый циклом while. Сразу начнем с примера программы:
#include<stdio.h> void nain() {int i,j=l,k=0;
printf("Введите i="); scanf("%d".&i); while(j<=i) {k+=j; j++;} printf("Cyммa ряда равна %d",k); }
Öèêë while имеет следующую структуру:
while(Выражение1)Выражение2;
Само слово while означает ПОКА. Более корректно трактовать это слово в форме ДО ТЕХ ПОР ПОКА. Работает цикл следующим образом. Вычисляется Выражение1. Если его значение не 0, то выполняется Выражение2, которое может быть составным выражением. Затем снова вычисляется Выражение1,и если оно не 0, снова выполняется Выражение2. Так продолжается до тех пор, пока Выражение1 не примет значение, равное нулю. Разумеется, в процессе выполнения цикла что-то в выражении в скобках должно меняться. Иначе произойдет зацикливание программы. Кстати, в случае зацикливания или возникновения некоторых других аварийных ситуаций можно попробовать прервать работу программы, дважды нажав комбинацию клавиш Ctrl+Pause.
Наша последняя программа вычисляет сумму первых i натуральных чисел 1+2+3+...+i, ãäå i — целое число, вводимое с консоли. Условие, прове- ряемое в цикле j<=i, перестанет выполняться (примет значение 0), как только j станет больше i. Это событие рано или поздно наступит, поскольку в состав­ном выражении, выполняемом в цикле, каждый раз j увеличивается на едини­цу. Кроме того, в составном выражении в переменной k накапливается сумма членов ряда. С учетом того, что в описании переменных j è k им присвоены необходимые значения. Можно убедиться, «вручную» проследив работу цик­ла, что поставленная задача здесь решается. Если введено число i, равное нулю, то цикл не проработает ни одного раза и переменная k останется со своим начальным значением 0, что также верно. Заметим, что в данном вари
-
Циклические выражения 27
анте цикл записан не вполне оптимально. Составное выражение можно запи­сать более компактно и более оптимально с точки зрения быстродействия:
while(j<=i) k+=j++;
Можно видеть, что необходимость в фигурных скобках отпала, поскольку выражение перестало быть составным.
Рассмотрим еще одну программу, использующую цикл while:
void main() {int st=,.i=0,n; scanf("%d",&n); while(i++<n) st<<=1; printf("2^n=%d",st); }
Эта программа вычисляет в переменной st n-ю степень двойки. Начальное значение st равно 1. В цикле каждый раз производится сдвиг двоичного кода величины st на одну позицию влево, то есть выполняется умножение на 2. Тем самым и определяется степень двойки. Успокоим дотошного читателя, который разумно заподозрил, что мы делаем лишнюю работу. Эта программа только демонстрирует работу цикла. На самом деле вместо всего цикла доста­точно было бы записать одно выражение:
st<<=n;
Другой тип цикла называется циклом do-while и имеет следующую структуру:
do Выражение1; while(Выражение2);
Такую конструкцию следует понимать так: ВЫПОЛНЯТЬ Выражение1, ÏÎÊÀ Выражение2 есть НЕ НОЛЬ. Отличие от цикла while состоит в том, что сначала выполняется первое выражение, а затем проверяется второе и так происходит до тех пор, пока последнее не примет значение 0. В цикле while, наоборот, сначала, проверялось условие, а потом выполнялось выражение. Как мы видели, может иметь место такая ситуация, когда цикл while не вы­полняется ни разу. Цикл do-while выполняется, как минимум, один раз. И здесь также Выражение1 может быть составным.
С использованием цикла do-while напишем программу, вычисляющую сумму n+1первых членов ряда 1+1/2+1/3+1/4+... +1/n.
void main() { int n,j=l; double a=.0; scanf("%d",&n); n++; do a+=1.0/j++; while(j<n); printf("%lf".a); }
Программа будет работать правильно, но она снова не оптимальна. Мож­но обойтись без переменной j. Цикл в этом случае следует записать в виде:
do a+=1.0/n- -; while(n);
28 Глава 1. Язык программирования С
При этом из программы следует убрать выражение инкремента ï++; по­сле функции scanf. Можно видеть, что сумма ряда теперь вычисляется в об­ратном порядке — от конца к началу, и переменная n каждый раз уменьшает­ся на единицу (декрементируется). Упростилось и условие выхода из цикла. Действительно, цикл нужно выполнять до тех пор, пока n не станет равным нулю, что и записано в скобках после while.
Третий тип циклических выражений — циклы for. Структура цикла в об­щем виде может быть представлена так:
for(Выражения1; Выражение2; ВыраженияЗ)Выражение4;
Сразу обратим внимание на то, что при использовании цикла for вы мо­жете воспользоваться некими исключениями из правил, которые только в этом цикле и допустимы. Выражения1 è ВыраженияЗ не зря написаны здесь во множественном числе. На их месте могут быть записаны несколько выра­жений присваивания, перечисленные не через точку с запятой, как обычно, а через запятую. Тогда эти группы будут представлять собой своеобразные со­ставные выражения, не нуждающиеся, однако, в фигурных скобках. Выражение2 представляет собой обычное условие, принимающее значение 0 или не 0. Выражение4, которое может быть составным уже в обычном виде, является выражением, выполняющимся â цикле. Интересно òî, ÷òî Выражения1, ВыраженияЗ è äàæå Выражение4 могут отсутствовать, если в них нет нужды. Правильнее будет сказать, что они могут быть пустыми выраже­ниями, от которых остались только их точки с запятой. Более того, для Âûðà- женийЗ имеет место совсем нестандартная ситуация. Если они присутствуют, то они не должны оканчиваться символом «;». Все эти исключения, по мне­нию автора, только портят общее представление об языке С. С этим, однако, приходится мириться, поскольку цикл for с его «причудами» очень широко используется программистами. Здесь уместно отметить, что все три цикла взаимозаменяемы и, опять же, по субъективному суждению вашего покорного слуги, без цикла for вполне можно было бы обойтись.
Работа цикла for заключается в следующем. Сначала, причем только один раз, выполняются Выражения1, если они имеются. Понятно, что эти выраже­ния целесообразно использовать для выполнения предваряющих цикл при­сваиваний, для установки некоторых начальных значений переменных. Затем вычисляется Выражение2. Если оно равно 0, то на этом работа цикла заканчи­вается и программа работает дальше. Если Выражение2 не есть 0, то выполня­ется Выражение4, которое, как говорилось выше, может быть и пустым. Затем выполняются Выражения3 (если они есть), снова проверяется условие в Выражении2 и так далее, до тех пор пока в Выражение2 не образуется 0.
Проиллюстрируем работу цикла for на программе, вычисляющей факто­риал числа n! = 1*2*3*...*n:
void main() int n,i.j; scanf("%d".&n); for(i=1,j=1; i<=n; i++,j*=i); printf("%d!=%d",n,j); }
Циклические выражения 29
В данном примере как раз отсутствует Выражение4, поскольку все, что необходимо, выполняется в ВыраженияхЗ, которых два. Эти два выражения лучше превратить в одно: j*=++i. Убедитесь, что знаки ++ здесь должны стоять именно перед i (в префиксной форме), а не после i. Сначала надо увеличить i на единицу, а затем использовать, как это более явно видно из неисправленной программы. Выражения1 также не мешает преобразовать к виду i=j=1;
А теперь перепишем программу в другой форме:
void main()
{ int n,i=1,j=1;
scanf("%d".&n);
for(;i<=n;)j*=i++;
printf("%d!=%d",n,j); }
Здесь, наоборот, невостребованными оказались Выражения1, поскольку начальные присваивания сделаны при описании переменных. Отсутствуют и Выражения3, так как все необходимые действия перенесены в Выражение4.
Поскольку циклы являются важнейшими элементами программ, рассмот­рим еще несколько примеров. Следующая программа выводит на экран стол­бец случайных целых чисел:
#include<stdio.h>
#include<stdlib.h>
void main()
{ int i;
for(i=10; i- -;) printf("%d\ï",rand()); }
Здесь фигурирует новый заголовочный файл stdlib.h, имеющий отношение к функциям из так называемой стандартной библиотеки. В данном случае од­ной из таких функций является генератор случайных чисел rand(). Эта функ­ция при каждом к ней обращении возвращает очередное целое случайное чис­ло в диапазоне от 0 до 32 766 включительно. Что это за магическое число? Это максимальное целое число типа int. С помощью генератора rand можно легко получать последовательности и вещественных чисел. Так, в результате опера­ции rand()/32766.0 будет сгенерировано случайное вещественное число в диа­пазоне от 0.0 до 1.0. Подчеркнем, что число в знаменателе должно быть запи­сано именно с десятичной точкой, как вещественное число. В противном слу­чае будет выполнено целочисленное деление, и будет почти всегда генерироваться... Что? Только очень редко, примерно один раз из 30 000 будет попадаться... Что?
Íó, à ñàì öèêë for в последней программе будет выполнен 10 раз. На эк­ране будет столбик из 10 случайных чисел. Обращаем внимание на то, что цикл записан весьма компактно и оптимален по быстродействию.
Теперь составим программу, решающую следующую задачу. Нужно найти среднее арифметическое всех случайных чисел, генерируемых функцией rand. в последовательности до первого числа, превышающего значение 20 000.
30 Глава 1. Язык программирования С
#include<stdio. h> #include<stdlib.h> void main() { int i=0,a.z;
long s=0; double sred; printf("3ATPABKA="); scanf("%d".&z); srand(z); while((a=rand())<=20000) {i++; s+=a;} sred=(double)s/i; printf("СРЕДНЕЕ АРИФМЕТИЧЕСКОЕ %d ЧИСЕЛ = %lf",i,sred); }
В программе вызывается еще одна функция из стандартной библиотеки srand(z) от целого аргумента z. Число z вводится с консоли и является «затрав­кой» для последовательности случайных чисел, генерируемых функцией rand. Можно считать, что z является номером случайной последовательности. Каж­дому z будет соответствовать своя последовательность. Чтобы получать каж­дый раз один и тот же ряд случайных чисел, нужно вводить одно и то же z, и, наоборот, вводя каждый раз новое z, вы получите новый ряд. В переменной s накапливается сумма случайных чисел для определения среднего значения. Поскольку эта сумма может превысить максимально допустимую для типа int величину 32 767, мы задали переменной s тип «длинного целого» long. Понят­но, что начальное значение s должно быть нулевым. Целая переменная i явля­ется счетчиком числа выполнений цикла. Она также нужна для вычисления среднего арифметического. В цикле while, непосредственно при проверке ус­ловия, переменная à получает очередное случайное значение. Цикл выполня­ется до тех пор, пока очередное встретившееся случайное число не превысит 20 000. В составном выражении в цикле счетчик увеличивается каждый раз на единицу и к сумме добавляется очередное число. После выхода из цикла ве­щественная переменная sred получает значение среднего арифметического. Для этого надо сумму разделить на счетчик. Но и s è i имеют целый тип, и операция s/i выполнится целочисленно, что было бы неверно, поскольку среднее арифметическое — вещественное число. В этой связи в программе применена новая операция, которую можно назвать приведением к нужному типу. Мы знаем, что для того, чтобы операция деления выполнилась в веще­ственной форме или, как говорят, в виде операции с плавающей точкой, дос­таточно привести числитель или знаменатель к вещественному типу. В нашей программе в числителе написано (double)s. Это и означает, что значение пере­менной s будет преобразовано в вещественное число (с двойной точностью). Теперь все стало на свои места, и нам осталось вывести на экран вычислен­ное среднее. Заметим, что переменная sred, вообще говоря, не нужна — мож­но было бы сразу в выражении печати использовать (double)s/i èëè s/(double)i.
Операция приведения к типу, конечно, универсальна. Так, если перемен­ная Ð была вещественного типа, то (int)P дает целое типа int, полученное из Ð округлением, a (char)P дает символ, код которого равен округленному значе нию Ð, если, конечно, такой символ вообще существует.
-