25.01.2015 Views

Wprowadzenie do programowania w języku C — struktura programu

Wprowadzenie do programowania w języku C — struktura programu

Wprowadzenie do programowania w języku C — struktura programu

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Wprowadzenie</strong> <strong>do</strong> <strong>programowania</strong><br />

w języku C<br />

Część trzecia<br />

Struktura <strong>programu</strong><br />

Autor<br />

Roman Simiński<br />

Kontakt<br />

siminski@us.edu.pl<br />

www.us.edu.pl/~siminski<br />

Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa.<br />

Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne.<br />

Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione.


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego<br />

Problem<br />

Struktura <strong>programu</strong><br />

Spróbujmy to napisać z wykorzystaniem podprogramów<br />

Napisać program obliczający obwód i pole<br />

koła o promieniu podanym przez<br />

użytkownika.<br />

W języku C nie występuje podział podprogramów na procedury i funkcje. Wszystkie<br />

podprogramy są funkcjami, istnieje jednak możliwość wykorzystywania funkcji jak<br />

procedur, bądź deklarowania funkcji tak, by przypominały procedury.<br />

#include <br />

#include <br />

int main()<br />

{<br />

przywitanie();<br />

Wywołanie funkcji<br />

}<br />

return EXIT_SUCCESS;<br />

int przywitanie( void )<br />

{<br />

puts( "\nCzesc, tu funkcja przywitanie" );<br />

return 0;<br />

}<br />

Definicja funkcji<br />

Copyright © Roman Simiński Strona : 2


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — funkcje<br />

Czy testowy program się skompiluje bez problemów<br />

Tak, bez błędów i ostrzeżeń — w starszych wersjach kompilatorów.<br />

Dlaczego występują te rozbieżności<br />

Struktura <strong>programu</strong><br />

Tak, bez błędów lecz z ostrzeżeniem — w nowszych wersjach kompilatorów, oraz tych<br />

pracujących w trybie zgodności z normą ANSI.<br />

Nie, wystąpi błąd — w kompilatorach pracujących w trybie C++.<br />

Definicja funkcji przywitanie występuje po jej wywołaniu. Kompilator na etapie<br />

wywołania jej jeszcze nie zna. Czyni w stosunku <strong>do</strong> niej założenia — że to funkcja, której<br />

rezultatem jest wartość int. To założenie może być słusznie albo nie.<br />

Aby uniknąć niejednoznaczności, wprowadza się prototypy funkcji.<br />

Aby kompilator mógł kontrolować poprawność wywołania funkcji, należy to wywołanie<br />

poprzedzić definicją lub deklaracją wywoływanej funkcji. Deklaracja przyjmuje postać<br />

prototypu funkcji.<br />

Definicja funkcji<br />

int przywitanie( void )<br />

{<br />

puts( "\nCzesc, tu funkcja przywitanie" );<br />

return 0;<br />

}<br />

Prototyp funkcji<br />

int przywitanie( void );<br />

Copyright © Roman Simiński Strona : 3


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — funkcje<br />

Struktura <strong>programu</strong><br />

Ogólna postać definicji funkcji:<br />

nazwa_funkcji ( lista_parametrów_formalnych )<br />

{<br />

ciało_funkcji<br />

}<br />

Ogólna postać prototypu funkcji:<br />

nazwa_funkcji ( lista_parametrów_formalnych );<br />

Dwie wersje poprawnego <strong>programu</strong> przykła<strong>do</strong>wego<br />

Z prototypem:<br />

Po „paskalowemu”:<br />

. . .<br />

int przywitanie( void );<br />

int main()<br />

{<br />

przywitanie();<br />

. . .<br />

int przywitanie( void )<br />

{<br />

. . .<br />

}<br />

}<br />

return EXIT_SUCCESS;<br />

int przywitanie( void )<br />

{<br />

. . .<br />

}<br />

int main()<br />

{<br />

przywitanie();<br />

}<br />

return EXIT_SUCCESS;<br />

Copyright © Roman Simiński Strona : 4


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — funkcje<br />

Struktura <strong>programu</strong><br />

Dlaczego przywitanie to funkcja, skoro nie u<strong>do</strong>stępnia sensownego rezultatu<br />

int przywitanie( void )<br />

{<br />

puts( "\nCzesc, tu funkcja przywitanie" );<br />

return 0;<br />

}<br />

Może lepiej tak, czyli jak zrobić z funkcji procedurę:<br />

void przywitanie( void )<br />

{<br />

puts( "\nCzesc, tu funkcja przywitanie" );<br />

}<br />

Ale może być kłopot<br />

int main()<br />

{<br />

przywitanie();<br />

}<br />

return EXIT_SUCCESS;<br />

void przywitanie( void )<br />

{<br />

puts( "\nCzesc, tu funkcja przywitanie" );<br />

}<br />

Kompilator zakłada, że funkcja<br />

będzie miała rezultat int.<br />

Copyright © Roman Simiński Strona : 5


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — funkcje, podsumowanie<br />

Struktura <strong>programu</strong><br />

Podsumowanie informacji o prototypach<br />

Starsze implementacje C <strong>do</strong>puszczały wywoływanie funkcji wcześniej kompilatorowi<br />

nieznanych.<br />

W trakcie kompilowania wywołania nieznanej funkcji przez <strong>do</strong>mniemanie<br />

przyjmowano, że zwraca ona wartość int i nic nie wia<strong>do</strong>mo na temat jej parametrów.<br />

Nie pozwalało to kompilatorowi kontrolować poprawności wywołania funkcji.<br />

Aby kompilator mógł kontrolować poprawność wywołania funkcji, należy to<br />

wywołanie poprzedzić definicją lub deklaracją wywoływanej funkcji.<br />

Deklaracja przyjmuje postać prototypu funkcji.<br />

Deklaracja i definicja funkcji powinna być zgodna. Jeżeli w obrębie jednego pliku<br />

wystąpi niezgodność, kompilator zgłosi błąd kompilacji.<br />

Copyright © Roman Simiński Strona : 6


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — funkcje, podsumowanie<br />

Struktura <strong>programu</strong><br />

Uwagi na temat definicji funkcji:<br />

Słowo kluczowe void, będące nazwą typu, oznacza brak, nieobecność jakiejkolwiek<br />

wartości.<br />

Jeżeli typem rezultatu będzie typ określany słowem kluczowym void, to oznacza, iż<br />

funkcja nie u<strong>do</strong>stępnia rezultatu – staje się wtedy czymś po<strong>do</strong>bnym <strong>do</strong> procedury<br />

z języka Pascal.<br />

Jeżeli w miejscu listy parametrów formalnych występuje słowo kluczowe void, to<br />

oznacza, że funkcja nie posiada parametrów.<br />

Jeżeli funkcja „zwraca wartość” w miejscu wywołania, w ciele funkcji powinna<br />

wystąpić instrukcja return, a po niej, wyrażenie o typie zgodnym z typem rezultatu<br />

funkcji.<br />

Na liście parametrów formalnych, dla każdego parametru określamy jego typ.<br />

Copyright © Roman Simiński Strona : 7


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — obliczanie obwodu i pola koła<br />

Struktura <strong>programu</strong><br />

A może by tak w końcu wrócić <strong>do</strong> <strong>programu</strong>, który mieliśmy napisać...<br />

#include <br />

#include <br />

#define PI 3.14<br />

#define MAKS_DL 80<br />

void komunikat_wstepny( void );<br />

void oblicz( void );<br />

float obwod_kola( float r );<br />

float pole_kola( float r );<br />

int main()<br />

{<br />

komunikat_wstepny();<br />

oblicz();<br />

}<br />

return EXIT_SUCCESS;<br />

void komunikat_wstepny( void )<br />

{<br />

puts("\nObliczam obwod ...");<br />

}<br />

void oblicz( void )<br />

{<br />

float r;<br />

char s[ MAKS_DL ];<br />

}<br />

printf("\nPodaj promien R = " );<br />

fgets( s, MAKS_DL, stdin );<br />

r = atof( s );<br />

printf( "Obwod : %g\n", obwod_kola(r) );<br />

printf( "Pole : %g\n", pole_kola(r) );<br />

printf( "\nNacisnij Enter by ..." );<br />

getchar();<br />

float obwod_kola( float r )<br />

{<br />

return 2 * PI * r;<br />

}<br />

float pole_kola( float r )<br />

{<br />

return PI * r * r;<br />

}<br />

Copyright © Roman Simiński Strona : 8


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — przykłady funkcji<br />

Struktura <strong>programu</strong><br />

Kilka prostych funkcji<br />

void print_message( void )<br />

{<br />

puts( "\nObliczam pole kola" );<br />

}<br />

int zawsze_5( void ) /* Wiem, że to bez sensu :-\ */<br />

{<br />

return 5;<br />

}<br />

float <strong>do</strong>_kwadratu( float a )<br />

{<br />

return a * a;<br />

}<br />

float oblicz_spalanie( float paliwo, float dystans )<br />

{<br />

return ( paliwo * 100 ) / dystans;<br />

}<br />

Copyright © Roman Simiński Strona : 9


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — przykłady funkcji<br />

Zamiast<br />

Struktura <strong>programu</strong><br />

. . .<br />

printf("\nPodaj promien R = " );<br />

fgets( s, MAKS_DL, stdin );<br />

r = atof( s );<br />

printf( "Obwod : %g\n", obwod_kola(r) );<br />

printf( "Pole : %g\n", pole_kola(r) );<br />

. . .<br />

A może tak:<br />

. . .<br />

printf("\nPodaj promien R = " );<br />

r = wczytaj_liczbe_f();<br />

printf( "Obwod : %g\n", obwod_kola( r ) );<br />

printf( "Pole : %g\n", pole_kola( r ) );<br />

. . .<br />

Przykład użytecznej funkcji<br />

float wczytaj_liczbe_f( void )<br />

{<br />

char bufor_tekstowy[ 80 ];<br />

}<br />

fgets( bufor_tekstowy, 80, stdin );<br />

return atof( bufor_tekstowy );<br />

Copyright © Roman Simiński Strona : 10


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — przykłady funkcji<br />

Struktura <strong>programu</strong><br />

Zamiast<br />

. . .<br />

printf("\nPodaj promien R = " );<br />

r = wczytaj_liczbe_f();<br />

printf( "Obwod : %g\n", obwod_kola( r ) );<br />

printf( "Pole : %g\n", pole_kola( r ) );<br />

. . .<br />

A może tak:<br />

. . .<br />

r = wczytaj_liczbe_f( "\nPodaj promien R = " );<br />

printf( "Obwod : %g\n", obwod_kola( r ) );<br />

printf( "Pole : %g\n", pole_kola( r ) );<br />

. . .<br />

Przykład użytecznej funkcji — wersja kolejna<br />

float wczytaj_liczbe_f( char komunikat[] )<br />

{<br />

char bufor_tekstowy[ 80 ];<br />

}<br />

printf( komunikat );<br />

fgets( bufor_tekstowy, 80, stdin );<br />

return atof( bufor_tekstowy );<br />

Copyright © Roman Simiński Strona : 11


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — przykłady funkcji<br />

Struktura <strong>programu</strong><br />

Przykład wykorzystania rezultatu <strong>do</strong> sygnalizacji błędów<br />

float oblicz_spalanie( float paliwo, float dystans )<br />

{<br />

if( dystans == 0 )<br />

return –1;<br />

else<br />

return fabs( ( paliwo * 100 ) / dystans );<br />

}<br />

. . .<br />

spalanie = oblicz_spalanie( 40.5, 0 );<br />

