C _Учебник_МОНУ
.pdfСимволи і рядки |
269 |
//Вставляння пробілу в рядок str на позицію str.begin() + n str.insert(str.begin() + n,' '); Edit5->Text= str.c_str();
//Вставляння у кінець рядка str трьох знаків оклику str.insert(str.end(),3,'!'); Edit6->Text= str.c_str();
//Вставляння на початок рядка s чотирьох символів з С-рядка ch
s.insert(0,ch,4); |
Edit7->Text= str.c_str(); |
//Вставляння 8-ми символів з рядка str, починаючи з позиції n у рядок s на позицію X n = str.find('l');
int X = s.length(); s.insert(X,str,n,8); Edit8->Text= s.c_str();
//Вставляння у рядок s частини рядку str з begin() до begin()+7
//на позицію begin()+4 s.insert(s.begin()+4,str.begin(),str.begin()+7); Edit9->Text= s.c_str();
}
7.3 Розширені символьні типи
7.3.1 Тип С++ wchar_t
Алфавіт більшості європейських мов може бути подано однобайтовими числами (тобто кодами в діапазоні від 0 по 255). Для більшості кодувань перші 127 кодів є однаковими і становлять набір ASCII-кодів: арабські цифри, великі й малі літери латиниці, спеціальні символи й розділові знаки (див. додаток А). Друга половина кодів – від 128 по 255 – відводиться під літери тієї чи іншої мови. Фактично друга половина кодової таблиці інтерпретується по-різному в різних кодуваннях для різних країн.
Проте для таких мов, як китайська, японська і деякі інші, одного байта вже недостатньо, щоб закодувати всі їхні символи, оскільки алфавіти цих мов нараховують понад 127 і навіть понад 255 символів. Тому для кодування символів стали відводити вже два байти, а таке кодування назвали Unicode. Перші
127символів Unicode збігаються з ASCII-символами.
Вмові С++ для опрацювання двобайтових символів існує спеціальний тип wchar_t. Цей тип іноді називають розширеним типом символів, і деталі його реалізації можуть варіюватися від компілятора до компілятора, зокрема може змінюватися і кількість байтів, яка відводиться під один символ; зазвичай
вона відповідає типові short (2 байти). Константи типу wchar_t записуються з префіксом L у вигляді L'ab':
wchar_t c=L'ab';
Рядкові константи типу wchar_t* записуються також з префіксом L, наприклад L"Gates". Існує ціла низка спеціальних функцій для роботи з цими рядками. Майже всі функції для рядків char* мають аналоги для wchar_t*. Приміром, функція wcslen() визначає довжину рядка типу wchar_t, команди wcin та wcout вводять та виводять ці рядки, функції swscanf() та swprintf() вво-
Символи і рядки |
271 |
Питання та завдання для самоконтролю
1)Дайте означення терміну ASCII.
2)Яка є кількість ASCII-кодів? І чому саме?
3)Скільки байтів виділяється для змінної типу char?
4)Які операції можна виконувати над символами?
5)Назвіть вирази, які матимуть значення 1 (true – істина – “так”):
а) '0' < 'y' |
г) 'w' > 'W' |
б) '5' > 'f' |
д) ' ' > '0' |
в) 'F' > 'f' |
е) 'я' > 'ю' |
6)Як у програмі змінити регістр символів?
7)Чи можливо у програмі змінити регістр символів кирилиці? Якщо так, то в який спосіб?
8)Які типи рядків підтримуються в С++ Builder?
9)Наведіть відомі способи оголошення С-рядка.
10)Як ввести С-рядок із компонента Edit?
11)Чи можна присвоїти рядку AnsiString C-рядок? Якщо так, наведіть
приклад.
12)Як присвоїти рядку string рядок AnsiString? Якщо так, наведіть
приклад.
13)В який спосіб можна звернутися до окремого символу рядка?
14)Як порівняти два С-рядки? Наведіть приклад.
15)Чи можна присвоїти С-рядку частину іншого? Якщо так, наведіть
приклад.
16)Яка функція С++ Builder перетворює ціле число на рядок?
17)Чи можна з‟єднувати рядки, якщо так, то в який спосіб?
18)Наведіть способи введення С-рядка у консолі.
19)Поясніть, що виведеться на екран після виконання фрагменту програми: char s1[]="слово";
char *s2=new char[5]; strncpy(s2, s1, 3); puts(s2);
20)Як виправити логічну помилку, припущену у завданні 19?
21)Наведіть фрагменти коду для заміни всіх малих літер 'a' на коми: а) у С-рядку;
б) у рядку string;
в) у рядку AnsiString.
22)Наведіть і поясніть фрагмент коду для видалення з С-рядка трьох символів, розпочинаючи з п‟ятої позиції.
23)У рядку символів визначити кількість повторювань кожного слова та видалити дублікати слів. Слова відокремлюються пробілами.
24)У рядку символів довільного розміру видалити усі слова, довжина яких перевищує N літер.
25)Скопіювати до нового рядка частину рядка від початку до:
а) першого пробілу; |
б) другого пробілу; в) останнього пробілу. |
Розділ 8
Функції
8.1 Правила організації функцій
Коли програма стає завеликою за обсягом і складною для сприйняття, є сенс розділити її за змістом на невеликі логічні частини, називані функціями, кожна з яких виконуватиме певне завдання. Унаслідок цього програма стане більш легкою і для розуміння при створюванні, і для процесу налагодження. Окрім того, створення функції позбавляє потреби створювання двох, а то й і більшої кількості, майже однакових фрагментів програмного коду для розв‟язання однакових завдань за різних вхідних даних. Розподіл програми на функції є базовим принципом структурного програмування.
Функція – це незалежна іменована частина програми, яка може багаторазово викликатися з інших частин програми, маніпулювати даними та повертати результати. Кожна функція має власне ім‟я, за яким здійснюють її виклик. Розрізнюють два основні різновиди функцій: 1) стандартні убудовані функції, які є складовою частиною мови програмування, наприклад: sin(), pow() тощо і 2) функції, які створюються безпосередньо користувачем для власних потреб.
Створювана у програмі функція повинна бути оголошеною і визначеною. Оголошення функції має бути написаним у програмі раніш за її використання. Визначення може перебувати у будь-якому місці програми, за винятком тіла (середини) інших функцій. Оголошення функції складається з прототипу (чи
заголовка) і має форму
[клас] <тип результату> <ім‟я функції> (<перелік формальних аргументів із зазначенням типу>);
Наприклад оголошення функції обчислення середньоарифметичного двох цілих чисел може мати видгляд
float seredne (int a, int b);
де seredne – ім‟я функції;
a і b – формальні вхідні аргументи (параметри), які за виклику набувають значень фактичних параметрів;
float – тип функції, який безпосередньо є типом результату виконання операторів функції. Результат повертається оператором return.
Прототип функції може бути розташовано як безпосередньо у програмі, так і в заголовному файлі (див. далі п. 9.2).
Окрім оголошення, кожна функція повинна мати визначення (реалізацію). Визначення функції, окрім заголовку, містить тіло функції (команди, які виконує функція) і команду повертання результату return:
<тип функції> <ім‟я функції> (<перелік аргументів>)
{<тіло функції>
return <результат обчислень>
Функції |
273 |
}
Наприклад, визначення функції seredne може бути таким: float seredne (int a, int b)
{float sr; sr=(a+b)/2.0; return sr;
}
Наведена функція обчислює sr – середньоарифметичне двох цілих чисел a та b і повертає його значення у точку виклику.
У разі, коли визначення функції розміщено у програмі раніш за точку виклику, писати окремо оголошення і окремо реалізацію цієї функції немає потреби і оголошення функції можна уникнути.
Якщо функції виконують певні обчислення й дії, які не потребують повертання результатів, за їхній тип вказують тип void (тобто порожній, без типу). У таких функціях оператор return може бути відсутнім чи записуватись без значення, яке повертається. Яскравим прикладом таких функцій є відгуки подій у C++ Builder, наприклад:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
}
У поданому нижче прикладі створювання власної консольної функції max3() всі обчислення для пошуку максимального з трьох дійсних чисел x, y та z, а також дії стосовно виведення результатів обчислень відбуваються у функції і немає потреби повертати їх через return:
void max3(float x, float y, float z)
{if (x>y && x>z) cout<<x; else
if (y>x && y>z) cout<<y;
else cout<<z;
}
Приклади створювання функцій з типом void вже розглядались у розд. 5 при опрацюванні числових масивів у функціях.
Виконання функції розпочинається, коли у тексті програми зустрічається оператор виклику, тобто ім‟я функції з фактичними параметрами у дужках. При цьому формальні параметри послідовно набувають значень фактичних: значення першого фактичного аргументу копіюється у перший формальний аргумент, другий – у другий і т. д. А тому дуже важливими чинниками є кількість, порядок записування і відповідність типів всіх аргументів, інакше це може призвести до серії помилок.
Якщо функцію оголошено з будь-яким типом, окрім типу void, тобто вона повертає певний результат, при викликанні такої функції її варто присвоїти змінній того ж самого типу, що й сама функція, чи то вивести на екран за допомогою оператора виведення. Наприклад, функцію seredne() може бути викликано в один зі способів:
Функції |
275 |
int [10] func(); // Помилка!
Якщо функція має повернути масив, то можна оголосити її тип як вказівник на перший елемент масиву (кількість елементів цього масиву має бути відомою):
int * func();
9) С++ дозволяє існування у програмі функцій з однаковим ім‟ям, але різними параметрами.
Функції використовують пам‟ять зі стека програми. Певна область стека надається функції й залишається пов‟язаною з нею до завершення її роботи. Після завершення роботи надана для функції пам‟ять звільнюється й може бути зайнята іншою функцією.
Усі величини, оголошені всередині функції, а також її параметри, є локальними. Областю їхньої дії є функція, тобто для решти функцій програми ці змінні та їхні значення залишаються невідомими. Глобальні змінні є відомими всім функціям програми, кожна з функцій може змінювати значення таких змінних. Використовування глобальних змінних часто призводить до помилок, які важко відшукати. Тому слід уникати використовування глобальних змінних, якщо це не є нагальною потребою.
При викликанні функції, як і при вході до кожного блока, у стеку виділяється пам‟ять під локальні автоматичні змінні. При виході з функції пам‟ять, яку було виділено під локальні змінні, звільнюється. За спільної роботи функції обмінюються даними. Це можна здійснити за допомогою глобальних змінних, через параметри й через значення, які повертає функція.
У розглянутому нижче прикладі змінні з ім‟ям х визначені одразу у двох функціях – в main() і в Sum(), що не заважає компіляторові розрізнювати їх поміж собою:
int Sum(int А, int В)
{ // Локальну змінну x і параметри A та B видно лише у тілі функції Sum() int x = A + B;
return x;
}
void main()
{int x = 2, y = 4; // x, y – локальні змінні для main() cout << Sum(x, y);
}
Глобальні змінні є видимими у всіх функціях, де не описані локальні змінні з тими ж іменами, тому використовувати їх для передаванні даних між функціями дуже легко. Якщо імена глобальної й локальної змінної збігаються, перевага надається локальній змінній. Проте використовувати змінні з однаковими іменами не рекомендовано, оскільки це ускладнює налагодження програми. Слід прагнути до того, щоб функції були максимально незалежними, а їхній інтерфейс повністю визначався би прототипом функції.
Функції |
277 |
void __fastcall TForm1::Button1Click(TObject *Sender) { double z=(2.0*fact(5)+3*fact(8))/(fact(6)+fact(4));
Edit1->Text=FloatToStr(z);
}
Приклад 8.4 Віднайти периметр трикутника, заданого координатами вершин.
Розв‟язок. Для обчислення довжини сторони трикутника доцільно створити функцію і викликати її тричі для кожної зі сторін. Ця функція обчислюватиме довжини відрізку, заданого координатами точок, які він з‟єднує, за формулою
d 
(x2 x1)2 ( y2 y1)2 .
Функція segment() має чотири параметри – координати обох кінців відрізка. Результат функції – дійсне число (довжина відрізка).
Тексти функції та її виклику в основній консольній програмі: double segment(double x1,double y1,double x2,double y2)
{return sqrt(pow(x2-x1,2)+pow(y2-y1,2));
}
void main()
{double x1, y1, x2, y2, x3, y3, P; cout<<"Перша вершина:\n";
cout<<"Уведіть координату х: "; cin>>x1; cout<<"Уведіть координату y: "; cin>>y1; cout<<"Друга вершина:\n";
cout<<"Уведіть координату х: "; cin>>x2; cout<<"УВведіть координату y: "; cin>>y2; cout<<"Третя вершина:\n";
cout<<"Уведіть координату х: "; cin>>x3; cout<<"Уведіть координату y: "; cin>>y3; P=segment(x1,y1,x2,y2)+segment(x2,y2,x3,y3)+
segment(x1,y1,x3,y3); cout<<"Периметр дорівнює: "<<P<<endl;
}
Результати виконання програми:
Перша вершина:
Уведіть координату х: 3 Уведіть координату y: 5
Друга вершина:
Уведіть координату х: 1 Уведіть координату y: 7
Третя вершина:
Уведіть координату х: 4 Уведіть координату y: 2
Периметр дорівнює: 11.8217
