Мова програмування С++

Описание:
Тип работы: дипломная работа
Характеристика методів та етапів створення простих програм на мові програмування С++. Особливості структури та порядку запуску програми. Функції вводу і виводу та маніпулятори мови С++. Робота з одновимірними масивами. Символьна інформація та рядки.
Доступные действия
Введите защитный код для скачивания файла и нажмите "Скачать файл"
Защитный код
Введите защитный код

Нажмите на изображение для генерации защитного кода

Текст:

Дипломна робота

Мова програмування С++


Зміст

1. Створення простих програм на С++

1.1 Структура програми

1.2 Етапи виконання програми

1.3 Порядок запуску програми

2. Форматний ввід/вивід у мові С/С++

2.1 Функції вводу/виводу мови С

2.2 Функції вводу/виводу та маніпулятори мови С++

3. Лінійні програми на С++

3.1 Стандартні типи даних мови С++

3.2. Операції мови С++

4. Основні оператори мови С++

4.1 Складові оператори

4.2 Оператори розгалуження

4.3 Оператори циклу

4.4 Оператори переходу

5. Вказівними та операції над ними

5.1 Поняття вказівника

5.2 Дії над вказівниками

6. Робота з одновимірними масивами

6.1 Статичні та динамічні масиви

6.2 Рядки, як одновимірні масиви

7. Двовимірні масиви

8. Символьна інформація та рядки

8.1 Збереження символьної інформації

8.2 Функції вводу/виводу для роботи з рядками

8.3 Спеціальні функції для роботи з рядками та символами

9. Функції користувача

9.1 Функції: визначення, опис, виклик

9.2 Передача масивів у функцію

9.3 Перевантаження функцій у С++

9.4 Функції зі змінною кількістю параметрів

10. Структури

Список літератури


1. Створення простих програм на С++

C++ (Сі-плюс-плюс) — універсальна мова програмування високого рівня з підтримкою декількох парадигм програмування: об"єктно-орієнтованої, узагальненої та процедурної. Розроблена Б"ярном Страуструпом (англ. Bjarne Stroustrup) в AT&T Bell Laboratories (Мюррей-Хілл, Нью-Джерсі) у 1979 році та названа «Сі з класами». Страуструп перейменував мову у C++ у 1983 р. Базується на мові Сі. Визначена стандартом ISO/IEC 14882:2003.

 

1.1 СТРУКТУРА ПРОГРАМИ

Розглянемо програму, що виводить на екран монітора фразу “Ласкаво просимо до С++!”:

Приклад 1.

// Welcome.cpp – ім^я файла з програмою

# include

void main ()

{ cout << ” Ласкаво просимо до С++! n”;

}

Результат виконання програми:

Ласкаво просимо до С++!

У першому рядку програми міститься однорядковий коментар, що починається з символу “//”, який вказує, що після цього символу йде однорядковий коментар. Коментарі не викликають ніяких дій комп^ютера і ігноруються компілятором С++, а лише допомагають іншим людям читати і зрозуміти Вашу програму.

У другому рядку розміщено команду (директиву) препроцесору, що забезпечує включення до програми засобів зв^язку зі стандартними потоками вводу і виводу даних. Вказані засоби містяться у файлі під назвою iostream.h (мнемоніка: “і” (input) – ввід; “output” – вивід; “stream” – потік; “head” - заголовний). Рядок, що починається з ”#”, обробляється препроцесором перед компіляцією програми. Файл iostream.h повинен бути залучений для всіх програм, що виводять дані на екран монітора або вводять дані з клавіатури.

Третій рядок є заголовком функції з іменем main. Будь-яка програма на С++ повинна містити лише одну функцію з таким іменем. Саме з неї починається виконання програми. void – специфікатор типу, який вказує, що функція main в даному прикладі не повертає ніякого значення. Круглі дужки після main потрібні в зв^язку з форматом (синтаксисом) заголовка будь-якої функції. В них розміщується список параметрів. У нашому прикладі параметри не потрібні.

Тіло будь-якої функції повинно починатися і закінчуватися фігурними дужками, між якими знаходиться послідовність описів, операторів і визначень. Кожен оператор, визначення чи опис повинні закінчуватися крапкою з комою.

Рядок

cout << ” Ласкаво просимо до С++! n”;

є командою комп^ютеру надрукувати на екрані рядок символів, що записаний у лапках. Повний рядок, включаючи cout, операцію ”<<”, рядок ”Ласкаво просимо до С++! n” і крапку з комою “;”, називається оператором. Всі вводи і виводи в С++ виконуються над потоками символів. Таким чином потік символів Ласкаво просимо до С++! спрямовується до об^єкта стандартного потоку виводу cout, який пов^язаний з екраном. Вже зараз слід відмітити одну з принципових особливостей мови С++, яку називають перевантаженням або розширенням дії стандартних операцій. Операція ”<<” називається операцією „розмістити у потік” лишень у тому випадку, коли зліва від неї знаходиться ім^я об^єкта cout. Інакше пара символів “<<” означає бінарну операцію зсуву вліво. Символи правого операнда зазвичай виводяться так само, як вони виглядають між лапками.

Слід зазначити, що символи ” ” не виводяться на екран. Комбінацію символів, що починаються з позначки оберненого Стеша (””), називають знаком переходу або escape-символом. Керуюча послідовність ” означає перехід на початок нового рядка. Цей символ в лапках може знаходитися будь-де в рядку, при цьому послідовність символів, що знаходиться за ним, виводитиметься з нового рядка. Тобто результат виконання операції

cout << ” Ласкаво просимо до С++! n”;

матиме вигляд:

Ласкаво просимо

до С++!

 

1.2 ЕТАПИ ВИКОНАННЯ ПРОГРАМИ

Вихідна програма, підготовлена на мові С++ у вигляді текстового файла з розширенням *.срр (welcome.cpp), проходить 3 етапи обробки:

1)   препроцесорне перетворення тексту програми;

2)   компіляція;

3)   компоновка (редагування зв¢язків чи складання).

Після цих 3 етапів формується машинний код програми, що виконується.

Задачею препроцесора є перетворення (доповнення) тексту програми до початку її компіляції. Правила препроцесорної обробки визначаються програмістом за допомогою директив препроцесора. Директива починається з ”#” (¢дієс¢, ¢шарп¢). Наприклад,

1) #define - визначає правила заміни в тексті:

#define ZERO 0.0

Це означає, що кожне використання у програмі імені ZERO буде замінюватися на 0.0.

2) #include< ім¢я заголовного файла > - передбачена для залучення до тексту програми тексту файлу з каталогу “Заголовних файлів” INCLUDE, які постачаються разом зі стандартними бібліотеками. Кожна бібліотечна функція чи об¢єкт С++ має відповідний опис в одному з заголовних файлів (наприклад, iostream.h, stdio.h, conio.h, math.h). Список заголовних файлів визначається стандартом мови. Використання директиви include не під¢єднує відповідну стандартну бібліотеку, а лише дозволяє долучити до тексту програми описи із зазначеного заголовного файлу. В нашому випадку препроцесор обробляє директиву #include і під^єднує до вихідного тексту програми засоби для обміну з дисплеєм. Далі файл передається на компіляцію, у ньому виявляються синтаксичні помилки, які потрібно усунути програмістові. Після безпомилкової компіляції текст програми перекладається компілятором на машинну мову, далі отримуємо об^єктний файл з розширенням *.obj. Підключення об¢єктних кодів файлів з визначеннями необхідних стандартних функцій і об¢єктів з бібліотеки відбувається на етапі компоновки, тобто після компіляції. У об¢єктному коді створюваної програми ніби замуровуються дірки за допомогою кодів стандартних функцій. Хоча в заголовних файлах містяться всі описи стандартних функцій, до коду програми залучаються лише функції й об¢єкти, які використовуються в програмі.

Після компоновки утворюється модуль програми з розширенням *.ехе.

Отже, в нашому випадку, виконавши директиви, препроцесор сформує повний текст програми, компілятор створить об^єктний файл welcome.obj, за замовчуванням обравши для нього зазначене ім^я, а компоновщик (редактор зв^язків Linker) доповить програму бібліотечними функціями, наприклад, для роботи з об^єктом cout і побудує модуль welcome.exe, запустивши, який ми одержуємо на екрані бажану фразу. Схема етапів виконання програми наведена на рис. 1.1.

1.3 ПОРЯДОК ЗАПУСКУ ПРОГРАМИ

1.         Відкрийте нове вікно редагування (File > New) і надайте йому ім^я Welcome (File > Save As);

2.         У новому вікні наберіть текст програми, що наводиться у Прикладі 1.

3.         Відкомпілюйте програму (Compile > Compile або (Alt+F9)). В разі повідомлень про помилку, перевірте текст програми і усуньте невідповідності. Щоразу, вносячи зміни у вихідний текст програми, зберігайте файл (File > Save або F2). Після чого змінену програму слід відкомпілювати;

4.         Запуск відкомпільованої програми здійснюється за командою (Run > Run або Ctrl+F9). Якщо з моменту останньої компіляції вихідний код було модифіковано, ця команда виконає послідовно компіляцію і компоновку. Результат виконання програми можна переглянути, натиснувши комбінацію клавіш Alt+F5.

 


2. Форматний ввід/вивід у мові С/С++

 

2.1 ФУНКЦІЇ ВВОДУ/ВИВОДУ МОВИ С

 

У мові С++ немає вбудованих засобів вводу/виводу – вони здійснюються за допомогою функцій, типів та об^єктів, що містяться у стандартних бібліотеках. Використовується два способи: функції, успадковані з мови С та об^єкти С++.

Основні функції вводу/виводу в стилі С, опис яких міститься у заголовному файлі :

рrintf (<керуючий рядок>, <список аргументів>);

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

Специфікація перетворення має такий вигляд:

% <прапор> <розмір поля . точність> специфікація,

де прапор може набувати наступних значень:

- вирівнювання вліво числа, що виводиться (за замовчуванням виконується вирівнювання вправо);

+ виводиться знак додатного числа;

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

точність – задає точність числа, тобто кількість цифр його дробової частини;

специфікація вказує на вигляд інформації, що виводиться. У таблиці 2.1 наведено основні формати функції друку.

Таблиця 2.1

Формат Тип інформації, що виводиться
%d десяткове ціле число
% і для виведення цілих чисел зі знаком (printf (“a=%i”, -3));
%u для виводу беззнакових цілих чисел (printf(“s=%u”, s))
%c один символ
%s рядок символів
%e число з плаваючою крапкою (експоненційний запис)
%f число з плаваючою крапкою (десятковий запис) (printf(“b=%f , c=%f , d=%f ”, 3.55, 82.2, 0.555 ));
%u десяткове число без знака

 

Керуючий рядок може містити наступні керуючі символи:

– перехід на новий рядок;

– горизонтальна і v – вертикальна табуляція;

 – повернення назад на один символ;

– повернення на початок рядка;

a – звуковий сигнал;

” –лапки;

? – знак питання;

- зворотний слеш.

Список аргументів - об¢єкти, що друкуються (константи, змінні). Кількість аргументів та їх типи повинні відповідати специфікаціям перетворення в керуючому рядку.

Приклад 1.

#include

#define PI 3.1415926

void main()

{

int number=5, cost=11000, s=-777;

float bat=255, x=12.345;

printf ("%d студентів з¢їло %f бутербродів. ", number, bat);

printf ("Значення числа pi рівне%f. ", pi);

printf ("Вартість цієї машини %d%s ", cost,"у.е");

printf ("x=%-8.4f s=%5d%8.2f ", x, s, x);

}

В результаті виконання останньої функції printf() на екрані буде виведено:

х=12.3450 s= -777 12.34

Функція scanf передбачена для форматного вводу інформації довільного вигляду. Загальний вигляд функції:

scanf (<керуючий рядок>, < список адрес>);

На відміну від функції виводу printf(), scanf() використовує у списку адреси змінних, для одержання яких перед іменем змінної ставиться символ ”&”, що позначає унарну операцію одержання адреси. Для вводу значень рядкових змінних символ ”&” не використовується. При використанні формату %s рядок вводиться до першого пропуску. Вводити дані можна як в одному рядку через пропуск, так і в різних рядках.

Дану особливість ілюструє відповідна частина програми:

int course;

float grant;

char name[20];

printf ( "Вкажіть ваш курс, стипендію, ім¢я ");

scanf ( "%d%f", &course, &grant);

scanf ( "%s", name); /* ”&” відсутній при зазначенні масиву символів */

Для зміни кольору тексту використовують функції із файла : clrscr() – очищує екран; textcolor(Колір) – задає колір символів; textbackground (Колір) – встановлює колір фону. Вивід тексту на екран здійснюється за допомогою функції cprintf(), яка використовується аналогічно printf(). Зверніть увагу на те, що перехід на початок нового рядка у цій функції здійснюється за допомогою комбінації ” ”.

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


Таблиця 2.2

Колір

Константа

Значення константи

Чорний BLACK 0
Синій BLUE 1
Зелений GREEN 2
Червоний RED 4
Фіолетовий MAGENTA 5
Сірий GREY 8
Блакитний LIGHTBLUE 9
Помаранчевий LIGHTRED 12
Жовтий YELLOW 14
Білий WHITE 15

2.2 ФУНКЦІЇ ВВОДУ/ВИВОДУ ТА МАНІПУЛЯТОРИ МОВИ С++

А ось як виглядає програма вводу/виводу з використанням бібліотеки класів С++:

Приклад 2.

# include

void main()

{ int i;

cout<< “Введіть ціле число ”;

//об^єкт для вводу з клавіатури і >>розміщення у потік виводу

cin>> i;

cout<< “Ви ввели число”<< i <<”дякую!”;

}

Для форматного виводу у С++ використовуються маніпулятори, для використання яких до програми потрібно підключити заголовний файл :

setw(int) – встановлює максимальну ширину поля виводу чисел та рядків (не символів);

setprecision(int) – встановлює максимальну кількість цифр дробової частини для дійсних чисел з фіксованою крапкою;

setiosflags(ios::showpoint | ios::fixed) – вивід дійсних чисел з фіксованою крапкою;

setiosflags(ios::left) або setiosflags(ios::right) – вирівнювання по лівому або правому полю;

endl – при виводі включає у потік символ нового рядка, еквівалентний “ ” (його опис міститься у файлі iostream.h).

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

Приклад 3.

# include

#include

void main()

{float d=52.28679;

float f= 410.0;

cout<< setprecision(3);

cout<

cout<

}

Результат виводу (ˆ позначає пробіл):

ˆˆˆˆˆˆ52.287

ˆˆˆˆˆ410.000

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

 


3. Лінійні програми на С++

 

3.1 СТАНДАРТНІ ТИПИ ДАНИХ МОВИ С++

Всі об¢єкти (змінні, масиви тощо), з якими працює програма в С/С++, необхідно визначати або описувати. Найпростіша форма визначення змінної:

<тип> <список імен змінних>;

При оголошенні об¢єкти можна ініціалізувати (задавати початкове значення).

Наприклад: int j=10, m(3), n;

float c(-1.3), l=-10.23, f1;

Оголошення повідомляють компілятору про властивості та імена об¢єктів і функцій. Змінні можуть змінювати свої значення. При наданні значення змінній у комірці пам¢яті, яка відводиться під неї, розміщується код цього значення. Доступ до значення цієї змінної можливий через ім¢я змінної, а доступ до ділянки пам¢яті здійснюється за її адресою. Розмір ділянки пам¢яті, що відводиться змінній, визначається її типом. Перелік базових типів даних наведено у таблиці 3.1.

Таблиця 3.1

Тип даних Назва Розмір, біт Діапазон значень
unsigned char Беззнаковий цілий довжиною не менше 8 біт 8 0 . . 255
сhar Цілий довжиною не менше 8 біт 8 -128 . . 127
unsigned int Без знаковий цілий 16 0 . . 65535
short int (short) Короткий цілий 16 -32768 . . 32767
unsigned short Беззнаковий короткий цілий 16 0 . . 65535
int Цілий 16 -32768 . . 32767
unsigned long Беззнаковий довгий цілий 32 0 . . 4294967295
long int (long) Довгий цілий 32 -214748348 . . 2147483647
float Дійсний одинарної точності 32 3.4Е-38 . . 3.4Е+38
double Дійсний подвійної точності 64 1.7Е-308 . . 1.7Е+308
long double Дійсний максимальної точності 80 3.4Е-4932 . . 1.1Е+4932

3.2 ОПЕРАЦІЇ МОВИ С++

 

Позначки операцій – це один або декілька символів, що визначають дію над операндами. Операції поділяють на унарні, бінарні та тернарні за кількістю операндів, які беруть участь в операції (таблиця 3.2).

Таблиця 3.2.

Операція Короткий опис

Унарні операції

& Операція одержання адреси операнда
* Звернення за адресою (розіменування)
- Унарний мінус – змінює знак арифметичного операнда
~ Порозрядове інвертування внутрішнього двійкового коду (побітове заперечення)
! Логічне заперечення (НЕ) значення операнда. Цілочисельний результат 0 (якщо операнд ненульовий, тобто істинний) або 1 (якщо операнд нульовий, тобто хибний). Таким чином: !1 дорівнює 0; !2 дорівнює 0; !(-5)=0; !0 дорівнює 1.
++

Інкремент (збільшення на одиницю):

Префіксна операція (++х) збільшує операнд на 1 до його використання.

Постфіксна операція (х++) збільшує операнд на 1 після його використання.

int m=1, n=2;

int a=(m++)+n; // a=3, m=2, n=2

int b=m+(++n);// b=6, m=2, n=3

- -

Декремент (зменшення на одиницю):

Префіксна операція (--х) зменшує операнд на 1 до його використання.

Постфіксна операція (х--) зменшує операнд на 1 після його використання.

sizeof

Обчислення розміру (в байтах) об¢єкта того типу, який має операнд. Має дві форми:

1) sizeof (вираз);

sizeof(1.0); // Результат - 8,

Дійсні константи за замовчуванням мають тип double;

2) sizeof (тип)

sizeof (char); // Результат – 1.

Бінарні операції

Арифметичні операції
+ Бінарний плюс (додавання арифметичних операндів)
- Бінарний мінус (віднімання арифметичних операндів)
Мультиплікативні
* Добуток операндів арифметичного типу
/ Ділення операндів арифметичного типу (якщо операнди цілочисельні, абсолютне значення результату заокруглюється до цілого, тобто 20/3 дорівнює 6)
% Одержання залишку від ділення целочисельних операндів (13%4 = 1)
Операції зсуву (визначені лише для цілочисельних операндів)
<<  Зсув вліво бітового представлення значення лівого цілочисельного операнда на кількість розрядів, рівну значенню правого операнда (4<<2 дорівнює 16, т.я. код 4 100, а звільнені розряду обнуляються, 10000 – код 16)
>>  Зсув вправо бітового представлення значення правого цілочисельного операнда на кількість розрядів, рівну значенню правого операнда
Порозрядні операції
& Порозрядна кон^юнкція (І) бітових представлень значень цілочисельних операндів
| Порозрядна диз^юнкція (АБО) бітових представлень значень цілочисельних операндів
^ Порозрядне виключне АБО бітових представлень значень цілочисельних операндів
Операції порівняння
Менше, ніж
Більше, ніж
<= Менше або рівне
>= Більше або рівне
= = Рівне
!= Не рівне
Логічні бінарні операції
&& Кон^юнкція (І) цілочисельних операндів або відношень, цілочисельний результат (0) або (1)
|| Диз^юнкція (АБО) цілочисельних операндів або відношень, цілочисельний результат (0) або (1) (умова 0

Тернарна операція

Умовна операція
? :

Вираз1 ? Вираз2 : Вираз3;

Першим вираховується значення Виразу1. Якщо воно істинне, тоді обчислюється значення Виразу2, яке стає результатом. Якщо при обчисленні Виразу1 одержуємо 0, тоді в якості результату береться значення Виразу3.

Наприклад:

х<0 ? -x : x ; //обчислюється абсолютна величина x.


Таблиця 3.3. Пріоритет виконання операцій

Ранг Операції Напрямок виконання
1 () (виклик функції), [], ->, "." >>> 
2 !, ~, +, - (унарні), ++, --, *, (тип), sizeof, (new,delete – Сі++) <<< 
3 .* , ->* - Сі++ >>> 
4 *, /, % (бінарні) >>> 
5 +, - (бінарні) >>> 
6 <<, >> >>> 
7 <, <=, =>, > >>> 
8 ==, != >>> 
9 & (порозрядна) >>> 
10 ^ >>> 
11 | (порозрядна) >>> 
12 && (логічна) >>> 
13 || (логічна) >>> 
14 ?: (тернарна) <<< 
15 =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=,>>= <<< 
16 "," (кома) >>> 

Основні матичні функції мови С/С++, опис яких міститься у файлі , наведені у таблиці 3.4.

Таблиця 3.4

Матичний запис Функція Пояснення Приклад
arccos x acos Повертає арккосинус кута, рівного х радіан acos(x);
arcsin x asin Повертає арксинус аргументу х в радіанах asin(x);
arctg x atan Повертає арктангенс аргументу х в радіанах atan(x);
аrctg(x/у) atan2 Повертає арктангенс відношення параметрів х та у в радіанах atan2(x, y);
- ceil Заокруглює дійсне значення х до найближчого більшого цілого і повертає його як дійсне ceil(x);
cosx cos Повертає косинус кута, рівного х радіан cos(x);

chx=1/2(ex+e-x)

cosh Повертає гіперболічний косинус аргументу, рівного х радіан cosh(x);

ex

exp Повертає результат піднесення числа е до степені х exp(x);
|x| fabs Повертає модуль дійсного числа х fabs(x);
- floor Заокруглює дійсне число до найближчого меншого числа і повертає результат як дійсний floor(x);
- fmod Повертає залишок ділення х на у. Аналогічна операції %, але працює з дійсними числами fmod(x, y);
ln x log Повертає значення натурального логарифму х log(x);
lg x log10 Повертає значення десяткового логарифму х log10(x);

xy

pow Вираховує значення числа х у степені у pow(x, y);
sinx sin Повертає синус кута, рівного х радіан sin(x);

sh x=1/2 (ex-e-x)

sinh Повертає гіперболічний синус кута, рівного х радіан sinh(x);

sqrt Визначає корінь квадратний числа х sqrt(x);
tg x tan Повертає тангенс кута, рівного х радіан tan(x);
tgh x tanh Повертає гіперболічний тангенс кута, рівного х радіан tanh(x);

Таблиця 3.5 Операції присвоювання

Операція Пояснення Приклад
= Присвоїти значення виразу-операнду з правої частини операнду лівої частини Р=10.5-3*х
*= Присвоїти операнду лівої частини добуток значень обох операндів Р*=2 еквівалентно Р=Р*2
/= Присвоїти операнду лівої частини результат від ділення значення лівого операнда на значення правого

Р/=(2.2-х) еквівалентно

Р=Р/(2.2-х)

%= Присвоїти лівому операнду залишок від ділення цілочисельного значення лівого операнда на цілочисельне значення правого операнда Р%=3 еквівалентно Р=Р%3
+= Присвоїти операнду лівої частини суму значень обох операндів А+=В еквівалентно А=А+В
-= Присвоїти операнду лівої частини різницю значень лівого і правого операндів Х-=3.4-у еквівалентно Х=Х-(3.4-у)

4. Основні оператори мови С++

 

4.1 СКЛАДОВІ ОПЕРАТОРИ

Складовий оператор – це два або більше оператори, що повинні виконуватися у певній частині програми як один оператор. До складових операторів належать власне складовий оператор та блок. В обох випадках - це послідовність операторів, розміщених у фігурних дужках. Блок відрізняється від складового оператора наявністю в його тілі оператора визначення об^єкту (змінної, константи, масиву тощо).

Наприклад:

{n++; summa+=n;}//це складовий оператор

{int n=0; n++;summa+=n;} //це блок

4.2 ОПЕРАТОРИ РОЗГАЛУЖЕННЯ

 

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

Загальна форма запису:

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

else оператор2;

Наприклад, для знаходження коренів квадратного рівняння використовується запис:

if (d>=0)

{x1=(-b-sqrt(d))/(2*a);

x2=(-b+sqrt(d))/(2*a);

cout<< “ x1=”<

}

else cout<<“ Розв¢язку немає”;

Якщо оператор1 та/або оператор2 містять два або більше операторів, їх беруть у фігурні дужки {}, тобто вони є складовими. Оператор if перевіряє істинність чи хибність умови. Якщо умова справджується (не рівна 0), тоді виконується оператор1, інакше, при хибності умови (==0), виконується оператор2.

Другу частину оператора (else оператор2;) можна опускати. Така його форма має назву “скороченої”. Тоді у випадку хибності умови, керування передається до оператора, що йде услід за умовним оператором.

Якщо оператор1 і оператор2 в свою чергу є операторами if , вони є вкладеними.

Загальний вигляд вкладеного оператора if: if (умова1) оператор1;

else if (умова2) оператор2;

else оператор3;

В якості умов у мовах С/С++ використовуються стандартні операції відношення: <, <=, >, >=, !=, ==. Пари наведених символів не можна відокремлювати чи переставляти.

Для об^єднання в умові декількох умов використовуються логічні операції. Наведемо їх перелік в порядку спадання пріоритету: ! (заперечення або логічне НІ), && (кон^юнкція або логічне І), || (диз^юнкція або логічне АБО). Між позначками && та || не дозволяються пробіли.

Наприклад: 0

((!x)&&(y>0)||((z==1)&&(k>0))

Оператор вибору switch подібний до умовного оператора if, проте у ньому замість виразу-умови використовується вираз, результатом якого може бути декілька цілочисельних значень, кожне з яких, вимагає виконання свого оператора. Отже, програму можна спрямувати більше ніж у двох напрямках.

Загальна форма запису оператора вибору:

switch(вираз)

{ case consnant1: оператори; break;

сase consnantN: оператори;break;

default: оператори; },

де consnant1…consnantN - цілі або символьні константи. При виконанні оператора switch, обраховується вираз, записаний після switch і його значення послідовно порівнюється з константами, записаними після case. При першому ж співпаданні виконуються оператори, позначені даною міткою. Якщо виконувані оператори не містять оператор переходу break, далі виконуватимуться оператори усіх наступних варіантів. Якщо значення виразу, записаного після switch, не співпало з жодною константою, виконуватимуться оператори після мітки default, яка не є обов^язковою.

4.3 ОператорИ циклУ

 

Цикл з параметром for:

Основна форма запису:

for (вираз_1; вираз_2; вираз_3 ) оператор;

де вираз_1 – ініціалізація початкового значення параметру циклу;

вираз_2 – перевірка умови на продовження циклу;

вираз_3 – зміна параметру циклу з кожною ітерацією (корекція);

оператор – тіло циклу, простий або складовий оператор.

Цикл продовжується до тих пір, поки вираз_3 не стане рівним 0. Будь-який вираз можна опускати, залишаючи натомість “ ; ”.

Приклади використання циклу з параметром:

1)  Зменшення параметра:

for ( n=10; n>0; n--)

{ <тіло циклу>}

2)  Зміна кроку коректування:

for ( n=2; n>60; n+=13)

{ <тіло циклу>}

3)Корекція може здійснюватися не лише за допомогою додавання чи віднімання:

for ( d=100.0; d<150.0;d*=1.1)

{ <тіло циклу>}

for (x=1;y<=75;y=5*(x++)+10)

{ <тіло циклу>}

5)  Можна використовувати декілька виразів ініціалізації або модифікації:

for (x=1, y=0; x<10;x++,y+=x)

{ <тіло циклу>}.

Цикл з передумовою while:

Основна форма запису:

while (умова)

оператор;

де оператор – це простий, складовий або порожній оператор.

Цикл виконується до тих пір, поки умова приймає значення “true”, тобто вираз у дужках повертає ненульовий результат. У циклі з передумовою спочатку перевіряється істинність умови, а потім виконується оператор тіла циклу. Тому цикл while не виконується жодного разу, якщо від початку умова буде хибною.

Цикл з післяумовою do – while:

Основна форма запису:

do

оператор;

while (умова);

де оператор – це простий, складовий чи порожній оператор.

Тіло циклу виконується до тих пір, поки умова справджується. Оскільки в циклі do–while умова перевіряється в кінці, оператор тіла циклу виконуватиметься хоча б один раз.

Для запобігання безкінечності циклу в тілі циклів while та do–while потрібно передбачити зміну параметрів, які входять до умови.


4.4 ОПЕРАТОРИ ПЕРЕХОДУ

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

1)  goto < мітка> - оператор безумовного переходу. Керування передається оператору з даною міткою:

<мітка>: оператор;

В мові С мітка не декларується.

2)  break - оператор перериває цикл або перемикач, управління передається на перший наступний оператор;

while (умова)

{< оператори>

if (<вираз-умова>) break;

<оператори>}.

Тобто оператор break доцільно використовувати, коли умову продовження ітерації потрібно перевіряти в тілі циклу.

2)  continue – припинення поточної і перехід до наступної ітерації циклу. Використовується, коли тіло циклу містить розгалуження.

3) return – здійснює повернення результату з тіла функції.

 


5. Вказівники та операції над ними

5.1 ПОНЯТТЯ ВКАЗІВНИКА

Кожна змінна у програмі - це об^єкт, який володіє ім^ям і значенням. Після визначення змінної з ініціалізацією всі звернення у програмі до неї за іменем замінюються компілятором на адресу іменованої області оперативної пам^яті, в якій зберігається значення змінної (Рис. 5.1). Програміст може визначити власні змінні для збереження адрес областей пам^яті. Такі змінні називають вказівниками.

int a=10;


Рис. 5.1.

Вказівник визначається наступним чином:

<тип> *< ідентифікатор> <ініціалі затор>;

Приклад 1. Визначення вказівників

int* pa=&a;// вказівник ра містить значення адреси змінної а

float *ptr (NULL); // Нульовий вказівник на об^єкт типу float

char*p; // Неініціалізований вказівник на об^єкт типу char

Значення адреси змінної одержується за допомогою унарної операції ”&”.

Для доступу до комірки пам^яті, виділеної під змінну через вказівник до останнього, слід застосувати унарну операцію розіменування ”*”.

Приклад 2. Непряма адресація через вказівник

int x=2; //змінна типу int

int *y =&x;// вказівник на елемент даних типу int

*y=1; // через вказівник до поля x вноситься значення 1,

//тобто x=1

p=new char(12);

В останньому операторі прикладу 2 неініціалізований вказівник р, описаний у прикладі 1, асоціюється з ділянкою у динамічній пам^яті під змінну типу char, до якої заноситься значення 12.

5.2 ДІЇ НАД ВКАЗІВНИКАМИ

Приклад 3: Дії над вказівниками

int a=5;

int *p=&a, *p2, *p2; p2=p1=p;

++p1; p2+=2;

cout<<“a=”<

cout<<” p=”<<*p<<” p=”<

Результат виконання:

a=5, *p=5, p=FFC8, p1=FFCC, p2=FFD0.

Конкретні значення адрес залежать від низки причин: архітектури комп^ютера, типу і розміру оперативної пам^яті тощо.

З арифметичних операцій між вказівниками дозволена лише операція віднімання.

Різницею двох вказівників одного типу є відстань між двома областями пам^яті, кратна довжині (в байтах) об^єкта того типу, якому відповідає вказівник. Різниця однотипних вказівників, що адресують суміжні об^єкти, за абсолютною величиною рівна одиниці. Адреси змінних позначаються цілочисельними 16-ковими константами.

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

До вказівника дозволено додавати і віднімати цілочисельну константу (k). При цьому він пересувається між ділянками пам^яті на величину k*(sizeof(type)).


6. Робота з одновимірними масивами

 

6.1 СТАТИЧНІ ТА ДИНАМІЧНІ МАСИВИ

 

Масив – це кінцева послідовність даних одного типу. Кожен елемент масиву має однакове ім^я – ім^я масиву, і відрізняється індексом (ціле число), за яким здійснюється доступ до елемента масиву. Індекси масивів у С/С++ починаються з 0. У програмі одновимірний масив оголошується наступним чином:

<тип> <ім^я масиву> [розмір] <ініціалізація>; ,

де розмір – кількість елементів одновимірного масиву.

Після визначення ім^я масиву стає вказівником-константою, значення якого є незмінним і становить адресу першого (нульового) елемента масиву.

За способом розміщення масиви поділяються на статичні та динамічні. Розмір статичного масиву можна задавати константою або константним виразом. Оскільки ділянка у оперативній пам^яті під масив задається на етапі компіляції і її розмір визначається типом елементів масиву та їх кількістю, розмірність масиву повинна бути визначена у тексті програми, а не підчас її виконання. Для визначення масиву змінного розміру використовується механізм динамічного виділення пам^яті.

Наприклад:

- оголошення одновимірного масиву з п^яти елементів цілого типу:

int a[5];

- динамічне виділення пам^яті під 10 цілочисельних елементів:

int*m=new int [10];

Враховуючи те, що ім¢я масиву є вказівником, зрозумілим стає зміст останньої операції: вказівникові на int m присвоюється початкова адреса ділянки пам¢яті, виділеної у динамічній області під 10 цілочисельних елементів.

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

Натомість ініціалізацію статичних масивів можна здійснювати при їх визначенні. При цьому слід зауважити, що у С/С++ не перевіряється вихід індексу за межі масиву.

Наприклад:

double d[] = {1, 2, 3, 4, 5};

float f[10]={1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.0};

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

Для звернення до елементів масивів використовуються два способи, наприклад до 4-го (по порядку) елемента масиву a можна звернутися як a[3] або *(a+3). Останнє звернення базується на факті, що ім^я масиву є одночасно вказівником на його нульовий елемент, а зміщення вказівника у пам^яті відбувається на величину індексу помножену на розмір типу елементів масиву у байтах.

Пам^ять, зарезервовану під динамічний масив за допомогою new[ ], потрібно звільняти оператором delete [] <ім¢я массиву>.

Отже, якщо кількість елементів масиву відома до виконання програми, краще використовувати статичний масив, розмірність якого позначити як значення іменованої константи. Якщо розмірність масиву необхідно задавати в процесі виконання програми (до введення його елементів), то доцільно створювати динамічний масив.

6.2 РЯДКИ, ЯК ОДНОВИМІРНІ МАСИВИ СИМВОЛІВ

 

У мовах С/С++ немає окремого типу даних “рядок символів”, подібно до типу string у алгоритмічній мові PASCAL. Тому робота з рядками реалізована шляхом використання одновимірних масивів типу char. Рядок символів – це одновимірний масив типу char, останнім елементом якого є нульовий байт. Нульовий байт – це байт, кожен біт якого рівний нулю, при цьому для нульового байта визначена символьная константа ¢¢ (ознака закінчення рядка або нуль-термінатор). Тому, якщо рядок містить k символів, в описі масиву потрібно вказати розмірність k+1.

Так, для збереження у масиві рядкової константи “Лабораторна робота з рядками”, необхідно описати масив char s[29]. В кінці рядкової константи символ ´ ¢ вказувати не потрібно, оскільки це зробить компілятор мови С.

Рядки можна

а) ініціалізувати при декларуванні.

Наприклад:

charS1[10]=”123456789”,S2[]=”abcdefg”,S3[]={‘1^,‘2^,‘3^,‘^};,

де в двох останніх випадках розмір рядків буде встановлений за кількістю символів;

б) вводити з клавіатури, не використовуючи при цьому оператора циклу, подібно звичайним масивам.

Наприклад:

char Tоріс[20];

cout<<”Введіть тему лабораторної роботи: ”; cin>>Tоріс;


7. Двовимірні масиви

 

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

<тип> <ім^я> [<розмір1>][<розмір2>];

 

Наприклад:

int a[3][5]; // Цілочисельна матриця з 3 рядків і 5 стовпців

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

a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24

| -0-ий рядок- - |-- 1-ий рядок - |- - 2-ий рядок- - |

Для доступу до окремого елемента двовимірного масиву використовується конструкція, яка має вигляд a[i][j], де i – номер рядка, j – номер стовпчика. Кожен індекс може змінюватися від 0 до значення, яке на одиницю менше за значення відповідної розмірності.

Як і для одновимірного масиву, при описі двовимірного масиву можна задавати початкові значення його елементів. Їх записують у фігурних дужках. Елементи масиву ініціалізуються в порядку їх розміщення у пам^яті.

Наприклад: оператор

int с[3][4] = {1,2,34,2,3,4,1,3,4,1,2};

визначає матрицю з наступними значеннями елементів: 1 2 3 4

2 3 4 1

3 4 1 2

Можна задавати початкові значення не для всіх елементів масиву. Для цього список значень для кожного рядка береться додатково у фігурні дужки. Наприклад:

int d[3][4] = {{0,1,2},{9,-2},{-7,1,6,8}};

В даному випадку розмірність, що позначає кількість рядків, можна не вказувати.

Для створення динамічного двовимірного масиву необхідно вказати в операції new всі його розмірності, причому ліва розмірність (кількість рядків) може бути змінною:

int nriad=5;

int **m=(int**) new int[nriad][10];

Більш ефективний і безпечний спосіб виділення пам^яті під двовимірний масив, коли обидві його розмірності вказуються на етапі виконання програми, тобто є змінними, наведено нижче:

int nriad, nstp;

cout <<”Введіть кількість рядків та стовпців:”;

cin >> nriad >> nstp;

int**a = new int *[nriad];// 1

for (int i=0; i < nriad; i++)// 2

a[i] = new int[nstp];// 3

В операторі 1 оголошується змінна типу ”вказівник на вказівник на int” і виділяється пам^ять під масив вказівників на рядки масиву (nriad – кількість рядків). В операторі 2 організовано цикл для виділення пам^яті під кожен рядок масиву. В операторі 3 кожному елементу масиву вказівників на рядки присвоюється адреса початку ділянки пам^яті, виділеної під рядок двовимірного масиву з кількістю елементів типу int у ній, рівною nstp


8. Символьна інформація та рядки

 

8.1 ЗБЕРЕЖЕННЯ СИМВОЛЬНОЇ ІНФОРМАЦІЇ

Для символьних даних в C/С++ введено тип char. Для представлення символьної інформації використовуються символи, символьні змінні і текстові константи. Приклади:

const char c=^c^; //символ-константа – займає один байт

char a,b; // символьні змінні, займають по одному байту

const char *s=“Приклад рядка ” ; // рядкова константа

Рядок в С++ - це масив символів, що закінчується нуль-символом ‘^. За місцезнаходженням цього символу визначається фактична довжина рядка. Кількість елементів у такому масиві на 1 більше за зображення рядка (рис. 8.1).

A A

“A”

рядок (2 байти)

‘A^

символ (1байт)

Рис. 8.1.

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

Приклади:

char s1[10]="string1"; // масив символів з десяти елементів

char s3[]={‘s^,^t^,^a^,‘r^,^t^,^^}; // масив з 6 елементів типу char

сhar *s4="string4"; // вказівник-змінна на рядок

char *s=”String5”; // виділяється 8 байтів для рядка

char *sss=new char[10]; /* виділяється динамічна пам^ять

під 10 елементів типу char*/

strcpy(sss,”Thanks”);// у цю область пам^яті копіюється рядок.


8.2 ФУНКЦІЇ ВВОДУ/ВИВОДУ ПРИ РОБОТІ З РЯДКАМИ

Для вводу і виводу символьних даних у бібліотеці мови С (файл ) визначені наступні функції:

int getchar() - здійснює введення одного символу з вхідного потоку і повертає один байт інформації (символ) у вигляді значення типу int. Це робиться для розпізнавання ситуації, коли при зчитуванні буде досягнуто кінець файлу.

int putchar (int c) – розміщує в стандартний вихідний потік символ c.

Приклад:

# include

void main()

{char c, d;

c=getchar(); putchar(c);

d=getchar(); putchar(d);

}

char* gets(char*s) – зчитує рядок s із стандартного потоку до появи символу ‘ ^, сам символ ‘ ^ у рядок не заноситься. Повертає вказівник на цей рядок.

