 
C/C++
funkcje
postać, przekazywanie parametrów
argumenty funkcji main() 
funkcje rekurencyjne
funkcje przeciąŜone
zasięg deklaracji zmiennych
przesłanianie zmiennych
 
C/C++ - funkcje
Funkcje są jedynymi  elementami strukturalnymi w języku C i podstawowym 
budulcem klas w C++. 
Funkcje są podprogramami które separują pewien fragment kodu od pozostałej 
części programu.
Posiadają identyfikator (nazwę), oraz jest dla nich określany sposób 
przekazywania parametrów (argumentów) i zwracania rezultatów działania, 
czyli interfejs.
Raz napisana funkcja moŜe być wielokrotnie wykorzystana poprzez 
wywołanie z parametrami aktualnymi (wywołania).
funkcja
parametry
rezultat
 
C/C++ - funkcje
Ogólna postać funkcji jest następująca:
typ_rezultatu nazwa_funkcji(lista_parametrów)
{
ciało funkcji, czyli instrukcje
return wynik;
}
W pierwszym wierszu definicji funkcji następuje określenie typu rezultatu 
zwracanego przez funkcję, nazwy funkcji oraz określenie argumentów (parametrów) 
stanowiących dane wymagane przez funkcję do prawidłowego wyznaczenia rezultatu 
działania funkcji. Instrukcje wykonywane w ramach funkcji są ujęte w nawiasy 
programowe. Wynik działania funkcja zwraca wykonując instrukcję return. 
Instrukcja return kończy działanie funkcji. Wartość zwracana poleceniem  return
musi być zgodna z typem rezultatu określonym w pierwszym wierszu definicji 
funkcji. Pominięcie określenia typu rezultatu zwracanego przez funkcję oznacza 
przyjęcie domyślnego typu int.  Lista parametrów zawiera listę deklaracji zmiennych 
(tzw. parametrów formalnych funkcji). Poszczególne jej elementy są separowane 
przecinkiem. 
 
C/C++ - funkcje
Przykład . Funkcja na obliczanie silni liczby.
long int silnia(int liczba)
{
long int silnia=1;
for(int i=2;i<=liczba;i++) silnia*=i;
return silnia; //zwrócenie wyniku przez funkcj
ę
}
main()
{
int n;
long int r;
r=silnia(n); // wywołanie funkcji
return 0;
}
parametr
formalny
parametr aktualny
przykład
W momencie wywołania funkcji parametry aktualne „kojarzone” są z
parametrami formalnymi.
 
C/C++ - funkcje
Przekazywanie parametrów do funkcji
Poprawnie zdefiniowana funkcja nie korzysta ze zmiennych globalnych
(zadeklarowanych poza funkcjami).
Wszystkie potrzebne dane funkcja powinna otrzymywać przez listę parametrów.
WyróŜnia się trzy sposoby przekazywania parametrów do funkcji:
1.
przez wartość
2.
przez adres (wskaźnik)
3.
przez referencję
Przekazywanie parametrów przez wartość umoŜliwia jedynie przekazanie wartości
zmiennych, funkcja w tym przypadku nie moŜe  modyfikować wartości 
zmiennych przekazywanych jako parametry.
Aby funkcja mogła zmieniać zawartość zmiennej musi otrzymać jej adres lub
zmienna musi być przekazana przez referencję.
 
C/C++ - funkcje
Przekazywanie parametrów przez wartość
przykład
float suma(float a,float b)
{
a=a+b;
return a;
}
main()
{
float x=3.4,y=4.6,z;
z=suma(x,y);// po wywołaniu funkcji warto
ść
zmiennej
//nie uległa zmianie i wynosi nadal x=3.4
return 0;
}
 
C/C++ - funkcje
Przekazywanie parametrów przez adres (zmienną wskaźnikową)
przykład
void suma(float *a,float b) //wynik zwracany przez
// pierwszy składnik
{
*a=*a+b;
}
main()
{
float x=2.4,y=4.7;
suma(&x,y);
// w wywołaniu funkcji przekazywany jest
//adres zmiennej w której znajdzie si
ę
wynik
return 0;
 
C/C++ - funkcje
Zmienne referencyjne
W języku C++ został wprowadzony tzw. typ referencyjny  umoŜliwiający 
kojarzenie zmiennych ze zmiennymi referencyjnymi w takim sensie, Ŝe 
operacja na zmiennej referencyjnej powoduje natychmiastową modyfikację 
zmiennej  z nią skojarzonej i nadanie jej takiej samej wartości.
W linii deklaracji zmiennej referencyjnej naleŜy skojarzyć z nią zmienna.
Deklaracja zmiennej referencyjnej:
int x, &r=x; // r zmienna referencyjna
r=20;
cout<<x;
przykład
 
C/C++ - funkcje
Przekazywanie parametrów przez referencję
przykład
void suma(float &a,float b) //wynik zwracany przez
// pierwszy składnik
{
a=a+b;
}
main()
{
float x=2.4,y=4.7;
suma(x,y);
// wynik w zmiennej x
return 0;
}
 
C/C++ - funkcje
Przekazywanie tablic do funkcji -
tablice jednowymiarowe
W przypadku przekazywania funkcjom tablic jednowymiarowych (takŜe
wielowymiarowych) nie jest moŜliwe przekazanie tablicy przez wartość. 
Podczas wywołania funkcji naleŜy przekazać adres pierwszego  elementu 
tablicy (wskaźnik do początku tablicy). 
Parametr formalny (w definicji funkcji) moŜna zadeklarować jako:
wskaźnik,
tablicę o określonym rozmiarze,
tablicę o nieokreślonym rozmiarze.
W kaŜdym z przypadków informację o długości tablicy naleŜy przekazać 
niezaleŜnie. 
W funkcji do elementów tablicy odwoływać się moŜna dwojako:  przez 
wskaźnik lub przez operator []. 
 
C/C++ - funkcje
Przekazywanie tablic jednowymiarowych do funkcji przez wskaźnik do typu
elementu
(odwoływanie do elementu przez wskaźnik)
przykład
#include <conio.h>
#include <iostream>
#define N 5
double srednia(int *w,int n)
{
double wynik;
for (int i=0;i<n;i++) wynik+=*(w+i);
return wynik/n;
}
main ()
{
int wek[N]={1,2,3,4,5};
double x;
x=srednia(wek,N);
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablic jednowymiarowych do funkcji przez wskaźnik
do typu elementu (odwoływanie do elementu przez operator [])
przykład
#include <conio.h>
#include <iostream>
#define N 5
double srednia(int *w,int n)
{
double wynik;
for (int i=0;i<n;i++) wynik+=w[i];
return wynik/n;
}
main ()
{
int wek[N]={1,2,3,4,5};
double x;
x=srednia(wek,N);
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablic jednowymiarowych do funkcji przez deklarację
wskaźnika do tablicy (określony rozmiar)
przykład
#include <conio.h>
#include <iostream>
#define N 5
double srednia(int w[5],int n)
{
double wynik;
for (int i=0;i<n;i++) wynik+=w[i];
return wynik/n;
}
main ()
{
int wek[N]={1,2,3,4,5};
double x;
x=srednia(wek,N);
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablic jednowymiarowych do funkcji przez deklarację
wskaźnika do tablicy ( nieokreślony rozmiar)
przykład
#include <conio.h>
#include <iostream>
#define N 5
double srednia(int w[],int n)
{
double wynik;
for (int i=0;i<n;i++) wynik+=w[i];
return wynik/n;
}
main ()
{
int wek[N]={1,2,3,4,5};
double x;
x=srednia(wek,N);
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablic jednowymiarowych do funkcji przez deklarację
wskaźnika do tablicy (nieokreślony rozmiar) odwołanie przez wskaźnik
przykład
#include <conio.h>
#include <iostream>
#define N 5
double srednia(int w[],int n)
{
double wynik;
for (int i=0;i<n;i++) wynik+=*(w+i);
return wynik/n;
}
main ()
{
int wek[N]={1,2,3,4,5};
double x;
x=srednia(wek,N);
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablic do funkcji -
tablice wielowymiarowe
W przypadku przekazywania tablic wielowymiarowych jeŜeli
parametr formalny został zadeklarowany jako wskaźnik, to w 
funkcji do elementów tablicy odwoływać się moŜna jedynie przez 
wskaźnik (odpowiednio obliczając adres w oparciu o indeksy 
tablicy.
JeŜeli natomiast, jako parametr formalny zadeklarowana została
tablica to musi ona posiadać określone wszystkie wymiary poza 
ostatnim (określonym tuŜ za nazwą tablicy). MoŜna oczywiście 
podać wszystkie wymiary. Podanie wymaganych wymiarów jest 
konieczne aby w funkcji moŜna było odwoływać się do 
elementów przez indeksy (przez []).
 
C/C++ - funkcje
Przekazywanie tablic do funkcji -
tablice wielowymiarowe
W wywołaniu funkcji jako parametr aktualny podać naleŜy:
-
adres pierwszego elementu np. &TAB[0][0], jeśli w liście 
parametrów formalnych zadeklarowany został wskaźnik,
-
nazwę tablicy np. TAB, jeśli w liście parametrów formalnych 
zadeklarowana została tablica. Wynika to z faktu, Ŝe &TAB[0][0] 
jest adresem pierwszego elementu tablicy, a TAB jest wskaźnikiem
do tablicy (zawiera informację o wymiarach), co przy tablicy o 
wymiarach 2x3 moŜna zapisać:
int (*wsk)[2][3] .
 
C/C++ - funkcje
Przekazywanie tablicy dwuwymiarowej do funkcji przez wskaźnik do typu
elementu tablicy
przykład
#include <conio.h>
#include <iostream>
#define N 2
#define M 3
double srednia(int *w,int n,int m)
{
double wynik;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++) wynik+=*(w+i*m+j);
return wynik/(n*m);
}
main ()
{
int tab[N][M]={1,2,3,4,5,6};
double x;
x=srednia(&tab[0][0],N,M); // x=srednia(tab,N,M); - bł
ą
d
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie tablicy dwuwymiarowej do funkcji przez deklarację
wskaźnika do tablicy
przykład
#include <conio.h>
#include <iostream>
#define N 2
#define M 3
double srednia(int w[][M],int n,int m)
{
double wynik;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++) wynik+=w[i][j];
return wynik/(n*m);
}
main ()
{
int tab[N][M]={1,2,3,4,5,6};
double x;
x=srednia(tab,N,M); // x=srednia(&tab[0][0],N,M); - bł
ą
d
cout<<"srednia elementów: "<<x;
getch();
return(0);
}
 
C/C++ - funkcje
Przekazywanie struktur do funkcji
Struktury do funkcji przekazuje się jak zmienne typu prostego, czyli przez: wartość,
wskaźnik, referencję.
Przykład. Przekazywanie struktury przez wartość.
przykład
#
include <iostream>
#include <math.h>
struct zespolona {
double re, im;
};
double modul(zespolona x)
{
return sqrt((x.re)*(x.re++)+(x.im)*(x.im));
// x.re zwiekszono o 1
}
int main()
{
zespolona zz={3.0,4.0}; // zainicjowanie zmiennej zespolonej
double y=modul(zz);
cout<<"abs("<<zz.re<<"+j"<<zz.im<<")="<<y;
// zz.re nie ulegla zmianie
return 0
}
 
C/C++ - funkcje
Przekazywanie struktur do funkcji
Przykład. Przekazywanie struktury przez wskaźnik.
przykład
#
include <iostream>
#include <math.h>
struct zespolona {
double re, im;
};
double modul(zespolona *x)
{
return sqrt((x->re)*(x->re++)+(x->im)*(x->im));
// x->re zwiekszono o 1
}
int main()
{
zespolona zz={3.0,4.0}; // zainicjowanie zmiennej zespolonej
double y=modul(zz);
cout<<"abs("<<zz.re<<"+j"<<zz.im<<")="<<y;
// zz.re została zmodyfikowana
return 0
}
 
C/C++ - funkcje
Przekazywanie struktur do funkcji
Przykład. Przekazywanie struktury przez referencję.
przykład
#
include <iostream>
#include <math.h>
struct zespolona {
double re, im;
};
double modul(zespolona &x)
{
return sqrt((x.re)*(x.re++)+(x.im)*(x.im));
// x->re zwiekszono o 1
}
int main()
{
zespolona zz={3.0,4.0}; // zainicjowanie zmiennej zespolonej
double y=modul(zz);
cout<<"abs("<<zz.re<<"+j"<<zz.im<<")="<<y;
// zz.re została zmodyfikowana
return 0
}
 
C/C++ - funkcje
Przekazywanie argumentów funkcji main()
W języku C/C++ moŜliwe jest przekazywanie parametrów
aplikacji . W tym celu naleŜy w liście argumentów funkcji 
main() umieścić dwa elementy. Pierwszy przekazuje liczbę 
argumentów a drugi wskaźnik do tablicy łańcuchów którymi 
są poszczególne parametry. Pierwszym argumentem 
obligatoryjnie staje się nazwa programu.
Argumenty aplikacji (z wiersza poleceń) zadaje się po nazwie
programu separując spacjami.
 
#
include <iostream>
#include <conio.h>
int main(int argc, char *argv[])
{int a,b;
cout<< argc<<'\n';
for (int i=0;argv[i];i++)
cout<< argv[i]<<'\n';
// a=argv[1]; // bł
ą
d
a=atoi(argv[1]);// atoi() – konwersja ła
ń
cucha na liczb
ę
int
cout<<a+1<<'\n';
getch();
return 0;
}
przykład
C/C++ - funkcje
Przekazywanie argumentów funkcji main()
 
C/C++ - funkcje
Funkcje rekurencyjne
Funkcje rekurencyjne są funkcjami, które w swoim ciele wywołują samą siebie.
NaleŜy wiedzieć, iŜ przy wywołaniu funkcji rekurencyjnej dochodzi do jej wielokrotnego 
wywołania bez kończenia wywołań poprzednich. Idzie za tym konieczność 
wielokrotnego składowania parametrów na stosie, co moŜe prowadzić do jego 
przepełnienia.
Zaletą funkcji rekurencyjnych jest duŜa szybkość wykonywania.
Ogólna postać funkcji rekurencyjnej
int funkcja_rek (int parametr)
{
...
liczba=funkcja_rek(parametr);
...
return 0;
}
 
C/C++ - funkcje
Funkcje rekurencyjne
Przykład. Iteracyjna i rekurencyjna postać funkcji na obliczanie silni
przykład
long double SilniaIteracyjna(int liczba)
{
long double silnia=1;
for(int i=1; i<=liczba; i++)
silnia*=i;
return silnia;
}
long double SilniaRekurencyjna(int liczba)
{
if (liczba==0)
return 1;
else
return liczba*SilniaRekurencyjna(liczba-1);
}
 
C/C++ - funkcje
Funkcje przeciąŜone
W języku C++ istnieje moŜliwość deklarowania funkcji o tej
samej nazwie i róŜnych interfejsach, czyli róŜnej liczbie 
argumentów, róŜnych ich typach, odmiennym sposobie 
zwracania wyników. Funkcje takie noszą nazwę 
przeciąŜonych lub przeładowanych.
Oczywiście funkcje przeciąŜone będą róŜniły się takŜe ciałami.
W przypadku funkcji przeciąŜonych kompilator rozpoznaje
funkcję po nazwie, liście argumentów i typie rezultatu.
 
C/C++ - funkcje
Funkcje przeciąŜone
Przykład. Funkcja przeciąŜona na obliczanie modułu liczby: całkowitej,
rzeczywistej i zespolonej.
przykład
struct complex{
double re,im;
};
double abs(double x)
{
return x>0?x:-x;
}
int abs(int i)
{
return i>0?i:-i;
}
double abs(complex z)
{
return sqrt(z.re*z.re+z.im*z.im);
}
int main(){
complex s={-2,4};
cout<<abs(-12.39)<<"\n";
cout<<abs(35)<<"\n";
cout<<abs(s)<<"\n";
getch();
return 0;
}
 
C/C++ - zasięg deklaracji zmiennych
1.
W języku C/C++ nie ma obowiązku deklarowania zmiennych w określonym 
miejscu. Pamiętać jednak, Ŝe od miejsca deklaracji zmiennej zaleŜy jej zasięg.
2.
Zmienne globalne (deklarowane poza funkcjami) posiadają domyślną klasę 
pamięci static i są widoczne w kaŜdym miejscu w programie o ile nie zostały 
przesłonięte przez zmienne lokalne funkcji. Zmienne lokalne (deklarowane w 
funkcjach) są widoczne widoczne tylko wewnątrz funkcji w których zostały 
zadeklarowane.
3.
Zmienne zadeklarowane wewnątrz funkcji posiadają domyślną klasę auto i są 
usuwane z pamięci po zakończeniu działania funkcji. Deklaracja zmiennej klasy 
static wewnątrz funkcji powoduje, Ŝe pozostaje ona w pamięci po zakończeniu 
działania funkcji.
4.
Zmienne zadeklarowane w liście parametrów funkcji są zmiennymi lokalnymi 
funkcji.
5.
Zmienne zadeklarowane w bloku są widoczne tylko w jego wnętrzu (w tym w 
jego zagnieŜdŜeniach).
 
C/C++ - zasięg deklaracji zmiennych
Zmienne globalne są widoczne w kaŜdym miejscu w programie.
#include <conio.h>
#include <iostream>
int zmienna_globalna=44444; // deklaracja zmiennej globalnej
void funkcja()
{
cout<<zmienna_globalna; //u
Ŝ
ycie zmiennej globalnej
}
int main()
{
cout<<zmienna_globalna; // u
Ŝ
ycie zmiennej globalnej
getch();
return(0);
}
przykład
 
C/C++ - zasięg deklaracji zmiennych
Zmienne lokalne  są widoczne tylko w funkcji gdzie zostały 
zadeklarowane (równieŜ te klasy static).
#include <conio.h>
#include <iostream>
void funkcja()
{
int zm_lok_1=333; //zmienna klasy auto
static int zm_lok_2=444; // zmienna klasy static
}
int main()
{
funkcja();
cout<<zm_lok_1; //b
łą
d - zmienna lokalna funkcji "funkcja"
cout<<zm_lok_2; //b
łą
d - zmienna lokalna funkcji "funkcja"
return(0);
}
przykład
 
C/C++ - zasięg deklaracji zmiennych
Zmienne zadeklarowane w liście parametrów funkcji są zmiennymi 
lokalnymi funkcji
#include <iostream>
#include <conio.h>
double trojkat(float &a,float b, float c)
{
double y;
y=a+b+c;
a=(a*b)/2;
return y;
}
main()
{
//float
a=3,b=4,c=5;
// błąd -niezadeklarowane zmienne
cout<<"obwod trojkata wynosi "<<trojkat(a,b,c);
cout<<"\na jego pole: "<<a;
return 0;
}
przykład
 
C/C++ - zasięg deklaracji zmiennych
Zmienne zadeklarowane w bloku są widoczne tylko w jego wnętrzu (w 
tym w jego zagnieŜdŜeniach).
#include <conio.h>
#include <iostream>
#include "losowanie.c"
main ()
{ const int N=2
,
M=3;
int tab[N][M],p;
randomize;
for ( int i=0;i<N;i++)
// zmienna i jest zmienn
ą
lokaln
ą
p
ę
tli for
for ( int j=0;j<M;j++){
// zmienna j jest zmienn
ą
lokaln
ą
p
ę
tli for
p=random(100);
// wewn
ę
trznej, tu s
ą
widoczne obie zmienne
tab[i][j]=p;
// i oraz j
}
i=2;j=3;
// poza p
ę
tlami zmienne i oraz j nie s
ą
widoczne,
getch();
// zostały ju
Ŝ
zniszczone a pami
ęć
im przydzielona zwolniona
return(0);
}
przykład
 
C/C++ - przesłanianie zmiennych
W języku C, tak jak w innych językach programowania, nie jest 
moŜliwe zadeklarowanie dwóch zmiennych o identycznych nazwach 
w tym samym bloku. Nie moŜe być zatem dwóch zmiennych 
globalnych o tej samej nazwie, podobnie w jednej funkcji nie moŜe 
być dwóch zmiennych lokalnych o tym samym identyfikatorze, a 
takŜe w jednej pętli (w jednym bloku).
MoŜna jednak deklarować zmienne o tej samej nazwie, o ile są 
zmiennymi lokalnymi róŜnych funkcji lub znajdują się w róŜnych 
blokach tego samego poziomu (bloki nie są zagnieŜdŜone).
MoŜna  w funkcji zadeklarować zmienną (lokalną) o takiej samej 
nazwie jak zmienna globalna. Wówczas w funkcji zmienna 
lokalna przesłania zmienną globalną i to na niej są wykonywane 
operacje realizowane w ramach funkcji. 
 
C/C++ - przesłanianie zmiennych
Przykład
#include <conio.h>
#include <iostream>
int x=444;
// deklaracja zmiennej globalnej o nazwie x
void funkcja()
{
int x=222;
// deklaracja zmiennej o nazwie x
cout<<x<<'\n';
//operacja zu
Ŝ
yciem zmiennej lokalnej
}
// zmienna lokalna przesłoniła zmienn
ą
globaln
ą
int main()
{ cout<<x<<'\n'; // u
Ŝ
ycie zmiennej globalnej
funkcja();
cout<<x;
getch();
return(0);
}
przykład