КАТЕГОРИИ: Архитектура-(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)
Дата добавления: 2014-01-04; Просмотров: 435; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |