Смекни!
smekni.com

Основы программирования на языке Си (стр. 6 из 27)

много болееподробновпоследующихлекциях. Будетпоказано, какпрограммист

может определитьсобственныйтипданных, необходимыйдлярешенияконкретной

задачи. Средстваопределенияновыхтиповданных–однаизнаиболеемощныхвоз-

можностей Си++, которыепозволяютхранитьиобрабатыватьвпрограммахнаСи++

сложные структурыданных.

3. Вывод вещественных чисел на экран

При выводенаэкранчисленныхзначенийтипа "float", "double" или "long

double" возможноуказаниеточностипредставленияданныхнаэкранеизаданиене-

которых дополнительныхпараметровотображения, например, отображениезначений

в форматесфиксированнойилиплавающейточкой.

В программе 3.1 вещественноечислоотображаетсявформатесфиксированной

точкой идвумядесятичнымизнакамипослезапятой. Идентификатор "sqrt" является

именем библиотечнойфункцииизвлеченияквадратногокорня. Описаниебиблиотеки

математических функций содержитсявзаголовочномфайле "math.h".

#include <iostream.h>

#include <math.h>

int main()

{

float number;

cout << "Введите вещественное число.&bsol;n";

cin >> number;

cout << "Корень из ";

cout.setf(ios::fixed); // СТРОКА 12

cout.precision(2);

cout << number;

cout << " примерно равен " << sqrt( number ) << ".&bsol;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 << "Число" << "Квадратный корень&bsol;n&bsol;n";

cout.setf( ios::fixed );

cout.precision(2);

for ( number = 1 ; number <= 10 ; number = number + 1 )

{

cout.width(20);

cout << number << sqrt(number) << "&bsol;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 << "Введите радиус окружности.&bsol;n";

cin >> radius;

drawCircle(radius*2);

cout.setf(ios::fixed);

cout.precision(2);

cout << "Длина окружности радиуса " << radius;

cout << " примерно равна " << 2*PI*radius << ".&bsol;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)" (операция "!=" означает "неравно"). Допускаетсяобъеди-

нение несколькихподобныхвыраженийвболеесложноевыражениеспомощью ло-