Помогни ни да направим Uroci.net по - богат! Добави урок

C++ част.4 (Функции и обхват)

C++ » C++
fix3d   трудност:    видян: 42378



4.6. Изпращане на аргументи

За функциите се записва информация в една структура, наречена програмен стек от времето на изпълнение. Тази информация остава в стека докато функцията е активна. След като функцията приключи изпълнението си тази информация се изтрива автоматично. Цялата област, отделена за информацията, се нарича запис на активиране.

Списъкът от аргументите на една функция описва формалните й аргументи. Всеки формален аргумент се записва в записа на активиране. Размерът на този запис се определя от типовите спецификатори на аргументите. Изразите, записани в кръглите скоби при обръщението към функция се наричат фактически аргументи на обръщението. Изпращането на аргументи е процес на инициализиране на информацията за формалните аргументи чрез фактическите аргументи.

Подразбиращият се в С++ метод за инициализация при изпращането на аргументи е чрез копиране на стойностите за четене (rvalue) на фактическите аргументи в областта, отделена за формалните аргументи. Това се нарича изпращане по стойност. При изпращането по стойност функцията никога няма достъп до фактическите аргументи на обръщението. Стойностите, които функцията обработва са нейни собствени локални копия; те са записани в стека. Изобщо, промените направени над тези стойности не се отразяват на стойностите на фактическите аргументи. Когато функцията приключи работата си и записа на активирането бъде изтрит тези локални стойности се изгубват. При изпращането по стойност съдържанието на фактическите аргументи не се променя. Това означава, че програмистът не е длъжен да запазва и възстановява стойностите на аргументите, когато прави обръщение към функция. Без механизма за изпращане по стойност може да се предполага, че всеки формален аргумент, който не е деклариран от тип const може да бъде потенциално изменен при всяко извикване на функцията. Извикването по стойност има минимален потенциал за нанасяне на щети и изисква минимум усилия от потребителя. Изпращането по стойност е един разумен механизъм за изпращане на аргументи по подразбиране.

Изпращането по стойност, обаче, не е подходящо за всяка функция. Механизмът за изпращане по стойност не е подходящ за следните случаи:

- когато като аргумент трябва да бъде изпратен голям обект от тип клас. Времето и паметта, необходими за копиране и разполагане на класовия обект в стека често може да се окажат много големи за програмни приложения от реалната практика.

- когато стойностите на аргументите трябва да бъдат обработени. Функцията swap() е един пример, при който потребителят иска да промени стойностите на фактическите аргументи, но това не може да бъде направено чрез механизма за изпращане по стойност.

void swap( int v1, int v2) {
int tmp = v2;
v2 = v1;
v1 = tmp; }

swap() разменя локалните копия на аргументите си. Фактическите променливи, изпратени на swap(), остават непроменени. Това се илюстрира от следната програма, която вика swap()

#include <stream.h>

vpid swap( int, int);
main() {
int i = 10;
int j = 20;
cout << "Before swap()ti "<< i << "tj" << j << "n";
swap( i, j );
cout << "After swap()ti "<< i << "tj" << j << "n"; }

След като компилираме и изпълним тази програма ще получи следния резултат:

Before swap()
i 10 j 20

After swap()
i 10 j 20

За програмиста съществуват две алтернативи на механизма изпращане по стойност. В първия случай формалните аргументи се декларират като указатели (pointer). Тогава функцията swap() може да бъде написана така

void pswap( int *v1, int *v2) {
int tmp = *v2;
*v2 = *v1;
*v1 = tmp; }

main() трябва да бъде модифицирана така, че да декларира и извиква pswap(). Програмистът вече трябва да изпраща адресите на двата обекта, а не самите обекти

pswap( &i, &j );

Когато компилираме и изпълним тази програма, показаните резултати вече ще бъдат правилни

Before swap()
i 10 j 20

After swap()
i 20 j 10

Когато желаете само да избегнете копирането на даден аргумент, декларирайте го като const

void print( const BigClassObject* );

По този начин читателят на програмата (и компилаторът) знаят, че функцията не променя обекта, адресиран от аргумента. Втората алтернатива на изпращането по стойност е формалните аргументи да бъдат декларирани от тип указател. swap(), например, може да бъде написана и така

void rswap( int &v1, int &v2 ); {
int tmp = v2;
v2 = v1;
v1 = v2; }

Обръщението към rswap() от main() изглежда така, както и обръщението към оригинала swap()

rswap( i, j );

След като тази програма бъде компилирана и изпълнена ще се види, че стойностите на i и j са правилно разменени.



Страници: «3 4 5 6 7 8 9 »

Сподели урока:



Регистрирайте се, за да добавите коментар


Калдейта Ком ЕООД - © 2003-. Всички права запазени.
Препоръчваме: IT Новини