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

C _Учебник_МОНУ

.pdf
Скачиваний:
199
Добавлен:
12.05.2015
Размер:
11.12 Mб
Скачать

Програмування базових алгоритмів

99

(чи обидва) з них дорівнює 1, то відповідний біт результату встановлюється в 1, інакше – біт результату дорівнює 0. Наприклад, 10102 | 10012 = 10112.

Операція побітове логічне “виключне АБО” (^) порівнює кожен біт першого операнда з відповідним бітом другого операнда і, якщо обидва опрацьовувані біти мають однакове значення, результат дорівнює 0, у решті випадків –

1. Наприклад, 10102 ^ 10012 = 00112.

Наведемо приклади виконування побітових логічних операцій.

short i=0x45FF,

// i= 0100 0101 1111 1111

r,

j=0x00FF;

// j= 0000 0000 1111 1111

r =

i ^ j;

// r=0x4500 = 0100 0101 0000 0000

r =

i | j;

// r=0x45FF = 0100 0101 0000 0000

r = i & j

// r=0x00FF = 0000 0000 1111 1111

short n, i = 0xAB00, j = 0xABCD;

n = i & j;

// У результаті n = AB00 (шістнадцяткове)

n = i | j;

// У результаті n = ABCD (шістнадцяткове)

n = i ^ j;

// У результаті n = CD (шістнадцяткове)

Операції побітового зсуву >> і << виконують зсув бітів лівого операнда на кількість розрядів, зазначену правим операндом, відповідно праворуч чи ліворуч. Значення бітів, яких бракує, доповнюються нулями. При виконанні операції зсуву можуть втрачатися старші чи молодші розряди:

>> – побітовий зсув праворуч на задану кількість бітів (65 >> 2 = 16, оскільки число 65 = 4116 = 0100 00012 після зсуву праворуч становить 0001 00002 = = 1016 = 16). Операція є еквівалентна до цілочисельного поділу на 2 у відповідному степені (65 / 4 = 16);

<< – побітовий зсув ліворуч (13 << 2 = 20, оскільки число 13 = D16 = 11012 після зсуву ліворуч становить 11 01002 = 3416 = 52). Операція є еквівалентна до цілочисельного множення на 2 у відповідному степені (13 * 4 = 52). Слід пам‟ятати, що при цьому є можливе втрачання старших розрядів.

Наведемо кілька прикладів роботи операцій зсуву.

int с =

12, m, n;

 

m = c >>

2;

// m=6

n = c <<

2;

// n=24

c = n >>

3

// c=24/23=24/8=3

int i =

0x1234, j, k ;

k = i <<

4;

// k=0x0234

j = i <<

8;

// j=0x3400

i = j >>

8;

// i=0x0034

unsigned

int x = 0x00AA, y = 0x5500, z;

z = (x << 8) + (y >> 8);

В останньому прикладі x зсувається ліворуч на 8 позицій, а y – праворуч на 8 позицій. Результати зсувів додаються, утворюючи величину 0xAA55, котра присвоюється z.

Застосовування операцій >> та << почергово до однієї й тієї самої змінної може спричинити змінення її значення через втрату розрядів.

Перетворювання, виконувані операціями зсуву, не забезпечують опрацювання ситуацій переповнення і втрати знаків. Знак першого операнда після ви-

100

Розділ 4

конання операції зберігається. Результат операції зсуву є невизначений, якщо другий операнд буде від‟ємний.

Побітові операції є зручні для організації зберігання у стислому вигляді інформації про стан on/off (ввімкнено/вимкнено). В одному байті можна зберігати 8 таких “прапорців”. Якщо змінна ch є сховищем таких “прапорців”, то перевірити, чи є “прапорець” третього біту у стані on, можна у такий спосіб:

if (ch & 4) . . .

Ця перевірка базується на двійковому поданні числа 4 = 0000 0100.

Зауважимо, що вираз a ^ a завжди повертає значення 0, а вираз a ^ b ^ a

– значення b. Ці закономірності часто застосовуються у растровій графіці.

4.3.4 Пріоритет логічних операцій

Обчислення в логічних виразах виконуються зліва направо у відповідності з таким пріоритетом операцій:

1)~ , !;

2)>>, <<;

3)<, <=, >, >=;

4)= =, !=;

5)& (побітове “І”);

6)^ (побітове “виключне АБО”);

7)| (побітове “АБО”);

8)&& (“І”);

9)|| (“АБО”).

Вирази у круглих дужках виконуються першочергово.

4.3.5 Пріоритети операцій і порядок обчислень

З урахуванням вищенаведеного пріоритету логічних операцій та пріоритету арифметичних операцій, наведеного в підрозд. 3.5, наведемо загальний пріоритет для всіх операцій мови С в табл. 4.3. Операції с вищими пріоритетами обчислюються першими.

 

 

 

 

Таблиця 4.3

 

 

Пріоритет і порядок виконування операцій

 

 

 

 

 

 

Пріоритет

 

Знак операції

Тип операції

Порядок

 

виконування

 

 

 

 

1

::, (), [], ., –>

вираз

зліва направо

2

–, ~, !, *, &, ++, --,

унарні

справа наліво

 

sizeof, (<тип>)

 

 

3

*,

/, %

мультиплікативні

 

4

+,

адитивні

 

5

<<, >>

зсув

зліва направо

6

<, >, <=, >=

відношень

 

7

==, !=

відношень (порівнянь)

 

 

Програмування базових алгоритмів

101

 

 

 

Продовження табл. 4.3

 

 

 

 

 

 

Пріоритет

Знак операції

Тип операції

Порядок

 

виконування

 

 

 

 

 

8

&

побітове “І”

 

 

9

^

побітове “виключне АБО”

 

 

10

|

побітове “АБО”

зліва направо

 

11

&&

логічне “І”

 

 

 

12

||

логічне “АБО”

 

 

13

? :

умовна

 

 

14

=, *=, /=, %=, +=, –=,

просте і складені

справа наліво

 

 

&=, |=, >>=, <<=, ^=

присвоювання

 

 

15

,

послідовне обчислення

зліва направо

 

4.3.6 Умовний оператор if

Оператор if має дві форми: скорочену та повну.

Скорочена форма має вигляд: if (<умова>) <оператор>;

Якщо значення логічного виразу в умові є ненульове, тобто умова є істинна, то виконується оператор чи група операторів в операторних дужках {}, інакше відбудеться перехід на наступний оператор.

Ні

Умова? Так

Оператор

Повна форма цього оператора:

Умова?

Ні

 

 

 

if (<умова>) <оператор1>;

Так

 

 

else <оператор2>;

 

 

Оператор1

 

Оператор2

Якщо значення логічного виразу в умові

 

 

 

 

 

 

 

є ненульове, тобто умова є істинна, то викону-

 

 

 

ється оператор1 чи група операторів в операторних дужках {}, інакше – виконується оператор2, після чого відбудеться перехід на наступний оператор. Зауважимо, що обчислюється лише один з операторів, а не обидва.

Наприклад, обчислення значення виразу

 

1 b

x

за

x b;

 

 

 

y x b

за

x b

 

 

 

 

 

 

 

 

 

b x

 

 

можна реалізувати чи то двома операторами if скороченої форми, чи одним оператором if повної форми:

1)if(x == b) y = 1 + pow(b, x); if(x != b) y = (x + b)/(b – x);

2)if(x == 0) y = 1 + pow(b, x); else y = (x + b)/(b – x);

102

Розділ 4

Зауважимо, що умову (х 0) можна записати чи то як (х != 0), чи як (х). І, навпаки, для того щоб перевірити, чи дорівнює нулю певне число х, умова може мати вид (x==0) чи (!x).

Окрім того, слід розрізняти вирази в умовах типу if(х = = 5) . . .;

та

if(х = 5) . . .;

Обидва ці оператори є працездатними, оскільки в С++ будь-який вираз, який має певне числове значення, може використовуватися в умовних операторах. Але, якщо у першому випадку значення логічного виразу може бути як істинним, так і хибним, залежно від значення змінної х, то у другому випадку значення логічного виразу завжди є істинне, оскільки в результаті присвоювання значення х = 5 – ненульове.

Наведемо кілька прикладів використання умовного оператора if.

1) Обчислити частку від ділення двох дійсних чисел, якщо це є можливо.

if(y!=0)

// Якщо знаменник не 0, можна обчислити.

r = x / y;

 

Це приклад скороченої форми умовного оператора (без гілки “інакше”). 2) Обчислити квадратний корінь числа, якщо це є можливо.

if(x>=0)

// Якщо під коренем додатне число, можна обчислити,

y = sqrt(x);

else

// інакше – виводимо повідомлення, що обчислити неможливо.

ShowMessage("Обчислити неможливо!");

Це приклад повної форми умовного оператора (з гілкою “інакше”).

3) Якщо змінні x та y є однаковими, обчислити їхній добуток, інакше – обчислити модуль їх різниці.

if(x == y) r = x * y; else r = fabs(x - y);

4) Якщо модуль змінних x та y є менше за 10, збільшити їх удвічі; інакше – зменшити їх удвічі.

if(fabs(x)<10 && fabs(y)<10) { x=x*2;

y=y*2;

}

else

{x=x/2;

y=y/2;

}

У цьому прикладі, оскільки за істинності умови має виконуватись набір з двох команд, ці команди слід записати в операторних дужках {}.

Команди в операторних дужках {} називаються блоком команд.

Умовні оператори можуть бути необмежено вкладеними один в одного. У деяких випадках складно розібратися, в якій послідовності виконуються такі вкладені оператори. Вельми часто зустрічається використовування конструкції

Програмування базових алгоритмів

103

if – else – if. Приміром, щоб визначити знак змінної x (вона може бути додатною, від‟ємною чи нулем), можна використовувати три простих незалежних команди if:

if(x>0) ShowMessage("positive"); if(x<0) ShowMessage("negative"); if(x==0) ShowMessage("zero");

чи оператор if – else вкладеної конструкції:

if (x>0) ShowMessage("positive"); else

if (x<0) ShowMessage("negative"); else ShowMessage("zero");

Тут, якщо спрацював перший else, це означає, що x є від‟ємним числом чи нульовим. Тому слід перевірити обидві гілки за допомогою ще однієї команди if.

Обчислення функції

sin( x a)

cos x 2 y

arctg2 ax

1

за x 2;

за 2 x 3;

за x 3, a 0;

за x 3, a 0,

аналогічно до попереднього прикладу, можна реалізувати чи то за допомогою чотирьох операторів if скороченої форми, чи оператором if – else вкладеної конструкції:

1) if (x <= –2) y = sin(x + a);

if (x > –2 && x <= 3) y = cos(pow(x – M_PI, 2)); if (x > 3 && a != 0) y = pow(atan(x / a), 2); if (x > 3 && a = = 0) y = 1;

2)if (x <= –2) y = sin(x + a); else

if (x <= 3) y = cos(pow(x – M_PI, 2)); else

if (a != 0) y = pow(atan(x / a), 2); else y = 1;

Уконструкціях if – else – if умови операторів if перевіряються зверху донизу. Тільки-но якась з умов набуває ненульового значення, одразу виконуватиметься оператор, який слідує за цією умовою, а останню частину конструкції буде проігноровано.

Слід записувати подібні вкладені оператори максимально наочно, використовуючи відступи з пропусків, уникати заплутаних складових і великого рівня вкладеності.

104

Розділ 4

Приклади створювання проектів програм з розгалуженою структурою, організованих за допомогою оператора if

 

 

x2

8

за

x 4;

 

Приклад 4.11 Ввести х та обчислити

 

 

 

за

4 x 0;

 

y 3x 2

 

 

 

2 x

 

за

x 0.

 

 

 

 

 

 

 

 

 

 

 

 

 

Розв‟язок. Робочий вигляд

Початок

 

 

 

 

 

 

 

 

 

форми і блок-схема:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

х

 

 

 

 

 

 

 

 

 

 

 

 

Так

 

 

 

 

 

 

 

 

 

x 4

 

y = x2 – 8

 

 

n = 1

 

 

 

 

 

 

 

 

Ні

 

Так

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4 x 0

 

 

 

 

 

 

 

 

 