if( spalanie == -1 )<br />

printf( "Nie <strong>do</strong>konam oblicze ń dla błędnych danych" );<br />

else<br />

printf( "Spalanie %4.2f l na 100 km", spalanie );<br />

. . .<br />

Uwaga na instrukcję return<br />

float oblicz_spalanie( float paliwo, float dystans )<br />

{<br />

if( dystans == 0 )<br />

printf( "Nie <strong>do</strong>konam oblicze ń dla zerowego dystansu" ); // return <br />

else<br />

return ( paliwo * 100 ) / dystans;<br />

}<br />

Copyright © Roman Simiński Strona : 12


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong><br />

Struktura <strong>programu</strong> jednomodułowego — uwagi<br />

Parę pułapek związanych z definicjami funkcji<br />

W języku C wolno czasem opuścić słowo kluczowe int, wtedy zostanie ono przyjęte<br />

<strong>do</strong>myślnie. To, że tak robić można nie oznacza, że tak robić trzeba.<br />

Zapisy równoważne<br />

int fun()<br />

{<br />

. . .<br />

}<br />

fun()<br />

{<br />

. . .<br />

}<br />

Nawiasy po nazwie funkcji są konieczne, nawet gdy funkcja nie ma parametrów.<br />

Nawiasy występują zarówno przy definicji, deklaracji jak i przy wywołaniu funkcji.<br />

Jednak puste nawiasy wbrew pozorom nie oznaczają braku parametrów a ich<br />

nieokreśloną liczbę! Trzy następujące po sobie kropki ... oznaczają zmienną liczbę<br />

parametrów, jakie można przekazać funkcji.<br />

Zapisy równoważne<br />

int fun()<br />

{<br />

. . .<br />

}<br />

int fun( ... )<br />

{<br />

. . .<br />

}<br />

Dozwolone wywołania funkcji fun:<br />

fun(); fun( 5 ); fun( "Ala" ); fun( 2 * a ); fun( "Ala" , "As" );<br />

Copyright © Roman Simiński Strona : 13


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — uwagi<br />

Struktura <strong>programu</strong><br />

Funkcja printf jest przykładem funkcji o zmiennej liczbie parametrów:<br />

printf( "Witaj w programie" );<br />

printf( "Pole kola %g, jego obwod %g", pole_kola( r ), obwod_kola( r ) );<br />

printf( "Spalanie %4.2f l na 100 km", ( paliwo * 100 ) / dystans );<br />

W języku C każdy programista może pisać własne funkcje ze zmienną liczbą<br />

parametrów, wymaga to zastosowania odpowiednich makr – zostanie to omówione<br />

później.<br />

Słowo kluczowe void oznacza brak, nieobecność jakiejkolwiek wartości.<br />

void fun( void )<br />

{<br />

. . .<br />

}<br />

Zapis oznacza, że funkcja fun nie u<strong>do</strong>stępnia<br />

żadnej wartości, oraz nie otrzymuje żadnych<br />

parametrów.<br />

Copyright © Roman Simiński Strona : 14


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Struktura <strong>programu</strong> jednomodułowego — uwagi<br />

Struktura <strong>programu</strong><br />

W języku C wszystkie funkcje są zewnętrzne<br />

void oblicz_pole_kola( void )<br />

{<br />

float r;<br />

char s[ MAKS_DL ];<br />

}<br />

printf("\nPodaj promien R = " );<br />

gets( s );<br />

r = atof( s );<br />

printf( "Pole kola wynosi %g", pole_kola( r ) );<br />

float pole_kola( float r )<br />

{<br />

return PI * r * r;<br />

}<br />

Procedure ObliczPoleKola;<br />

Var<br />

R : Real;<br />

Function PoleKola : Real; { Funkcja nielokalna }<br />

Const<br />

Pi = 3.14;<br />

Begin<br />

PoleKola := Pi * R * R;<br />

End;<br />

Begin<br />

WriteLn;<br />

