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
- No tags were found...
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<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