Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 4

Jedynym mechanizmem przekazywania parametrów w C jest „przez kopię”: wartość argumentu

aktualnego (zmiennej w programie wołającym, w przykładach poniżej j oraz k) jest kopiowana do


argumentu formalnego (zmiennej w deklaracji funkcji, w przykładach poniżej i oraz j).

Ponieważ argument formalny ma zasięg lokalny (istnieje tylko wewnątrz funkcji), zmiana jego wartości
nie jest widziana w programie wołającym (nawet jeśli argument aktualny i formalny nazywałyby się tak
samo, np. w wywołaniu int i=0; f1(i)).

Aby umożliwić zwrot wartości funkcji przez argument oraz aby uniknąć kopiowania dużych zmiennych
(np. struktur albo tablic), należy w C posłużyć się wskaźnikami. Poniżej wersja programu C++ w stylu C z
użyciem wskaźników:
Pw87aaa
#include "iostream"
using namespace std;

void f1(int i); // Argument przez kopie


void f2(int* i); // Argument przez wskaznik (adres)
int f3(int i); // Argument przez kopie, funkcja zwraca int
int f4(int* i); // Argument przez wskaznik (adres), funkcja zwraca int
void swap(int* i, int* j); // Zamienia wartosci argumentow, przez wskaznik

int main()
{
int j = 0, k = 0;
cout << "main: j = " << j << " k = " << k << endl;
f1(j);
cout << "main: j = " << j << " k = " << k << endl;
f2(&j);
cout << "main: j = " << j << " k = " << k << endl;
k = f3(j);
cout << "main: j = " << j << " k = " << k << endl;
k = f4(&j); // adres, nie referencja
cout << "main: j = " << j << " k = " << k << endl;
j = 1; k = 2;
cout << "przed swap: j = " << j << " k = " << k << endl;
swap(&j, &k); // adresy, nie referencje
cout << "po swap: j = " << j << " k = " << k << endl;
return 0;
}
void f1(int i)
{
i++; // zmiana i tylko lokalnie
cout << "f1: i = " << i << endl;
}

void f2(int* i)
{
(*i)++; // i jest wskaznikiem, zmieniamy int pokazywany przez wskaznik (j), nawiasy
sa potrzebne
cout << "f2: i = " << *i << endl;
}
int f3(int i)
{
i++; // zmiana i tylko lokalnie
cout << "f3: i = " << i << endl;
return i; // zwarcamy nowa wartosc i
}
int f4(int* i)
{
(*i)++; // i jest wskaznikiem, zmieniamy int pokazywany przez wskaznik (j), nawiasy
sa potrzebne
cout << "f4: i = " << *i << endl;
return *i; // i jest wskaznikiem, zwracamy int pokazywany przez wskaznik (j)
}
void swap(int* i, int* j)
{
int k = *i;
*i = *j;
*j = k;
}

W C++ wprowadzono referencje aby uniknąć kłopotliwego użycia wskaźników.

Dla kompilatora referencja to adres, dla programisty to inna nazwa (synonim, alias) zmiennej. Czyli
deklaracja void f2(int& i); i wywołanie int j=0; f2(j); oznaczają, ze i i j to ta sama zmienna (to
samo miejsce w pamięci, ten sam adres). Deklaracja int& zwalnia programistę z uciążliwej dereferencji
wskaźnika.

Uwaga >> int& w deklaracji to referencja (C++), a &j w wywołaniu to operator adresu (C). Żeby
programistom nie było za łatwo wybrano taki sam znak operatora dla dwóch różnych celów.

Poniżej wersja C++ z referencją i numeracją funkcji w wydrukach:


Pw87aaaa
#include "iostream"
using namespace std;

void f1(int i); // Argument przez kopie


void f2(int& i); // Argument przez referencje (adres)
int f3(int i); // Argument przez kopie, funkcja zwraca int
int f4(int& i); // Argument przez referencje (adres), funkcja zwraca int
void swap(int& i, int& j); // Zamienia wartosci argumentow, przez referencje

int main()
{
int j=0, k=0;
cout << "main: j = " << j << " k = " << k << endl;
f1(j);
cout << "main: j = " << j << " k = " << k << endl;
f2(j);
cout << "main: j = " << j << " k = " << k << endl;
k = f3(j);
cout << "main: j = " << j << " k = " << k << endl;
k = f4(j);
cout << "main: j = " << j << " k = " << k << endl;
j = 1; k = 2;
cout << "przed swap: j = " << j << " k = " << k << endl;
swap(j, k);
cout << "po swap: j = " << j << " k = " << k << endl;
return 0;
}
void f1(int i)
{
i++;

cout << "f1: i = " << i << endl;


}
void f2(int& i)
{
i++;
cout << "f2: i = " << i << endl;
}
int f3(int i)
{
i++;
cout << "f3: i = " << i << endl;
return i;
}
int f4(int& i)
{
i++;
cout << "f4: i = " << i << endl;
return i;
}
void swap(int& i, int& j)
{
int k = i;
i = j;
j = k;
}

You might also like