русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


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


Дата додавання: 2014-04-22; переглядів: 1824.


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

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

 

тип_елементів ім’я_масиву[] 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;

 


<== попередня лекція | наступна лекція ==>
Inline – функції | Використання кваліфікатора const в оголошеннях параметрів


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн