INF1 2011 Prac 07


MATERIAAY POMOCNICZE NR 7 Gdy dochodzimy do instrukcji zawierającej funkcję add(), to wywołanie tej funkcji
DO PRACOWNII Z PRZEMIOTU  INFORMATYKA 1 powoduje przekazanie sterowania do jej pierwszej instrukcji.
Do funkcji add() przekazywane sÄ… dwa parametry typu float. Pierwszy parametr (a)
Funkcje otrzymuje wartość pierwszego parametru wywołania funkcji (x1), natomiast drugi
parametr (b) - wartość drugiego parametru wywołania funkcji (x2).
W programie w języku C zawsze występuje co najmniej jedna funkcja - main().
Powrót z funkcji (do miejsca zaraz po jej wywołaniu) następuje na skutek wykonania
Od funkcji main() rozpoczyna się wykonanie całego programu.
instrukcji return.
Oprócz niej mogą występować także inne funkcje zdefiniowane przez użytkownika.
Wartość zwracana przez funkcję podstawiana jest pod zmienną wynik.
Ogólna struktura funkcji w języku C jest następująca:
Po słowie return może występować dowolne wyrażenie. Wyrażenie to często
umieszczane jest w nawiasach, ale nie jest to konieczne.
argumenty
typ wartości
Funkcję add() można zapisać w prostszy sposób:
nazwa funkcji
przekazywane do funkcji
zwracanej
float add(float a, float b)
przez funkcjÄ™
nagłówek funkcji
float add(float a, float b)
{
{
return (a+b);
float y;
instrukcja
}
y = a + b;
instrukcja ciało funkcji
W wywołaniu funkcji jako parametry mogą występować zmienne, wyrażenia
return y;
instrukcja
arytmetyczne lub stałe liczbowe, np.
}
wynik = add(10,20);
wartość zwracana
wynik = add(x1*20+4,x1/x2);
przez funkcjÄ™
Istnieją funkcje, które nie zwracają żadnej wartości, wtedy jako typ zwracanego wyniku
podajemy void, np.
Przykład nr 8.1
void drukuj(int a)
Funkcja dodajÄ…ca dwie liczby.
{
printf( Liczba a wynosi: %d \n ,a);
#include
return;
#include
}
float add(float a, float b)
Wywołanie takiej funkcji w programie ma postać: drukuj(-10);
{
float y; Powyższa funkcja nie zwraca żadnego wyniku więc wystarczy samo słowo return. Jeśli
y = a + b;
funkcja nie zwraca wyniku i nie ma w jej ciele return to sterowanie wraca do punktu
return y;
wywołania na skutek zakończenia wykonania wszystkich instrukcji w bloku funkcyjnym.
}
Mogą istnieć funkcje, do których nie przekazujemy żadnych parametrów formalnych, np.
int main()
void linia() void linia(void)
{
float x1=10.0, x2=20.0, wynik; { {
printf( ----------\n ); lub printf( ----------\n );
wynik = add(x1,x2);
} }
printf("Wynik = %f\n", wynik);
Wywołanie takich funkcji w programie ma postać: linia(); - nawiasy są konieczne.
getch()
Ale już zapis:
return 0;
}
linia(void)
{
printf( ----------\n );
Wykonanie powyższego programu rozpoczyna się od funkcji main().
}
Informatyka 1 - Pracownia Strona 1 z 9 © 2011 JarosÅ‚aw Forenc Informatyka 1 - Pracownia Strona 2 z 9 © 2011 JarosÅ‚aw Forenc
nie jest równoważny powyższym zapisom, gdyż jeśli nie podamy typu zwracanej
Przykład nr 8.2
wartości przez funkcję, to domyślnie jest to typ int.
Przekazywanie parametrów do funkcji przez wartość.
#include
#include
Umieszczanie definicji funkcji w programie
Definicje funkcji można umieszczać w dowolnym miejscu programu - przed lub po
void fun(int a, int b)
{
funkcji main(). Należy jednak pamiętać o tym, że zasięg widzialności funkcji rozpoczyna
printf("fun1: a=%3d, b=%3d \n",a,b);
siÄ™ od miejsca jej deklaracji.
a = 10;
Jeśli chcemy umieścić definicję funkcji po funkcji main(), czyli po miejscu, w którym b = 10;
printf("fun2: a=%3d, b=%3d \n",a,b);
jest wywoływana, to musimy wcześniej podać jej formalną deklarację czyli prototyp.
}
Prototyp opisuje to samo co nagłówek, ale kończy się średnikiem. W prototypie nie
int main()
musimy podawać nazw argumentów formalnych - wystarczą tylko typy.
{
Podanie nazw argumentów ma jednak znaczenie dla czytelności programu.
int a = 20, b = 20;
Dzięki prototypom kompilator ma możliwość sprawdzenia zgodności typów formalnych
printf("main1: a = %3d, b = %3d \n",a,b);
i faktycznych.
fun(a,b);
printf("main2: a = %3d, b = %3d \n",a,b);
Rozpatrzmy strukturę następujących dwóch programów:
#include & #include & getch();
return 0;
}
void fun(int a, int b); void fun (int a, int b)
{
int main() &
Wynik działania programu:
{ }
main1: a = 20, b = 20
&
fun1: a = 20, b = 20
fun(a,b); int main()
fun2: a = 10, b = 10
& {
main2: a = 20, b = 20
} &
Po powrocie z funkcji fun() wartości zmiennych a i b nie zmieniły się, gdyż w funkcji
fun(a,b);
fun() pracowaliśmy na ich kopiach (posiadających takie same nazwy).
void fun (int a, int b) &
{ }
&
Przekazywanie parametrów do funkcji przez wskaznik
}
Przekazywanie parametrów do funkcji przez wskaznik polega na tym, że do funkcji
W programie po lewej stronie funkcja fun() zdefiniowana jest po funkcji main(), dlatego przekazywane sÄ… adresy zmiennych. Wszystkie operacje w funkcji wykonywane sÄ… zatem
przed funkcją main() umieszczony jest prototyp funkcji fun(), który może mieć jedną na zmiennych z funkcji wywołującej (poprzez adres tych zmiennych).
z dwu postaci:
Przykład nr 8.3
void fun(int a, int b); lub void fun(int, int);
Przekazywanie parametrów do funkcji przez wskaznik.
W programie po prawej stronie umieszczenie prototypu funkcji fun() nie jest konieczne,
#include
gdyż definicja funkcji fun() umieszczona jest przed funkcją main().
#include
void fun(int *a, int *b)
{
Przekazywanie parametrów do funkcji przez wartość
printf("fun1: a=%3d, b=%3d \n",*a,*b);
Przekazywanie parametrów przez wartość oznacza, że po przekazaniu sterowania do
*a = 10;
funkcji tworzone są kopie zmiennych przekazywanych do funkcji i wszystkie działania *b = 10;
w funkcji wykonywane sÄ… na kopiach.
Informatyka 1 - Pracownia Strona 3 z 9 © 2011 JarosÅ‚aw Forenc Informatyka 1 - Pracownia Strona 4 z 9 © 2011 JarosÅ‚aw Forenc
#include ...
printf("fun2: a=%3d, b=%3d \n",*a,*b);
zmienne a i b typu int sÄ… zmiennymi globalnymi,
}
int a, b;
zmienne a i c typu float sÄ… zmiennymi lokalnymi widzianymi
int main()
tylko w funkcji f1(),
{ void f1()
int a = 20, b = 20;
{
zmienne c i d typu int sÄ… zmiennymi lokalnymi widzianymi
float a, c;
tylko w funkcji main(),
printf("main1: a = %3d, b = %3d \n",a,b);
...
fun(&a,&b);
zmienna globalna b widziana jest w obu funkcjach: f1()
}
printf("main2: a = %3d, b = %3d \n",a,b);
i main(),
getch();
int main() zmienna globalna a widziana jest tylko w funkcji main(),
return 0;
{ gdyż w funkcji f1() jej nazwa została przesłonięta przez
}
int c, d; zmiennÄ… lokalnÄ… a typu float.
...
}
Wynik działania programu:
main1: a = 20, b = 20
fun1: a = 20, b = 20
Przekazywanie tablicy jednowymiarowej (wektora) do funkcji
fun2: a = 10, b = 10
main2: a = 10, b = 10
Przy przekazywaniu do funkcji wektora, w nagłówku funkcji umieszczamy typ
elementów wektora, jego nazwę i same nawiasy kwadratowe lub nawiasy kwadratowe
Po powrocie z funkcji fun() wartości zmiennych a i b zostały zmienione, gdyż do funkcji
z rozmiarem wektora:
fun() przekazane zostały adresy zmiennych a i b (&a, &b) i pracowaliśmy na zmiennych
poprzez ich adresy.
void zeruj(int tab[]) lub void zeruj(int tab[5])
W funkcji main(): int a; - deklaracja zmiennej typu int,
W wywołaniu funkcji podajemy natomiast tylko nazwę wektora:
a - zmienna typu int,
zeruj(tab);
&a - adres zmiennej, a nie jej wartość.
W funkcji fun(): int *a; - deklaracja zmiennej wskaznikowej (wskaznik na int),
Przykład nr 8.4
a - adres zmiennej typu int,
Przekazywanie do funkcji tablicy jednowymiarowej (wektora).
*a - wartość zmiennej wskazywanej przez a.
#include
#include
Zmienne lokalne i zmienne globalne
void zeruj(int tab[5])
Zmienne zadeklarowane w funkcjach sÄ… zmiennymi lokalnymi widzianymi tylko {
int i;
w obrębie danej funkcji (bloku funkcyjnego) od miejsca, w którym zostały
for(i=0; i<5; i++) tab[i] = 0;
zadeklarowane. Zmienne lokalne sÄ… zmiennymi automatycznymi.
}
Zmienne zadeklarowane poza funkcjÄ… main sÄ… zmiennymi globalnymi widzianymi
int main()
w całym programie od miejsca deklaracji (są to zmienne statyczne).
{
int i, tab[5] = {1,2,3,4,5};
Jeśli zmienna globalna i lokalna mają takie same nazwy, to zmienna lokalna przesłania
widzialność zmiennej globalnej w danej funkcji.
for(i=0; i<5; i++) printf("%3d",tab[i]);
printf("\n");
zeruj(tab);
for(i=0; i<5; i++) printf("%3d",tab[i]);
printf("\n");
getch();
return 0;
}
Informatyka 1 - Pracownia Strona 5 z 9 © 2011 JarosÅ‚aw Forenc Informatyka 1 - Pracownia Strona 6 z 9 © 2011 JarosÅ‚aw Forenc
Wynikiem działania powyższego programu jest: Wynikiem działania powyższego programu jest:
1 2 3 4 5 1 2 3
0 0 0 0 0 4 5 6
Do funkcji zeruj() jest przekazywany adres wektora. Wszystkie operacje dokonane na
0 0 0
wektorze w funkcji są uwzględnione po wyjściu z niej. 0 0 0
Do funkcji zeruj() jest przekazywany adres macierzy. Wszystkie operacje dokonane na
macierzy w funkcji są uwzględnione po wyjściu z niej.
Przekazywanie tablicy dwuwymiarowej (macierzy) do funkcji
Przy przekazywaniu do funkcji tablicy dwuwymiarowej musimy koniecznie podać liczbę
wierszy i kolumn lub tylko liczbÄ™ kolumn: Przekazywanie struktur do funkcji
void zeruj(int tab[2][3]) lub void zeruj(int tab[][3]) Struktury przekazywane są do funkcji tak jak każde inne zmienne podstawowych typów,
czyli przez wartość.
W wywołaniu funkcji podajemy natomiast tylko nazwę tablicy:
zeruj(tab);
Przykład nr 8.6
Program zawierający funkcję obliczającą odległość dwóch punktów.
Przykład nr 8.5
Przekazywanie do funkcji tablicy dwuwymiarowej (macierzy).
#include
#include
#include
#include
#include
struct punkt
void zeruj(int tab[][3])
{
{
int x, y;
int i, j;
};
for(i=0; i<2; i++)
for(j=0; j<3; j++)
float odleglosc(struct punkt pkt1, struct punkt pkt2)
tab[i][j] = 0;
{
}
return sqrt(pow(pkt2.x-pkt1.x,2)+pow(pkt2.y-pkt1.y,2));
}
void drukuj(int tab[2][3])
{
int main()
int i, j;
{
for(i=0; i<2; i++)
struct punkt p1 = {2,3}, p2 = {-2,1};
{
float odl;
for(j=0; j<3; j++)
printf("%3d",tab[i][j]);
odl = odleglosc(p1,p2);
printf("\n");
printf("Punkt nr 1: (%d,%d)\n",p1.x,p1.y);
}
printf("Punkt nr 2: (%d,%d)\n",p2.x,p2.y);
printf("\n");
printf("Odleglosc = %g\n",odl);
}
getch();
int main()
return 0;
{
}
int i, j, tab[2][3] = {{1,2,3},{4,5,6}};
drukuj(tab);
zeruj(tab);
drukuj(tab);
Rekurencyjne wywołanie funkcji
getch();
Rekurencyjne wywołanie funkcji polega na ponownym jej wywołaniu zanim skończyło
return 0;
się jej poprzednie wywołanie.
}
Poniżej znajdują się trzy wersje funkcji obliczającej silnię liczby n.
Informatyka 1 - Pracownia Strona 7 z 9 © 2011 JarosÅ‚aw Forenc Informatyka 1 - Pracownia Strona 8 z 9 © 2011 JarosÅ‚aw Forenc
Przykład nr 8.7 (a)
Funkcja obliczajÄ…ca silniÄ™ liczby (wersja nierekurencyjna).
int silnia(int n)
{
int i, wynik = 1;
for (i=1; i<=n; i++)
wynik = wynik * i;
return wynik;
}
Przykład nr 8.7 (b)
Funkcja obliczajÄ…ca silniÄ™ liczby (wersja rekurencyjna).
int silnia(int n)
{
if (n<=1)
return 1;
else
return n*silnia(n-1);
}
Przykład nr 8.7 (c)
Funkcja obliczajÄ…ca silniÄ™ liczby (wersja rekurencyjna).
int silnia(int n)
{
return n ? n*silnia(n-1) : 1;
}
Informatyka 1 - Pracownia Strona 9 z 9 © 2011 JarosÅ‚aw Forenc


Wyszukiwarka

Podobne podstrony:
INF1 2011 Wykl 07 Dzienne 4na1
W czyje sumienia wpisano te groby Nasz Dziennik, 2011 03 07
Ludobójstwo bez kary Nasz Dziennik, 2011 03 07
Kerski spóźnił się z ofertą Nasz Dziennik, 2011 03 07
Wotum nieufności dla Edmunda Klicha Nasz Dziennik, 2011 03 07
2011 01 07 Warsztatowcy znow na Chalubinskiego (1)
Komorowski nie słucha rodzin Nasz Dziennik, 2011 03 07
Åšwiat w chaosie Nasz Dziennik, 2011 03 07
Czyja jest TVP Nasz Dziennik, 2011 03 07
egzamin zawodowy 2011 prac biurowych

więcej podobnych podstron