int puts(const char* s) – записує рядок у стандартний потік виводу, додаючи в кінці рядка символ ‘ ^, у випадку вдалого завершення повертає значення більше або рівне 0 і від^ємне значення у випадку помилки.

Також для вводу/виводу рядка можна використовувати функції scanf/printf, відповідно, задавши специфікатор формату %s:

# include

void main(){

const int n=10;

char s[n];

scanf(“%s”, s); printf(“%s”, s);}

Ім^я масиву є вказівником-константою на початок рядка, тому не слід застосовувати операцію взяття адреси (&), що зазвичай використовується з функцією вводу scanf. Ввід буде здійснюватися до першого символу пропуску. Для того щоб ввести рядок, який складається з декількох слів, використовується специфікатор %c (символи) із зазначенням у ньому максимальної кількості символів, що вводяться, наприклад:

scanf(“%10c”, s);

При виводі рядка на екран можна в специфікації %s зазначити кількість символів, які відводяться під рядок:

printf(“%15s”, s);

Функції вводу/виводу мови С++, описані у заголовному файлі <iostream.h>:

cin>>s; //ввід рядка зі стандартного потоку до появи першого пропуску.

При введенні, наприклад, рядка “Ваня Іванов” в рядок s буде записано лише перше слово рядка, а саме “Ваня”.

cout<

Якщо потрібно ввести рядок, який складається з декількох слів, в одну рядкову змінну, використовують методи getline або get класу istream, об^єктом якого є cin. Виклик цього методу здійснюється наступним чином: після імені об^єкту cin ставиться крапка, за якою записується ім^я методу:

#include

int main()

{const in n=80;

char s[n];

cin.getline(s, n); cout<

cin.get(s, n); cout<< s}

Метод getline зчитує з вхідного потоку n-1 символів або менше (якщо символ переводу рядка зустрінеться раніше) і записує їх у рядкову змінну s. Символ переводу рядка також зчитується (видаляється) з вхідного потоку, але не записується у рядкову змінну, замість нього розміщується завершальний ^^. Якщо в рядку вихідних даних більше за n-1 символів, наступне введення буде виконуватися з того ж рядка, починаючи з першого символу, що не був зчитаний.

Метод get працює аналогічно, але залишає в потоці символ переводу рядка. До рядкової змінної додається завершальний ^^.

8.3 СПЕЦІАЛЬНІ ФУНКЦІЇ ДЛЯ РОБОТИ З РЯДКАМИ ТА СИМВОЛАМИ

 

Для рядків не визначено операцій присвоювання, додавання, порівняння, оскільки рядок не є основним типом даних. Для роботи з рядками використовуються спеціальні бібліотечні функції, опис яких міститься у файлі <string.h>. Деякі з цих функцій наведено у таблиці 8.1:

Таблиця 8.1 Функції стандартної бібліотеки для роботи з рядками – файл <string.h>

Прототип функції Короткий опис та використання Пояснення

unsigned strlen(const char*s);

Обчислює довжину рядка s.

strlen(s);

Повертає фактичну довжину рядка, не враховуючи нуль-символ

int strcmp(const char*s1, const char *s2);

Порівнює рядки s1 і s2.

strcmp(s1, s2);

Якщо s1s1 – результат додатний.

int strncmp(const char*s1, const char *s2, n);

Порівнює перші n символів рядків s1 і s2.

strncmp( s1, s2, n);

Якщо n(s1)s1 – результат додатний.

char*strcpy(char*s1, const char*s2);

Копіює символи рядка s2 у рядок s1. strcpy(s1, s2); Нуль-символ при цьому теж включається

char*strncpy(char*s1, const char*s2, int n);

Копіює n символів рядка s2 у рядок s1.

strncpy(s1,s2,n);

Кінець рядка відкидається. Якщо нуль-символ у вихідному рядку зустрінеться раніше, копіювання припиняється, а решта символів рядка доповнюються ‘^-ми.

char*strcat(char*s1, const char*s2);

Дописує рядок s2 до рядка s1.

strcat(s1, s2);

Перший символ s2 записується на місце нуль-символу рядка s1. До результуючого s1 додається ‘^.

char*strncat(char*s1, const char*s2, size_t n);

Дописуються перші n символів рядка s2 до рядка s1.

strncat(s1,s2,5);

n-символів рядка s2 записується до s1, починаючи з місця нуль-символу s1.

char* strсhr(char*s, int ch)

Шукає символ ch у рядку s.

strchr(s, ch);

Повертає вказівник на перше входження символу в рядок справа. Якщо його немає – повертається NULL

char* strrev(char *s1)

Змінює порядок символів у рядку s1 на протилежний.

strrev(s1, s2);

Дзеркальне відображення рядка s1.

char *strstr(char*s1, char*s2)

Шукає підрядок у рядку.

strstr(s1, s2);

Пошук першого входження s2 у s1. В разі вдалого пошуку повертається вказівник на елемент з s1, з якого починається s2, інакше – NULL.

char *strtok(char*s1, char*s2)

Розбиває рядок на лексеми.

strtok(s1, s2);

Функція повертає вказівник на лексему в s1, відокремлену символом з набору s2 (пробілами або розділовими знаками).

Для роботи з символами у файлі <ctype.h> стандартної бібліотеки визначено функції, наведені в таблиці 8.2:

Таблиця 8.2 Функції стандартної бібліотеки для роботи з символами-файл

Прототип функції Короткий опис та використання Пояснення

int isalnum(int ch)

Перевіряє чи є символ ch буквою або цифрою (A-Z, a-z, 0-9).

isalnum(ch);

Повертається true, якщо ch є буквою або цифрою, інакше false

int isalpha(int ch)

Перевіряє чи є символ ch буквою (A-Z, a-z). isalpha(ch); Повертається true, якщо ch є буквою, інакше false

int isspace(int ch)

Перевіряє чи є символ ch пропуском (пробіл, табуляція, символ нового рядка, нової сторінки). isspace(ch); Повертається true, якщо ch є узагальненим пробілом, інакше false

int isdigit(int ch)

Перевіряє чи є символ цифрою (0-9).

isdigit(ch);

Повертається true, якщо ch є цифрою, інакше false

int islower(int ch)

Перевіряє чи є символ буквою нижнього регістру (a-z).

islower(ch);

Повертається true, якщо ch є буквою нижнього регістру, інакше false

int isupper(int ch)

Перевіряє чи є символ буквою верхнього регістру (A-Z).

isupper(ch);

Повертається true, якщо ch є буквою верхнього регістру, інакше false

int ispunct(int ch)

Перевіряє чи є символ символом пунктуації (. , : ; ? ! тощо).

ispunct(ch);

Повертається true, якщо ch є символом пунктуації, інакше false

int tolower (int ch)

Повертає символ у нижньому регістрі.

tolower (int ch);

Одержує символ ch і повертає його у нижньому регістрі

int toupper(int ch)

Повертає символ у верхньому регістрі.

toupper(int ch);

Одержує символ ch і повертає його у верхньому регістрі

Приклад 1:

Дано рядок символів, що складається зі слів, слова відокремлені пропусками. Видалити з рядка всі слова, що починаються з цифри.

#include

#include

#include

void main()

{const int n=250;// розмірність рядкового масиву

char s[n], // вихідний рядок

w[25], // проміжний масив для збереження слова з рядка

*mas[10];// масив вказівників для збереження слів з рядка

cout<<“ Bведiть рядок: ”;

cin.getline(s, n);

int k=0, t=0, i, len, j;

len=strlen(s);

while(t

{ for(j=0,i=t; isspace(s[i])==0; i++,j++)

w[j]=s[i]; // виокремлюємо слово до пробілу

w[j]=^^;// формуємо кінець слова

strcpy(mas[k],w);// копіюємо слово у масив

k++;// збільшуємо лічильник слів у рядку

t=i+1;// перехід через пробіл до наступного слова у

// вихідному рядку s

}

strcpy(s,” ”);// очищуємо вихідний рядок

for(t=0; t

if(isalpha(mas[t][0])!=0){// якщо перший символ не цифра

{strcat(s,mas[t]);// дописуємо слово в оновлений рядок

strcat(s,” “);// додаємо пробіл після слова

}

cout<<” Новий рядок: ”<< s;// виводимо результат

}

Приклад 2:

Програма яка підраховує скільки разів задане слово зустрічається у тексті файлу. Наприклад, у англійській поговірці “Don^t trouble trouble until trouble troubles you” слово “trouble” у чистому вигляді зустрічається 3 рази.

#include

#include

# include

void main()

{const int len=81;

char word[len], line [len];// масиви для слова і рядка

cout<< “Введiть слово для пошуку:”; cin>> word;

int_lword=strlen(word);// визначення довжини слова

ifstream fin (“text.txt”, ios:: in | ios:: nocreate);

if(!fin) {cout<< “Помилка відкриття файлу.”<

int count=0;

// поки не досягнуто нуль-символу

while(fin.getline(line, len))

{char *p=line;// вказівникові присвоєно адресу рядка

while(p=strstr(p,word))/* якщо слово знайдено

вказівник стає на позицію

початку слова у рядку*/

{ // адреса початку входження слова передається с

char * c=p;

p+=l_word;// перехід вказівника р через слово

// слово не на початку рядка

if(c!=line)

/* Чи є символ перед словом розділювачем? Інакше –

перейти до наступної ітерації */

if(!ispunct(*(c-2))&& isspace(*(c-1))) continue;

// Чи є символ після слова розділювачем?

if (ispunct(*p)|| isspace(*p)|| (*p==^^)) count ++;

}

}

cout << “Слово зустрічається в тексті ”<< count;

<<” разів”<

}

 


9. Функції користувача

 

9.1 ФУНКЦІЇ: ВИЗНАЧЕННЯ, ОПИС, ВИКЛИК

Функцію в С++ можна розглядати:

·   як один з похідних типів даних (поряд з масивами і вказівниками);

·   як мінімальний виконуваний модуль програми (підпрограму).

Всі функції мають однаковий формат визначення:

<тип><ім^я_функції>(<список_формальних_параметрів>)

<тіло_функції>,

де <тип> - тип результату, який повертається функцією; в разі, якщо функція не повертає ніякого значення, її специфікують типом void і називають “порожньою”. Найчастіше, це функції, які виводять на екран повідомлення чи виконують деякі зміни параметрів, проте не можуть передати певний результат іншим змінним при виклику.

<ім^я_функції> - або main для головної функції, або довільний ідентифікатор;

<список_формальних_параметрів> - або порожній ( ), або список, кожен елемент якого записується як:

<тип> <ім^я_формального_параметру>

Наприклад:

(int k )

(char i, char j, int z)

<тіло_функції> - це набір операторів, що виконуються у фігурних дужках {} при виклику функції. Тіло функції може бути складовим оператором або блоком. Визначення функцій не можуть бути вкладеними.

Для передачі результату з функції у функцію, що її викликала, використовується оператор return. Його можна використовувати у двох формах:

1)         return 0; - завершує функцію, яка не повертає ніякого значення (тобто перед її іменем вказано тип void);

2)         return <вираз>; - повертає значення виразу, тип виразу повинен співпадати з типом функції.

Приклад 1:

int op (char c, int x, int y)

{switch (c)

{case ‘+^ : return x+y;

case ‘-^ : return x-y;

case ‘*^ : return x*y;

case ‘/^ : return x/y;

default: cout<<“ Операція не визначена!”;

return 0;

}

}

Приклад 2.

float cube(float d)

{return d*d*d;}

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

Виклик функції має наступний вигляд:

<ім^я_функції>(<список фактичних параметрів>);

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

Наприклад:,

void main(){float s, f=0.55; s=cube(f);…}

В якості фактичних параметрів також можуть виступати явно задані константні значення:

Наприклад, виклик функції з прикладу 1 має наступний вигляд:

c = op ( ‘+^, 5 ,4 );

Оскільки визначення функцій не можуть міститися всередині блоків та складових операторів, тобто в інших функціях, у програмі вони можуть розміщуватися як до, так і після функції, яка їх викликає. В останньому випадку перед використанням функції у програмі необхідно розмістити її опис, або прототип, інакше виникатимуть проблеми. Компілятор передусім послідовно перевіряє коректність виклику та використання об¢єктів у програмі, при виявленні функції, яка не була описана чи визначена раніше, видасть повідомлення про помилку і вказівку про те, що функція повинна містити прототип. Те саме повідомлення Ви побачите на екрані, якщо використаєте у програмі функцію зі стандартних бібліотек і не під¢єднаєте заголовний файл, у якому вона описана. Прототип функції користувача багато в чому нагадує заголовок функції і має наступний формат:

<тип><ім^я_функції>(<список_формальних_параметрів>);

Головною відмінністю є наявність в кінці опису крапки з комою.

Так, прототипи функцій з прикладів 1 та 2 матимуть вигляд:

cube(float);

op(char c, int, int);

Прототип надає компіляторові інформацію про тип та ім¢я функції, а також про типи, кількість та порядок розміщення параметрів, які їй можна передавати. Зважаючи на це, імена формальних параметрів зазначати необов¢язково. Прототип являє собою зразок для здійснення синтаксичної перевірки компілятором.

9.2 ПЕРЕДАЧА МАСИВІВ У ФУНКЦІЮ

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

Приклад 3: Обчислення суми елементів масиву

int sum (int n, int a[] )

{ int i, s=0;

for( i=0; i

s+=a[i];

return s;

}

void main()

{ int a[]={ 3, 5, 7, 9, 11, 13, 15 };

int s = sum( 7, a );

cout<

}

Рядки в якості фактичних параметрів можуть визначатися або як одновимірні масиви типу char[], або як вказівники типу char*. На відміну від звичайних масивів, для рядків немає необхідності явно вказувати довжину рядка, оскільки будь-який рядок обмежується нуль-символом.

При передачі у функцію двовимірного масиву в якості параметру так само необхідно задавати кінцеві розміри масиву у заголовку функції. Робити це можна:

а) явним чином (а[3][4] тоді функція працюватиме з масивами лише заданої розмірності);

б) можна спробувати для квадратної матриці через додатковий параметр ввести розмірність (void matrix(double x[][], int n)), де n – порядок квадратної матриці, а double x[][] – спроба визначення двовимірного масиву зі заздалегідь невизначеними розмірами. В результаті на таку спробу компілятор відповість: Error…: Size of type is unknown or zero;

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

Приклад 4.

# include

//Функція транспонування квадратної матриці

void trans (int n, double*p[])

{double x;

for (int i=0; i

for(int j=i+1; j

{x=p[i][j];

p[i][j]=p[j][i];

p[j][i]=x;

}

}

void main(){

// Задано масив для транспонування

double A[4][4]={11, 12, 13, 14

21, 22, 23, 24

31, 32, 33, 34

41, 42, 43, 44};

// Допоміжний двовимірний масив вказівників

double * ptr[]={(double*)&A[0], (double*)&A[1],

(double*)&A[2], (double*)&A[3]};

// Виклик функції

int n=4;

trans(n, ptr);

for(int i=0; i

{cout<<” Рядок ”<<(i+1)<<”:”;

for(int j=0; j

cout<<” ”<< A[i][j];

}

}

 

9.3 ПЕРЕВАНТАЖЕННЯ ФУНКЦІЙ У С++

Перевантаження полягає в тому, що функція з одним іменем по різному виконується і повертає значення різних типів при передачі до неї фактичних параметрів у різній кількості та з різними типами. Для забезпечення перевантаження функцій необхідно для одного імені функції визначити заголовок і набір операторів для всіх функцій, що пов^язані з ним.

Приклад 5:

#include

int max_element ( int n, int a[])

// знаходить максимальний елемент для масиву типу int

{

int max=a[0];

for ( i=1; i

if (a[i]>max) max=a[i];

return max;

}

long max_element ( int n, long a[])

// знаходить максимальний елемент для масиву типу long

{

long max=a[0];

for ( i=1; i

if (a[i]>max) max=a[i];

return max;

}

double max_element ( int n, double a[])

// знаходить максимальний елемент для масиву типу double

{

double max=a[0];

for ( i=1; i

if (a[i]>max) max=a[i];

return max;

}

float max_element ( int n, float a[])

// знаходить максимальний елемент для масиву типу float

{

float max=a[0];

for ( i=1; i

if (a[i]>max) max=a[i];

return max;

}

void main ( )

{

int x[]={10, 20, 30, 40, 50, 60};

long y[]={12L, 44L, 22L, 37L,30L};

int m1=max_element(6, x );

long m2=max_element(5, y);

}

9.4 ФУНКЦІЇ ЗІ ЗМІННОЮ КІЛЬКІСТЮ ПАРАМЕТРІВ

У мовах С та С++ допускаються функції, кількість параметрів у яких при компіляції не визначена. Крім того, можуть бути невідомими і типи параметрів. Кількість і типи параметрів стають відомими лише в момент виклику функції, коли явно задається список фактичних параметрів. Формат заголовку функції зі змінним переліком параметрів має вигляд:

<тип> <ім^я> (<специфікація_формальних_параметрів, …>)

 

Проте, кожна функція зі змінним переліком параметрів повинна мати механізм визначення їх кількості або типу. Для цього використовують два основні підходи:

1) Передача у функцію значення реальної кількості фактичних параметрів за допомогою одного або декількох обов^язкових параметрів;

2) Додавання до списку фактичних параметрів спеціального параметру-індикатора з унікальним значенням, яке буде сигналізувати про кінець списку.

Підхід (1) демонструє програма у прикладі 6, яка містить функцію зі змінним списком параметрів, перший з яких визначає кількість фактичних параметрів, що використовуються при викликанні функції:

Приклад 6:

# include

// Функція сумує значення параметрів типу int

long summa (int k,…)// k – кількість параметрів, що додаються

{int *pik=&k;// вказівник, що звертається до параметрів функції

long total = 0;

for (;k;k--)// поки не вичерпано список параметрів

total+=*(++pik);// відбувається додавання

return total;// повернення результату

}

void main()

{// додаватимуться два параметри

cout<<” summa(2, 6, 4)=”<< summa(2,6,4);

// кількість параметрів, які потрібно додати - 6

cout<<” summa(6, 1, 2,3,4,5,6)= ”<< summa(6, 1,2,3,4,5,6);

}

Результат виконання:

summa(2,6,4)=10

summa(6,1,2,3,4,5,6)=21

Наступний приклад 7 ілюструє 2-й підхід до обмеження змінного списку параметрів. Програма містить функцію для визначення добутку змінної кількості параметрів. Ознакою кінця списку фактичних параметрів служить параметр з нульовим значенням.

Приклад 7:

# include

double prod (doble arg, … )

{double aa=1.0;// початкове значення добутку

double *prt=&arg;// вказівник на перший елемент у списку

if (*ptr==0) return 0.0;// чи є перший елемент нулем?

for (; *ptr; ptr++) aa*=*ptr;// знаходження добутку

return aa;

}

void main()

{cout<< “ prod(2.0, 4.0, 3.0, 0.0)=”<< prod (2.0, 4.0, 3.0, 0.0);

cout<<”“ prod(1.4, 3.0, 0.0, 16.0)=”<< prod (1.4, 3.0, 0.0, 16.0);

cout<<“ prod(0.0)=”<< prod (0.0);

}

Результат виконання:

рrod (2.0, 4.0, 3.0, 0.0)=24

рrod (1.4, 3.0, 0.0, 16.0)=4.2

рrod (0.0)=0.0


10. Структури

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

struct <ім^я структури> {

<опис елементів>

};

Для виділення пам^яті під структуру необхідно визначити структурну змінну:

<ім^я структури> <ім^я змінної>;

Приклад 1.

struct lab{

int num;

char* name;

};// визначення структурного типу з іменем lab

lab Lаb_10;// опис конкретної структуриз іменем Lab_10.

Можна одночасно визначати структурний тип і описувати за допомогою нього структуру:

Приклад 2.

struct gr // ім^я структурного типу

{ char [10];// елемент структури

int year, nomer;// однотипні елементи структури

} grupa1; // ім^я структурної змінної

Елементи структури називають полями (num, name). Поля можуть бути будь-якого базового чи похідного типу, наприклад, масивом, вказівником, об^єднанням або іншою структурою.

Для звернення до полів структури використовуються уточнені імена через операцію вибору: “крапка” (“.”) при зверненні через ім^я структури і операцію непрямого доступу “->” при зверненні через вказівник.

Приклад 3.

Lab_10.num=10;

lab*ptrlab=&Lab_10;

ptrlab->name=”Структури”;

Ввід/вивід структур виконується поелементно (cin>>Lab_10.num;).

Структури одного типу можна копіювати.

Структури, пам^ять під які виділяється на етапі компіляції, можна ініціалізувати, перераховуючи значення їх елементів:

lab Lab10={10, “Структури”}.

Можна створювати масиви структур.

Приклад 4.

// структура для опису дати

struct date { int day,month,year;};

/* масив з 5-ти структур типу date , кожна з яких складається з 3-х елементів типу int, яким надаються початкові значення*/

date d[5]={ { 1,3,1980}, { 5,1,1990}, {1,1,2002}};

Приклад 5.

Програма, що демонструє використання структур для ведення обліку успішності студентів деякої академічної групи:

#include

#include

struct Spysok {

char PIB[20];// масив для зберігання прізвищ студентів

char Grup[10];// номер групи

int Ot[3];// масив з трьох оцінок

float S_Bal;// середній бал

} *vid;// вказівник, на структуру

void Vvid(int nom, Spysok *vid)

{ cout << " Vvedit vidomosti " << (nom+1);

cout << " PIB - "; cin>>vid->PIB;

cout << " Nomer Gr - "; cin >> vid->Grup;

float s=0;

for(int i=0;i<3;i++) {

cout << " Otsinki - "; cin >> vid->Ot[i];

s+=vid->Ot[i];

}

vid->S_Bal=s/3;

}

void main()

{ struct Spysok Stud[50]; int i, N; char Litera;

clrscr();

cout << " Vvedit kilkist studentiv u grupi < 50 "; cin >> N;

for(i=0;i

cout << " Spysok studentiv”;

for(i=0;i

cout<<" "<

cout << " Poshuk vidomostey pro studentiv za pershoyu literoyu prizvyscha ";

cin >> Litera;

if (islower(Litera)) toupper(Litera);

cout << " Vidomosti pro Students:";

int kod_p=0;

for(i=0;i

if(Stud[i].PIB[0]==Litera)

{ kod_p=1;

cout<<” "<

<

}

if(kod_p==0) cout << " Takyx nemae!";

getch();

}


Список використаної літератури

1.         Подбельский В.В. Язык СИ++: Уч. Пособие. –5-е издание. –М.: Финансы и статистика, 2001. –560 с.

2.         Подбельский В. В., Фомин С. С. Программирование на языке Си: Учеб. пособие. –М.:Финансы и статистика, 1998. –600с.

3.         Павловская Т.А. С/С++. Программирование на языке высокого уровня: Учебник для ВУЗов. –СПб.:Питер, 2003. –461 с.

4.         Павловская Т.А., Щупак Ю.А. С/С++. Практикум. –СПб.: Питер, 2002. –204 с.

5.         Дейтел Х., Дейтел П. Как программировать на С++: Пер. с англ. –М.: Бином, 2000. –1024 с.

6.         Прата С. Язык программирования С++. Лекции и упражнения. Учебник: Пер. с англ. –СПб.: ДиаСофтЮП, 2003. –1104 с.

7.         Либерти Дж. Освой самостоятельно С++. –М.: Вильямс, 2001. –456 с.

8.         Культин Н. С/С++ в задачах и примерах. –СПб.:БХВ-Петербург, 2001. –288 с.

Информация о файле
Название файла Мова програмування С++ от пользователя z3rg
Дата добавления 11.1.2012, 19:15
Дата обновления 11.1.2012, 19:15
Тип файла Тип файла (zip - application/zip)
Скриншот Не доступно
Статистика
Размер файла 84.73 килобайт (Примерное время скачивания)
Просмотров 1580
Скачиваний 73
Оценить файл