y = 3x – 2

 

 

 

n = 2

 

 

 

 

 

 

 

Ні

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

y = 2 – x

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

n = 3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

y, n

Кінець

Текст програмного коду:

void __fastcall TForm1::Button1Click(TObject *Sender)

{int n; double y, x = StrToFloat(Edit1–>Text); if(x <= –4) { y = x*x – 8; n = 1;}

else

 

 

if(–4 < x && x < 0)

{ y = 3*x – 2; n = 2;}

else

{ y = 2 –

x; n = 3;}

Edit2–>Text = "Виконано умову №" + IntToStr(n) +

" y="+FloatToStr(y);

}

Приклад 4.12 Ввести значення координат (х, у) точки площини і визначити, до якої чверті площини належить ця точка.

Програмування базових алгоритмів

105

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender) {float x = StrToFloat(Edit1->Text);

float y = StrToFloat(Edit2->Text); int nomer;

if((x==0)||(y==0)) {ShowMessage("Точка лежить на осі");

Edit3->Clear(); return;

}

else

if(x>0 && y>0) nomer = 1; else

if(x<0 && y>0) nomer = 2; else

if(x<0 && y<0) nomer=3; else

nomer = 4; Edit3->Text = IntToStr(nomer);

}

Функція ShowMessage(); – призначена для виведення на екран діалогового вікна з текстом відповідного повідомлення та однією командною кнопкою ОК, при натисканні на яку вікно повідомлення зникає.

Приклад 4.13 Перевести оцінку по 100-бальній системі до 5-бальної за алгоритмом: оцінка менша за 60 відповідає незадовільній оцінці “2”; в межах від 60 до 79 – оцінці “3”; від 80 до 94 – “4”; розпочинаючи з 95 і до 100 – “5”.

Зауважимо, що в різних вузах можливі незначні відмінності від наведеного алгоритму.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender)

{int m100, m5; m100=StrToInt(Edit1->Text); if(m100>=95) m5=5; if(m100>=80 && m100<95) m5=4;

if(m100>=60 && m100<80) m5=3; if(m100<60) m5=2; Edit2->Text=IntToStr(m5);

}

106

Розділ 4

Аналогічна програма із вкладеною конструкцією if – else – if: void __fastcall TForm1::Button1Click(TObject *Sender)

{int m100, m5; m100=StrToInt(Edit1->Text); if(m100>=95) m5=5;

else

if(m100>=80) m5=4; else

if(m100>=60) m5=3; else m5=2;

Edit2->Text=IntToStr(m5);

}

У цьому варіанті програми немає потреби перевіряти праву межу інтервалів.

Приклад 4.14 Створити програмний проект для обчислення опору електричного кола, яке складається з двох з‟єднаних опорів, залежно від виду їхнього з‟єднання: паралельне чи послідовне (формули див. у прикладі 4.7).

Розв‟язок. Тобто вдосконалимо розв‟язок прикладу 4.4. Обирання виду

з‟єднаних опорів сформуємо за допомогою компонента RadioGroup , який дозволяє обирати лише одне зі значень списку, “вмикаючи” відповідну радіокнопку напроти елемента списку. Значення усіх елементів списку (видів з‟єднаних опорів) слід записати до властивості Items. Кількість елементів списку визначає кількість радіокнопок. Номер обраного елемента (нумерація починаючи з нуля) записується до властивості ItemIndex. Деталі роботи з компотнентом RadioGroup наведено також у табл. 2.2 та прикладі 4.24.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender)

{float r1, r2, R;

r1=StrToFloat(Edit1->Text); r2=StrToFloat(Edit2->Text); if(RadioGroup1->ItemIndex==0)

R=r1*r2/(r1+r2); else R=r1+r2;

Edit3->Text=FloatToStr(R);

}

Програмування базових алгоритмів

107

Приклад 4.15 Створити програмний проект для обчислення коренів квадратного рівняння ax2 bx c 0. Передбачити перевірку наявності можливих коренів, тобто перевірку, чи є дискримінант додатним.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender) {double a, b, c, D, x1, x2; a=StrToFloat(Edit1->Text); b=StrToFloat(Edit2->Text); c=StrToFloat(Edit3->Text);

D=b*b-4*a*c; if(D<0)

{Edit4->Clear(); Edit5->Clear();

ShowMessage("Коренів немає!");

}

else

{x1=(-b+sqrt(D))/(2*a); x2=(-b-sqrt(D))/(2*a); Edit4->Text=FloatToStr(x1);

Edit5->Text=FloatToStr(x2);

}

}

Приклад 4.16 Створити програмний проект для визначення координат та координатної чверті (квадранта) точки, яку задаватиме користувач.

Розв‟язок. Посеред форми розташуємо два компоненти Bevel (закладка Additional) як координатні осі, для яких слід змінити значення властивості Shape на значення bsBottomLine та bsRightLine, щоби вони набули вигляду горизонтальної та вертикальної ліній. За допомогою компонента StatusBar1 (закладка Win32) внизу форми у першій панелі цього компонента виводитимуться динамічно змінювані координати переміщення курсора. Точку користувач зможе поставити, просто клацнувши мишею. При цьому на другій панелі компонента StatusBar1 виводитимуться її координати та квадрант. Зображення точки задамо компонентом Shape1, встановивши для властивості Shape значення stCircle, а її розмір у 10 пікселів – властивостями Width та Height.

108

Розділ 4

Текст програми:

int x, y, Xt, Yt;

// Координати курсура і точки

//-----------

Подія форми на пересування миші ------------------

void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)

{// Координати пов‟язуємо з центром форми x=X-Form1->Width/2; y=Form1->Height/2-Y;

// Виведення динамічно змінюваних координат переміщення курсора

StatusBar1->Panels->Items[0]->Text=" X="+IntToStr(x)+

" Y="+IntToStr(y);

Xt=X; Yt=Y;

}

//----------- Подія форми на клацання миші --------------------

void __fastcall TForm1::FormClick(TObject *Sender)

{ Shape1->Left=Xt - Shape1->Width/2;// Горизонтальна координата точки Shape1->Top=Yt - Shape1->Height/2;// Вертикальна координата точки

Shape1->Visible = 1;

// Увімкнення видимості точки

String s;

 

if(x>0 && y>0) s="1 чверть";

// Визначення квадранта точки

if(x<0 && y>0) s="2 чверть";

 

if(x<0 && y<0) s="3 чверть";

 

if(x>0 && y<0) s="4 чверть";

 

// Виведення координат точки у другій панелі компонента StatusBar1

StatusBar1->Panels->Items[1]->Text="Координати точки: X="+IntToStr(x)+" Y="+IntToStr(y)+" "+s;

}

Приклад 4.17 Обчислити силу струму І на ділянці електричного ланцюга довжиною L за формулою

 

2

 

 

 

 

 

2 L

 

 

 

 

 

 

 

1

 

 

sin

 

LT cos

 

 

 

за

0 L

 

 

;

 

 

 

 

 

 

 

 

 

 

 

 

T

 

 

 

 

 

 

 

3

 

 

2

T

 

 

2

1

 

 

 

1

 

 

2

 

I sin

 

 

 

cos

 

 

 

 

за

 

 

 

 

L

 

 

;

 

 

 

 

 

 

 

 

 

 

 

 

 

L

 

 

 

TL

 

3

 

3

 

 

sin 2

1

cos2 LT

 

 

 

2

L 1.

eLT

за

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

TL

 

 

 

 

 

 

 

3

 

 

 

 

Значення періоду T та довжини L ввести з клавiатури.

Текст програми:

void __fastcall TForm1::Button1Click(TObject *Sender)

{float I, T=StrToFloat(Edit1->Text), L=StrToFloat(Edit2->Text);

//Обчислення сили струму за умовою

if ((L>=0)&&(L<=1./3)) I=sin(L*T)-cos(L/T); else

if (L<=2./3) I=sin(T/L)+cos(1./(T*L)); else

if (L<=1) I=exp(L*T)*(pow(sin(1./(T*L)),2)-pow(cos(L*T),2));

Edit3->Text = FloatToStr(I); // Виведення сили струму І

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]