- •1. Кроки для створення виконання програми
- •2. Змінні та константи
- •3. Символьні масиви і рядки
- •4. Директиви препроцесора
- •Тема 2: введення-виведення даних план
- •Аргументи для setiosflags і resetiosflags
- •2. Функція printf
- •2. Операції відношення
- •3. Логічні операції
- •4. Додаткові операції
- •5. Порозрядні операції
- •Тема 4: організація циклів план
- •1. Організація циклів за допомогою while і do...While
- •2. Організація циклів із використанням оператора for
- •3. Оператори switch і goto
- •Тема 5: створення функцій план
- •1. Створення функцій
- •2. Видимість змінних
- •3. Передача значень
- •4. Повертаємі значення і прототипи функцій
- •Тема 6: зовнішні пристрої і символьне введення/виведення план
- •1. Загальна концепція
- •2. Функції символьного введення-виведення
- •3. Символьні функції
- •4. Рядкові функції
- •5. Числові функції
- •6. Функції роботи з датою та часом
- •Тема 7: масиви план
- •1. Одномірні масиви, їхня ініціалізація
- •2. Сортування масивів
- •3. Розміщення одномірного масиву в пам’яті
- •4. Багатомірні масиви і їхнє розміщення в пам’яті
- •Тема 8. Вказівки і посилання план
- •1. Вказівки
- •2. Масиви і вказівки
- •Тема 9: робота з файлами план
- •1. Загальна характеристика роботи з файлами
- •2. Послідовні файли
- •Можливі режими доступу
- •3. Файли довільного доступу (із випадковим доступом)
- •Тема 10. Структури план
- •1. Загальна характеристика структури
- •2. Масиви структур
- •3. Використання масивів, як елементів структур
- •2. Робота зі структурами є універсальною, передбачено додавання записів до файлу (флаг ios:app). Для підрахунку кількості структур на диску приведемо наступні рядки програми:
- •Список літератури
2. Масиви і вказівки
Аналогія масиву і вказівок.
Масив являє собою лише вказівку і більше нічого.
int ara[5]={10,20,30,40,50};
ara+0 – вказує на ara[0]
ara+1 – вказує на ara[1]
-
Пам’ять
[0]
10
[1]
20
[2]
30
[3]
40
[4]
50
cout <<*(ara+2); //Друк ara[2]
Хоча масиви є замаскованими вказівками, але вони відносяться до особливого типу вказівок. Масив являє собою константу-вказівку, а не змінну-вказівку.
Тому що не можна змінити константу, то неможливо змінити значення імені масиву
char ch[20];
ch=”Привіт”; //Неприпустима операція
Приклад:
float v1=500.0,v2=600.0;
float *pt;
pt=&v1;
cout << *pt; //500
pt=&v2;
cout << *pt; //600
Тут використовується змінна-вказівка pt, значення якої може змінюватися.
Використання вказівок на символи.
Роздивимося 2 рядки:
char cara[]=”Привіт”;
char *cp = ”Москва”;
Після початкової ініціалізації у вказівці на символьну змінну міститься адреса першого символу рядка.
cara=”Привіт”; //Невірно
cp=”Київ”; //Можна: занесення у вказівку
//нового рядка.
Приклад:
#include <iostream.h>
# include <string.h>
void main()
{
char name[20]=”Іван Петров”;
char *t=name;
strcpy(t+5,”Сидоров”);
cout <<t; //Іван Сидоров
}
Використання арифметичних операцій із вказівками
ara[sub] → *(ara+sub)
int s[]={10,20,30};
int *ps=s; //Те ж саме int *ps=&s[0]
ps++;
cout <<*ps; //20 - виведення
ps++;
cout <<*ps; //30 - виведення
Приклад:
#include <iostream.h>
#include <iomanip.h>
void main()
{
float ara[ ]={100,200,300,400,500};
float *fp = &ara[0];
cout << setiosflags(ios::fixed)
<< setprecision(1);
cout << *fp << "\n";
fp++;
cout << *fp << "\n";
fp++;
cout << *fp << "\n";
fp=ara;
cout << *(fp+2) << "\n";
cout <<(fp+0)[0] << " "<< (ara+0)[0] << "\n";
cout << (fp+4)[0] <<" "<< (ara+4)[0] << "\n";
cout << (fp-1)[2] <<" "<< (ara-1)[2] << "\n";
}
Результат:
100.0
200.0
300.0
300.0
100.0 100.0
500.0 500.0
200.0 200.0
Запам’ятовування масивів рядків.
char names[5][20]=
{
{"Наташа"},
{"Георгій"},
{"Ан"},
{"Оля"},
{"Льоша"}
};
Таблиця займає в пам’яті багато місця. Нераціонально використовується пам’ять.
Для усунення проблем раціонального використання масиву символьних вказівок кожна вказівка містить адресу рядка в пам’яті, і ці рядки можуть мати різну довжину.
1-й варіант |
2-й варіант |
char *names[5]= { {"Наташа"}, {"Георгій"}, {"Ан"}, {"Оля"}, {"Льоша"} }; |
char *names[]= { "Наташа", "Георгій", "Ан", "Оля", "Льоша" }; |
Рядки можуть знаходитися в будь-якому масиві пам’яті
[0] |
Наташа\0 |
[1] |
Георгій\0 |
[2] |
Ан\0 |
[3] |
Оля\0 |
[4] |
Льоша\0 |
cout << *names //Друкує Наташа
cout << *(names+1) //Георгій
Порада: робота з вказівками на рядки набагато ефективніше, ніж із рядками. Наприклад, якщо рядки знаходяться у формі що вирівнюються таблиць, то їхнє формування займає багато часу. Сортування рядків, що визначені за допомогою масиву вказівок, виконується швидше. У останньому випадку під час сортування ви змінюєте тільки вказівки, а не вміст рядків.
Приклад:
При запровадженні чисел від 1 до 7 на екран виводиться день тижня
#include <iostream.h>
void main()
{
char *dn[]=
{
"Понеділок",
"Вівторок",
"Середа",
"Четвер",
"П’ятниця",
"Субота",
"Неділя"
};
int day_num;
do
{
cout <<"Введіть день тижня(1-7)?";
cin >> day_num;
}
while ((day_num < 1)||(day_num > 7));
cout << *(day_num - 1 + dn) << "\n";
}
3. Використання посилань у С++
Типи посилань встановлюють псевдоніми об’єктів. Вони використовуються як типи параметрів функцій для передачі аргументів по посиланню. Для опису типу посилань використовується модифікатор & аналогічно модифікатору * для покажчиків. Посилання в основному використовуються як параметри. Щоб показати, як працюють посилання, роздивимося непараметричні оголошення.
Для встановлення псевдоніму, він повинен бути того ж типу, що і змінна.
int i;
int &ir = i;
Для змінної i встановлюється псевдонім ir. Присвоювання ir значення і його використання значення дасть той же результат, що і присвоювання значення і використання i.
ir = 3;
j = ir * i; //результат 9
Посилання (адреса) не може бути змінена.
У більшості мов програмування параметри передаються або по посиланню, або за значенням. У першому випадку підпрограма (функція) працює безпосередньо зі змінною, переданою в якості параметра, у другому ж їй доступна не сама змінна, а тільки її значення. Різниця очевидна: змінну, передану по посиланню, підпрограма може модифікувати, а за значенням - ні. Нижче приведені 4 версії функції обміну значень 2-х змінних. У swap1 використовується передача параметрів за значенням, обміну не буде. У swap2 використовується передача за значенням вказівок. У swap3 і swap4 передача по посиланню.
1) void swap1(int x, int y)
{
int z = x;
x = y;
y = z; //Обміну в зовнішній програмі не буде.
}
2) void swap2(int *x, int *y)
{
int z = *x;
*x = *y;
*y = z;
}
3) void swap3(int &x, &int y)
{
int z = x;
x = y;
y = z;
}
4) void swap4(double &x, double &y)
{
int z = x; //Компілятор дасть попередження,
x = y; //оскільки параметру посилання одного
y = z; //типу повинна бути привласнене посилання
//того ж типу
}