Студопедия

КАТЕГОРИИ:



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

Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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

Передача параметрів


4.3. Передача параметрів значенням, особливості передачі параметрів у випадку указників, псевдонімів, псевдонімів сталих, псевдонімів указників, масивів, псевдонімів масивів; замовчувані значення параметрів; перетворення типів при передачі параметрів

 

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

 

Ось приклад

void DoubleMyValue (short valueParam)

{

valueParam *= 2;

}

int main ()

{

short number = 10;

DoubleMyValue (number);

cout<<number<<’\n’;

}

 

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

 

 

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

 

Перед swap(): i: 10 j: 20

Після swap(): i: 10 j: 20

 

Перший вихід із проблемної ситуації пропонують указники.


Як і раніше параметри передаються значеннями, але значення ці тепер адреси.

 

Перед swap(): i: 10 j: 20

Після swap(): i: 20 j: 10

 

 

void rswap( int &x, int &y)

{

int z = x; x=y; y=z;

}

int main() {

int i = 10;

int j = 20;

cout<<"Перед swap():\ti: "<<i<<"\tj: "<<j<<endl;

rswap( i, j ) ;

cout<<"Після swap():\ti: "<<i<<"\tj: "<<j<<endl;

return 0;

}

 

 

 



 

void pswap( int *x, int *y)

{

int z = *x; *x=*y; *y=z;

cout<<"pswap: "<<&x<<" z:"<<&z<<endl;

}

void rswap( int &x, int &y)

{

int z = x; x=y; y=z;

cout<<"rswap: "<<&x<<" z:"<<&z<<endl;

}

void swap( int x, int y)

{

int z = x; x=y; y=z;

cout<<"rswap: "<<&x<<" z:"<<&z<<endl;

}

int main() {

int i = 10, &ri = i;

int j = 20;

cout<<"main: "<<hex<<&i<<" ri: "<<&ri<<endl;

cout<<"Перед swap():\ti: "<<i<<"\tj: "<<j<<endl;

swap( i, j ) ;

cout<<"Після swap():\ti: "<<i<<"\tj: "<<j<<endl;

pswap( &i, &j ) ;

cout<<"Після pswap():\ti: "<<i<<"\tj: "<<j<<endl;

rswap( i, j ) ;

cout<<"Після rswap():\ti: "<<i<<"\tj: "<<j<<endl;

return 0;

}

 

Оголошення int *&v;читається справа наліво: псевдонім указника

 

void ptrswap( int *&, int *& );

int main()

{

int i = 10;

int j = 20;

int *pi = &i;

int *pj = &j;

cout<<"Перед ptrswap():\tpi: "

<<*pi<<"\tpj: "<<*pj<<endl;

ptrswap( pi, pj ) ;

cout<<"Після ptrswap():\tpi: "

<<*pi<<"\tpj: "<<*pj<<endl;

return 0;

}

 

 

Перед ptrswap: pi: 10 pj: 20

Після ptrswap: pi: 20 pj: 10

 

 

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

 

 

 

Якщо ми замінимо сигнатуру, задавши параметр псевдонімом, уникнемо копіювання, але не будемо гарантовані від зміни параметру всередині функції

 

int calc( Huge &par);

 

 

void getArray( int[ 10 ] ) ;

і

void getPtr( int* );

 

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

 

 

void putValues( int[ ], int size );

int main()

{

int i, j[ 2] ;

putValues( &i, 1);

putValues( j , 2);

return 0;

}

 

void putValues( int (&arr)[10] ) ;

int main()

{

int i, j [ 2 ];

putValues(i);

// помилкака: аргумент не є масивом

putValues(j);

// помилка:

// аргумент не є масивом з 10 елементів типу int

return 0;

}

 

 

p>Додатковий параметр sz відповідає за розмірність. Перша перевірка з’ясовує, чи були указники попередньо встановлені. Те ж саме копіювання символьних масивів додаткового параметру розмірності не потребує, оскільки вичерпання масиву перевіряється нульовим кодом

 

void сopyString (char *source, char *dest)

{

while ( *source != ‘\0’ )

{

*dest = *source;

dest++;

source++;

}

*dest = ‘\0’;

}

 

або це ж саме компактним С-текстом

 

void CopyString (char *source, char *dest)

{

while (*dest++ = *source++);

}

 

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

 

void GenerateATone (short frequency = 440)

{

//Частота 440 відповідає ноті сі

};

 

Виклики можуть бути такими

 

GenerateATone (330);

GenerateATone ();

 

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



 

void NormalDefaults (short x, short y=2, short z=3);

 

відповідає правилу, в той час як наступний — ні, оскільки перший аргумент має, а другий аргумент не має замовчування

 

void WillNotCompile (long time = 100L, short stack);

 

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

 

#include <iostream.h>

void MyFunc( short param1,

short param2 = 0,

short param3 = 0 );

int main()

{

MyFunc( 1 );

MyFunc( 1, 2 );

MyFunc( 1, 2, 3 );

return 0;

}

void MyFunc( short param1,

short param2,

short param3 )

{

cout << "MyFunc( " << param1

<< ", " << param2

<< ", " << param3

<< " )\n";

}

MyFunc( 1, 0, 0 )

MyFunc( 1, 2, 0 )

MyFunc( 1, 2, 3 )

 

<== предыдущая лекция | следующая лекция ==>
Вбудовані (inline) функції, порівняння з макровизначеннями, закриті функції | Обчислення значення функцій

Дата добавления: 2014-01-04; Просмотров: 287; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



ПОИСК ПО САЙТУ:


Рекомендуемые страницы:

Читайте также:
studopedia.su - Студопедия (2013 - 2021) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление
Генерация страницы за: 0.013 сек.