много болееподробновпоследующихлекциях. Будетпоказано, какпрограммист
может определитьсобственныйтипданных, необходимыйдлярешенияконкретной
задачи. Средстваопределенияновыхтиповданных–однаизнаиболеемощныхвоз-
можностей Си++, которыепозволяютхранитьиобрабатыватьвпрограммахнаСи++
сложные структурыданных.
3. Вывод вещественных чисел на экран
При выводенаэкранчисленныхзначенийтипа "float", "double" или "long
double" возможноуказаниеточностипредставленияданныхнаэкранеизаданиене-
которых дополнительныхпараметровотображения, например, отображениезначений
в форматесфиксированнойилиплавающейточкой.
В программе 3.1 вещественноечислоотображаетсявформатесфиксированной
точкой идвумядесятичнымизнакамипослезапятой. Идентификатор "sqrt" является
именем библиотечнойфункцииизвлеченияквадратногокорня. Описаниебиблиотеки
математических функций содержитсявзаголовочномфайле "math.h".
#include <iostream.h>
#include <math.h>
int main()
{
float number;
cout << "Введите вещественное число.\n";
cin >> number;
cout << "Корень из ";
cout.setf(ios::fixed); // СТРОКА 12
cout.precision(2);
cout << number;
cout << " примерно равен " << sqrt( number ) << ".\n";
return 0;
}
Программа 3.1.
Программа 3.1 напечатаетнаэкране:
23
Введите вещественное число.
200
Корень из 200.00 примерно равен 14.14.
Если СТРОКУ 12 заменитьна "cout.setf(ios::scientific);", товидрезульта-
та изменится:
Введите вещественное число.
200
Корень из 2.00e+02 примерно равен 1.41e+01.
В выходныеданныеможновключитьпараметрытабуляции. Дляэтогопредна-
значена функцияшириныполя, например, "cout.width(20)". Оназадаетширинусле-
дующего выводимогонаэкранзначенияравной, какминимум, 20 символам (при
меньшей ширинеавтоматическибудутдобавленыпробелы). Этавозможностьосо-
бенно полезнадляпечатитаблиц.
В компилятореVisual C++ при указаниишириныполяпоумолчаниюпредпо-
лагается, чтозначениявыравниваютсяпоправойгранице. Чтобызадатьвыравнива-
ние полевойграницеполя, потребуетсяиспользоватьещенесколькоманипуляторов
ввода-вывода. Этоспециальныефункциииоператоры, содержащиесявбиблиотеке
ввода/выводаСи++. Ониописанывзаголовочномфайлеiomanip.h. Для заданиявы-
равнивания полевойграниценадоустановитьспециальныйфлажок (переключатель)
с помощьюфункцииsetiosflags:
#include <iostream.h>
#include <iomanip.h>
#include <math.h>
int main()
{
int number;
cout << setiosflags( ios::left );
cout.width(20);
cout << "Число" << "Квадратный корень\n\n";
cout.setf( ios::fixed );
cout.precision(2);
for ( number = 1 ; number <= 10 ; number = number + 1 )
{
cout.width(20);
cout << number << sqrt(number) << "\n";
}
return 0;
}
Программа 3.2.
Программа 3.2 выдастнаэкранследующиесообщения:
Число Квадратный корень
1 1.00
2 1.41
3 1.73
4 2.00
5 2.24
6 2.45
24
7 2.65
8 2.83
9 3.00
10 3.16
(ПРИМЕЧАНИЕ: вовсехпримерахидентификатор "cout" являетсяименемперемен-
ной-объектакласса "stream" (поток). Функции "setf(...)", "precision(...)" и
"width(...)" являютсяфункциями-членами класса "stream". Понятия "объект",
"класс", "функция-член" идр. будутподробнорассматриватьсявкурсеобъектно-
ориентированного программирования.)
4. Описания, константы и перечисления
Как выужезнаете, впрограммахнаСи++ переменныеобязательнодолжны
быть описаныдопервогоиспользования, например, так:
float number;
После оператораописаниядомоментавыполненияпервогооператорапри-
сваивания значениепеременной "number" будетнеопределенным, т.е. этапеременная
может иметьслучайноезначение. ВСи++ можно (ижелательно) инициализировать
переменные конкретнымизначенияминепосредственноприописаниипеременных.
Например, возможенследующийоператорописаниясинициализацией:
float PI = 3.1416;
Если значениепеременнойвпрограмменикогданеизменяется, тоеецелесооб-
разно защититьотслучайногоизмененияспомощьюслужебногослова "const" –т.е.,
превратить вконстанту.
4.1 Тип "Перечисление"
Для описаниянаборасвязанныхпосмыслуконстанттипа "int" вСи++ есть
оператор перечисления. Например, описаниевида
enum { MON, TUES, WED, THURS, FRI, SAT, SUN };
эквивалентно описанию 7 констант-кодовднейнедели:
const int MON = 0;
const int TUES = 1;
const int WED = 2;
const int THURS = 3;
const int FRI = 4;
const int SAT = 5;
const int SUN = 6;
По умолчаниючленамперечисления "enum" присваиваютсязначения 0, 1, 2, и
т.д.. Принеобходимостичленыперечисленияможноинициализироватьдругимизна-
чениями. Неинициализированнымявночленамбудутприсвоенызначенияпопоряд-
ку, начинаяотпредыдущегопроинициализированногочлена:
enum { MON = 1, TUES, WED, THURS, FRI, SAT = -1, SUN };
В приведенномпримере "FRI" имеетзначение 5, а "SUN" –значение 0.
25
4.2 Расположение описаний констант и переменных в исходном тексте
В исходномтекстеописанияконстантчащевсегоразмещаютсявзаголовке
программы передфункцией "main". Послених, ужевтелефункции "main", размеща-
ются описанияпеременных. Дляиллюстрацииэтогопорядканижеприведенфраг-
мент программы, котораярисуетнаэкранеокружностьзаданногорадиусаивычисля-
ет еедлину (набиратьэтотпримерненадо, посколькуонприведеннеполностью.)
#include <iostream.h>
const float PI = 3.1416;
const float SCREEN_WIDTH = 317.24;
int drawCircle(float diameter); /* Это "прототип функции" */
int main()
{
float radius = 0;
cout << "Введите радиус окружности.\n";
cin >> radius;
drawCircle(radius*2);
cout.setf(ios::fixed);
cout.precision(2);
cout << "Длина окружности радиуса " << radius;
cout << " примерно равна " << 2*PI*radius << ".\n";
return 0;
}
int drawCircle(float diameter)
{
float radius = 0;
if (diameter > SCREEN_WIDTH)
radius = SCREEN_WIDTH/2.0;
else
radius = diameter/2.0;
...
...
}
После определенияфункции "main()" вэтойпрограммесодержитсяопределе-
ние функциирисованияокружности "drawCircle(...)". Деталиреализацииэтой
функции сейчаснесущественны (будемсчитать, чтофункцияdrawCircle(...)" реа-
лизована корректноиеюможнопользоватьсятакже, как, например, функцией
"sqrt(...)"). Обратитевнимание, что, хотяпеременная "radius" используетсявобеих
функциях "main()" и "drawCircle(...)", этонеоднаитажепеременная, адверазных.
Если быпеременная "radius" былаописанадофункции "main", товтакомслу-
чае онабылабыглобальной переменной (общедоступной). Тогда, предполагая, что
внутри функции "drawCircle(...)" описанияпеременнойуженет, если "drawCircle(...)"
присвоит глобальнойпеременнойзначение "SCREEN_WIDTH/2.0", тоэто
значение чутьпозжефункция "main()" используетдлявычислениядлины окружности
и получитсяневерныйрезультат.
В приведеннойпрограммеглобальнойпеременнойнет, аестьдвелокальных
переменных "radius". Например, перваяпеременная "radius" являетсялокальной пе-
26
ременной функции "main()", или, говорят, чтофункция "main()" являетсяобластью
видимости этой переменной.
Константы общегоназначения, такие, как "PI" и "SCREEN_WIDTH", принятоопи-
сывать глобально, чтобыонибылидоступнывнутрилюбойфункции.
Для контролядействийпрограммывприведенномфрагментепредусмотрено
повторное отображениеданных, введенныхпользователем. Другимисловами, задан-
ное пользователемзначение "radius" ещеразпечатаетсянаэкранепередотображени-
ем длиныокружности.
5. Присваивание и выражения
5.1 Краткая форма записи операторов присваивания
В программахчастовстречаютсяоператорыприсваивания, вкоторыхсправа
стоит выражение, модифицирующеетекущеезначениепеременной, например:
number = number + 1;
Переменным частоприсваиваютсязначения, вычисленныенаосновеихстарых
значений. ПоэтомувСи++ былавведена краткаяформазаписидляподобныхопера-
торов присваивания. Любуюизопераций "+" (сложение), "-" (вычитание), "*" (умно-
жение), "/" (деление) и "%" (остатокотделениянацело) можноуказатьвкачестве
префикса оператораприсваивания ("=") (cм. следующуютаблицу).
Пример:
number += 1;
total -= discount;
bonus *= 2;
time /= rush_factor;
change %= 100;
amount *= count1 + count2;
Эквивалентное выражение:
number = number + 1;
total = total - discount;
bonus = bonus * 2;
time = time / rush_factor;
change = change % 100;
amount = amount * (count1 + count2);
Первый примердопускаетещеболеекраткуюзаписьспомощью оператораин-
кремента "++":
number++;
Оператор "++" существуетивпрефикснойформе:
++number;
Постфиксная ипрефикснаяформазаписиимеютважноеразличие, котороене-
обходимо помнить. ПрефиксныйоператорприменяетсяДО вычисления остальной
части выражения, апостфиксный–ПОСЛЕ. Например, посолевыполненияоперато-
ров
x = 4;
y = x++;
переменная "x" получитзначение 5, а "y" –значение 4. Вслучаеоператоров
x = 4;
y = ++x;
обе переменныеполучатзначение 5. Этообъясняетсятем, что "++x" выполняетсядо
того, какзначение "x" будетиспользовановвыражении, а "x++" –после. ВСи++ су-
ществует аналогичныйоператордекремента "--", уменьшающийзначениеперемен-
ной на 1, иунеготожеестьпрефикснаяипостфикснаяформа.
27
Вообще, выражениесоператоромприсваиванияимеетзначение, равноезначе-
нию левойчастипослевыполненияприсваивания. Нижеприведеновыражение, соот-
ветствующее правиламСи++, котороеможноиспользоватьдляпроверкиусловия:
(y = ++x) == 5
Это выражениеозначаетследующее: "послеприсвоенияпеременнойy инкре-
ментированного значенияx проверить, неравнолизначениеy числу 5".
5.2 Логические выражения и операторы
Интуитивно логическиевыражениянаподобие "2<7", "1.2!=3.7" и "6>=9" вос-
принимаются человекомкакутверждения, которыемогутбыть "истинными (true)"
или "ложными (false)" (операция "!=" означает "неравно"). Допускаетсяобъеди-
нение несколькихподобныхвыраженийвболеесложноевыражениеспомощью ло-