WriteLn( ”Podaj promie ń R: ” );<br />

ReadLn( R );<br />

WriteLn( ”Pole wynosi: ”, PoleKola );<br />

End;<br />

Copyright © Roman Simiński Strona : 15


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy auto — zmienne automatyczne<br />

void fun( float a )<br />

{<br />

int i = 0;<br />

char c = 'A';<br />

float f;<br />

}<br />

if( i == 0 )<br />

{<br />

float i = 100.0;<br />

int k;<br />

. . .<br />

}<br />

Przesłanianie identyfikatorów ― w obrębie<br />

tego bloku instrukcji if nazwa i oznacza,<br />

lokalną w tym bloki, zmienną typu float.<br />

Zmienne klasy auto mogą być definiowane na początku każdego bloku (standard C89<br />

języka C, w standardzie C99 i w języku C++ jest inaczej).<br />

Zmienne klasy auto pojawiają się i znikają wraz z wejściem i wyjściem sterowania <strong>do</strong><br />

bloku w którym są zadeklarowane.<br />

Zmienne deklarowane wewnątrz bloku są automatycznymi, jeżeli nie podano klasy<br />

pamięci albo jawnie użyto specyfikatora auto.<br />

Copyright © Roman Simiński Strona : 16


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy auto — zmienne automatyczne,cd...<br />

#include <br />

#include <br />

void fun( float a )<br />

{<br />

int i = 0;<br />

int j;<br />

printf( "\na = %.2f | i = %d | j = %d", a, i, j );<br />

}<br />

int main()<br />

{<br />

fun( 1.0 );<br />

fun( 2.0 );<br />

fun( 3.0 );<br />

}<br />

return EXIT_SUCCESS;<br />

Zmienne klasy auto:<br />

Nie zachowują swoich wartości pomiędzy swoimi kolejnymi kreacjami.<br />

O ile nie zostaną zainicjalizowane, maja wartości przypadkowe.<br />

Parametry formalne funkcji też są klasy auto.<br />

Copyright © Roman Simiński Strona : 17


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Gdzie w pamięci operacyjnej lokowane są zmienne automatyczne<br />

Zmienna klasy auto tworzone są automatycznie, lokowane są na stosie.<br />

Stos to element procesu, służący <strong>do</strong> przechowywania danych chwilowych.<br />

Na stosie lokowane są zmienne auto, w tym argumenty funkcji, oraz adresy powrotu<br />

dla wywoływanych podprogramów.<br />

Stos ma ustalony i ograniczony rozmiar ― należy sprawdzić ustalenia rozmiaru stosu<br />

w opcjach kompilatora (konsolidatora). Może się zdarzyć, że stos ma rozmiar rzędu<br />

kilku kilobajtów.<br />

Wobec powyższego, niebezpieczna może być poniższa definicja dużej tablicy:<br />

void fun( void )<br />

{<br />

float tab[ 10000 ];<br />

. . .<br />

}<br />

Uwaga: użycie słowa kluczowego auto dla deklaracji zmiennej, która jest <strong>do</strong>myślnie<br />

właśnie klasy auto, jest bezcelowe:<br />

{<br />

}<br />

auto int i;<br />

{<br />

}<br />

int i;<br />

Copyright © Roman Simiński Strona : 18


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy static — zmienne statyczne<br />

#include <br />

void fun_auto( void )<br />

{<br />

int i = 1;<br />

printf( "\nAuto %d", i++ );<br />

}<br />

void fun_static( void )<br />

{<br />

static int i = 1;<br />

printf( "\nStatic %d\n", i++ );<br />

}<br />

Operator ++ zwiększa o 1 wartość<br />

zmiennej przy której występuje.<br />

Zatem, zapis:<br />

i++<br />

równoważny jest:<br />

i = i + 1<br />

int main()<br />

{<br />

fun_auto();<br />

fun_static();<br />

fun_auto();<br />

fun_static();<br />

fun_auto();<br />

fun_static();<br />

. . .<br />

}<br />

Copyright © Roman Simiński Strona : 19


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy static — zmienne statyczne, cd...<br />

Zmienne statyczne mogą być lokalne w bloku lub zewnętrzne dla wszystkich bloków.<br />

Jeżeli zmienna wewnątrz bloku zostanie zadeklarowana ze specyfikatorem static, to:<br />

✔<br />

jest raz inicjowana wartością inicjalizatora lub nadawana jest jej wartość zerowa<br />

odpowiednio <strong>do</strong> typu.<br />

✔<br />

przechowuje wartość po opuszczeniu i ponownym wejściu <strong>do</strong> bloku.<br />

Statyczne zmienne lokalne stanowią prywatną, nieulotną pamięć danej funkcji czy<br />

bloku.<br />

Szkic przykła<strong>do</strong>wego zastosowania zmiennej statycznej ― funkcja z limitem wywołań<br />

void fun_z_limitem_wywolan( void )<br />

{<br />

static int licznik_wywolan = 0;<br />

}<br />

if( licznik_wywolan < 10 )<br />

{<br />

licznik_wywolan++;<br />

/* Tutaj odpowiednie instrukcje */<br />

}<br />

else<br />

puts( "Wersja demo -- limit wywolan wyczerpany" );<br />

Copyright © Roman Simiński Strona : 20


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy register — zmienne rejestrowe<br />

Deklaracja zmiennej jako register jest równoważna z deklaracją auto, ale<br />

wskazuje że deklarowany obiekt będzie intensywnie wykorzystywany, i w miarę<br />

możliwości będzie umieszczony w rejestrze procesora.<br />

Jeżeli nie jest możliwe umieszczenie zmiennej w rejestrze, pozostaje ona w pamięci.<br />

Zmienne rejestrowe pozwalają zredukować zajętość pamięci i poprawić szybkość<br />

wykonania operacji takie zmienne wykorzystujących.<br />

Jednak większość współczesnych kompilatorów wykorzystuje optymalizację<br />

rejestrową, zatem wiele zmiennych i tak przechowywanych jest w rejestrach, mimo<br />

braku jawnej specyfikacji jako register.<br />

register i;<br />

for( i = 0; i < 10; i++ )<br />

{<br />

. . .<br />

}<br />

int very_time_critical_fun( register int i, register char c )<br />

{<br />

. . .<br />

}<br />

Copyright © Roman Simiński Strona : 21


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy extern — zmienne zewnętrzne<br />

#include <br />

#include <br />

float dystans, paliwo;<br />

void komunikat_wstepny( void )<br />

{<br />

. . .<br />

}<br />

int main()<br />

{<br />

komunikat_wstepny();<br />

czytaj_dane();<br />

pisz_wyniki();<br />

return EXIT_SUCCESS;<br />

}<br />

void czytaj_dane( void )<br />

{<br />

. . .<br />

dystans = fabs( atof( linia ) );<br />

. . .<br />

paliwo = fabs( atof( linia ) );<br />

}<br />

void pisz_wyniki( void )<br />

{<br />

if( dystans == 0 )<br />

printf( "Nie policze spalania dla zerowego dystansu" );<br />

else<br />

printf( "Spalanie %4.2f l na 100 km", ( paliwo * 100 ) / dystans );<br />

}<br />

Copyright © Roman Simiński Strona : 22


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― klasy pamięci<br />

Struktura <strong>programu</strong><br />

Zmienne klasy extern — zmienne zewnętrzne, cd...<br />

Zmienne zewnętrzne deklarowane są na zewnątrz wszystkich funkcji. Zasięg<br />

zmiennej zewnętrznej rozciąga się od miejsca deklaracji <strong>do</strong> końca tego pliku.<br />

Zmienne zewnętrzne istnieją stale, nie pojawiają się i nie znikają, zachowują swoje<br />

wartości i są <strong>do</strong>stępne dla wszystkich funkcji programy występujących w zakresie<br />

danej zmiennej.<br />

Zmienna zewnętrzna jest raz inicjowana wartością inicjalizatora lub nadawana jest<br />

jej wartość zerowa odpowiednio <strong>do</strong> typu.<br />

Jeżeli dla zmiennej zewnętrznej użyjemy specyfikacji static, to oznacza to<br />

uprywatnienie (ograniczenie <strong>do</strong>stępu) w obrębie danego pliku źródłowego.<br />

Zmienne zewnętrzne oraz ich właściwe definiowanie i deklarowanie mają istotne<br />

znaczenie przy organizacji programów wielomodułowych.<br />

Delikatne kwestie ― definicja a deklaracja<br />

extern int i; int i;<br />

Deklaracja zmiennej jako extern nie<br />

powoduje przydziału pamięci i może<br />

występować w programie wiele razy.<br />

Definicja zmiennej, powodująca<br />

przydzielenie pamięci.<br />

Copyright © Roman Simiński Strona : 23


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― przekazywanie parametrów<br />

Struktura <strong>programu</strong><br />

W języku C parametry przekazywane są przez wartość<br />

Każda funkcja może posiadać parametry — na etapie definicji funkcji określa się ich<br />

liczbę, typy i nazwy.<br />

Parametry te nazywane są parametrami formalnymi funkcji.<br />

float pole_trojkata( float a, float h ) /* Definicja funkcji */<br />

{<br />

return 0.5 * a * h;<br />

}<br />

a i h to nazwy parametrów formalnych funkcji<br />

Każdą funkcje można wywołać. Na etapie wywołania funkcji określa się konkretne<br />

wartości jakie maja przyjąć parametry formalne.<br />

Wartości, z którymi jest wywoływana funkcja nazywane są parametrami aktualnymi<br />

wywołania funkcji.<br />

float podstawa = 10, wysokosc = 5, pole;<br />

pole = pole_trojkata( podstawa, wysokosc );<br />

pole = pole_trojkata( 20, 10 );<br />

podstawa i wysokosc oraz 20<br />

i 10 to parametry aktualne<br />

Copyright © Roman Simiński Strona : 24


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Deklaracje i definicje zmiennych ― przekazywanie parametrów<br />

Struktura <strong>programu</strong><br />

W języku C parametry przekazywane są przez wartość<br />

W języku C obowiązuje zasada przekazywania parametrów przez wartość.<br />

Zakład ona, iż na etapie wywołania funkcji wartość parametru aktualnego<br />

kopiowana jest <strong>do</strong> odpowiedniego parametru formalnego.<br />

Parametr formalny i aktualny są od siebie niezależne i, po przekazaniu wartości, nie<br />

występuje pomiędzy nimi żadne powiązanie.<br />

W języku C nie występuje jawnie przekazywanie parametrów przez zmienną.<br />

Copyright © Roman Simiński Strona : 25


Podstawy i języki <strong>programowania</strong><br />

Język C<br />

Ilustracja przekazywania parametrów przez wartość<br />

Struktura <strong>programu</strong><br />

a -- to parametr formalny funkcji inc<br />

i -- to parametr aktualny wywołania funkcji inc<br />

Wywołanie funkcji inc<br />

i 5<br />

a<br />

Stan pamięci<br />

operacyjnej<br />

5<br />

Kopiowanie wartości parametru<br />

aktualnego i <strong>do</strong> parametru formalnego a<br />

Wykonanie funkcji inc<br />

Stan pamięci<br />

operacyjnej<br />

i 5<br />

a<br />

6<br />

5<br />

a++<br />

Inkrementacja parametru<br />

formalnego a<br />

Po wykonaniu funkcji inc<br />

Stan pamięci<br />

operacyjnej<br />

i 5<br />

a<br />

6<br />

Parametr a będący klasy<br />

auto jest usuwany<br />

Copyright © Roman Simiński Strona : 26

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!