Масиви і символьні рядки як параметри функцій 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Масиви і символьні рядки як параметри функцій



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

Використовують дві форми оголошення формального параметра функції, який повинен відповідати масиву:

 

тип_елементів ім’я_масиву[] int vect[]

тип_елементів * ім’я_вказівника int * vect

 

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

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

 

double avg1(int a[ ], int n) {

double t = 0;

for (int i = 0; i < n; i++)

     t += a[ i ];

return t / n;

}

double avg2(int * p, int n) {

int * last;

double t;

for (last = p + n, t = 0; p < last; p++)

     t += * p;

return t / n;

}

const int NUM = 5;

int a[ NUM ];

cout << avg1(a, NUM) << endl;

cout << avg2(a, NUM) << endl;

 

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

 

double avg2(int p[ ], int n) {

int * last;

double t;

for (last = p + n, t = 0; p < last; p++)

     t += * p;

return t / n;

}

 

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

 

char * to_upper(char * p) {

char d = 'A' - 'a';

char * t;

for (t = p; *t; t++)

     if ('a' < *t && *t < 'z')

           *t += d;

return p;

}

char s[ ] = "hello world!";

cout << to_upper(s) << endl;

cout << s << endl;

 

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

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

 

char * WrongFirstWord(char * s) {

char word[ 20 ], * w = word;

while (*s!= ' ' && *s!= '.' && *s!= ',' && s!= '\0')

     *w++ = *s++;

*w = '\0';

return word;

}

char * str = "There is no place like 127.0.0.1";

cout << WrongFirstWord(str) << endl;

 

При спробі компіляції такої функції буде видано попередження «Функція повертає значення локальної змінної», результат виконання такої функції буде непередбачуваний. Вирішити цю проблему можна таким чином: 1) всередині функції виділяти пам’ять динамічно, повертати вказівник на виділену ділянку пам'яті; 2) передавати адресу пам'яті, в яку необхідно записувати результат виконання функції, в якості параметра функції; 3) використовувати глобальні змінні.

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

 

char * FirstWord(char * s) {

char * pc = s;

while (*pc!= ' ' && *pc!= '.' && *pc!= ',' && pc!= '\0')

     pc++;

int n = pc - s; // Кількість символів в першому слові

char * word = new char [ n + 1 ];

pc = word;

while (*s!= ' ' && *s!= '.' && *s!= ',' && s!= '\0')

     *pc++ = *s++;

*pc = '\0';

return word;

}

char * str = "There is no place like 127.0.0.1";

char * res = NULL;

res = FirstWord(str);

cout << res << endl;

delete[] res;

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 56; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.246.193 (0.008 с.)