Wykład 2
Przekazywanie parametrów przez wskaźnik
Przy przekazywaniu parametru przez adres do funkcji przesyłany jest adres zmiennej (parametru aktualnego), na stosie tworzona jest kopia adresu.
void func(int *par) { *par = *par + 5; printf(“\n funkcja: par= %d”, par); }
void main() { int a1=15;
printf(“Parametr aktualny przed wywołaniem: a1=%d”, a1);
func(&a1);
prinft(„Parametr aktualny po wywołaniu: a1=%d”, a1); }
Ekran:
Parametr aktualny przed wywolaniem: a1 = 15
funkcja:par=20
Parametr aktualny po wywołaniu: a1=20
Przez referencję
Przy przekazywaniu parametru przez referencje do funkcji przesyłany jest adres zmiennej. Operacje przeprowadzane są bezpośrednio na zmiennej, której referencje przesłano do funkcji lub na zmiennej tymczasowej gdy występuje niezgodność typu referencyjnego i argumentu.
#include<iostream.h>
void func(int a, int &b) { a = a+5; b = b+6;
cout<<*funkcja: parametr po modyfikacji: a = *<<a;
cout<<*funkcja: parametr po modyfikacji: b = *<<b; }
main (){ int a1=5, b1=15;
func (a1,b1);
cout<<*Parametr po wywolaniu funkcji: a1 = *<<a1;
cout<<*Parametr po wywolaniu funkcji: b1 = *<<b1; }
EKRAN:
funkcja: parametr po modyfikacji: a = 10
funkcja: parametr po modyfikacji: b = 21
Parametr po wywolaniu funkcji: a1 = 5
Parametr po wywolaniu funkcji: b1 = 21
Po zakończeniu funkcji kopia zmiennej a1 przechowywana na stosie jest ze stosu usuwana - zmienna a1 - nie zostanie zmieniona. Drugi argument przesyłany jest przez referencje, na stosie przechowywany jest adres zmiennej, więc funkcja działa bezpośrednio na zmiennej, co powoduje że wartość zmiennej b1 jest zostaje zmieniona. Wywołanie funkcji dla parametrów przekazywanych przez wartość i referencję nie różni się od siebie. Może to prowadzić do błędów.
Przykład funkcji z parametrem przekazywanym przez wartość, wskaźnik i referencję:
#include<iostream.h>
void fun_war (float ); //przez wartość
void fun_wsk (float *); //przez wskaźnik
void fun_ref (float &); //przez referencje
void main() {
float obl, nr =12;
obl=fun_war (nr);
cout<<obl; //-100
cout<<nr; //nr =12;
fun_wsk (&nr);
cout<<nr; //nr=120
fun_ref (nr);
cout<<nr; //nr=130
}
float fun_war (float par) { par=3; return (-103 + par); } //przez wartość
void fun_wsk (float *par) {*par=120}; //przez wskaźnik
void fun_ref (float &par) {par=130;}; //przez referencje
Przekazywanie wartości z funkcji
Z funkcji która nie jest zadeklarowana jako void trzeba przekazać wartość, określa się ją w instrukcji return (instrukcja powrotu). W funkcji może wystąpić więcej niż jedna instrukcja powrotu.
int f() { } //błąd void f() { } //dobrze
Podczas każdego wywołania funkcji jest tworzona nowa kopia jej argumentów i zmiennych automatycznych. Zużyta pamięć jest odzyskiwana po powrocie z funkcji.
int *f() { int lokalna =1; //.....
return &lokalna; //błąd przekazywania adresu do zmiennej lokalnej }
int *f (int a){ //.....
return &a; // błąd przekazywania adresu do zmiennej lokalnej }
Powyższe kody funkcji są niepoprawne, ale będą kompilowane bez błędów.
Funkcje z argumentami domyślnymi
Wartości argumentom nadaje się w prototypie funkcji: void system (int liczba, int system = 10);
void main(){
system (12); // domyslnie ustawiane jest 10;
system (12,10);
system (12,16);
system (12,8); }
Funkcja wyswietla liczbę w dowolnym systemie liczbowym, choć zakłada, że najczęściej używa się systemu 10-tkowego.
Funkcja main () z argumentami.
Wcześniej mówiliśmy, że main() jest taką samą funkcja jak inne, w związku z tym może wystepować z argumentami. W środowisku języka C do uruchamianego programu można przekazać parametry wywołania, w wierszu polecenia wywołującego program. Działanie programu rozpoczyna się wtedy wywołaniem funkcji main() z dwoma argumentami.
void main (int argc, char *argv[])
Pierwszemu argc zostanie przypisana liczba parametrów znajdujących się w wierszu komendy plus jeden
Drugi argument argv (argument vector) zawiera:
argv[0] - nazwa programu wraz z pełną sieżką dostępu
wskaźniki do łańcuchów zawierających kolejne parametry wywołania
Przykład:
#include<iostream.h>
#include<conio.h>
void main (int argc, char *argv[])
{ cout<<*argc=*<<argc<<`\n';
int licznik=0;
while (licznik<argc){
cout<<*licznik=*<<licznik<<` ';
cout<<argv[licznik]<<`n';
licznik++ }
}
Program został zapisany w pliku test.cpp -> C:\CPP\test.exe
Wywołanie:
test Cienka czerwona linia
Ekran:
argc = 4
licznik = 0 C:\CPP\TEST.EXE
licznik = 1 Cienka
licznik = 2 czerwona
licznik = 3 linia
Jeżeli nie podamy argumentów w linii komend to argc=1 i argv[0] zawiera nazwa programu wraz z pełną sieżką dostępu
Funkcje rekurencyjne
Funkcje języka C mogą być wywoływane rekurencyjnie, tzn. funkcja może wywoływać sama siebie zarówno bezpośrednio jak i pośrednio. Najprostszym przykładem funkcji rekurencyjnej może być funkcja obliczająca wartość silni dowolnej liczby naturalnej.
double silnia_rec (unsigned n) |
double silnia(unsigned n) |
{ |
{ |
if(n > 0) |
long sil=1; |
sil = n * silnia_rec(n-1); |
int i; |
else |
for(i = 1;i<=n;i++) |
sil = 1; |
sil = sil *i; |
return sil; |
return sil; |
} |
} |
3
1