background image

 

Programowanie strukturalne – j

ę

zyk C 

 
 
  
 
Struktura programu 
 
 
Przykład programu: 
 
# include <stdio.h> 
 
main() 
 

 
printf(”Program w j

ę

zyku C \n”); 

 
return 0; 
 

 
Komentarze  
 
W j

ę

zykach programowania wyst

ę

puj

ą

 specjalne znaczniki 

powoduj

ą

ce i

ż

 umieszczony tekst nie jest cz

ęś

ci

ą

 programu, a 

jedynie dodatkow

ą

 informacj

ą

 o tre

ś

ci i zadaniach programu. 

 
/* - znak otwarcia komentarza 
 
*/ - znak zamkni

ę

cia komentarza 

 
/* komentarz */ 
 
/*  
 
komentarz 
 
*/ 
 
// komentarz 
 
  
 
Dyrektywa #include 
 
# include - dyrektywa preprocesora - polecenia dla 
preprocesora aby w tym miejscu doł

ą

czy

ć

 do programu zawarto

ść

 

wskazanego pliku  
 

background image

 

preprocesor – specjalny program wykonuj

ą

cy czynno

ś

ci 

przygotowawcze do kompilacji (przed kompilacj

ą

 
  
 
  
 
Pliki nagłówkowe 
 
Po dyrektywie #include wyst

ę

puj

ą

 pliki nagłówkowe, s

ą

 to pliki 

dodawane do programów za pomoc

ą

 tej dyrektywy, nazwa ich 

wywodzi si

ę

 st

ą

d , 

ż

e s

ą

 zawsze doł

ą

czane na pocz

ą

tku programu 

(w jego nagłówku) 
 
stdio.h - plik nagłówkowy standardowego wej

ś

cia – wyj

ś

cia 

 
stdlib.h – standardowa biblioteka funkcji 
 
string.h – operacje na ła

ń

cuchach tekstowych 

 
math.h – funkcje matematyczne 
 
conio.h – funkcje obsługi konsoli 
 
  
 
<stdio.h> i ”stdio.h” 
 
< ... > - plik nagłówkowy b

ę

dzie poszukiwany w katalogu innym 

ni

ż

 bie

żą

cy; wskazanym w opcjach kompilatora – jest to 

najcz

ęś

ciej katalog /..../INCLUDE 

 
” ... ” - plik nagłówkowy b

ę

dzie poszukiwany w katalogu 

bie

żą

cym 

 
  
 
Funkcja main() 
 
Funkcja specjalna w j

ę

zyku C, w ka

ż

dym programie musi ona 

wyst

ą

pi

ć

 i jest tylko jedna. 

 
Mo

ż

na j

ą

 wstawi

ć

 w dowolne miejsce w programie , jednak 

program zacznie zawsze wykonywa

ć

 si

ę

 od funkcji main() i 

zako

ń

czy swoje działanie w tej funkcji. Je

ż

eli wszystkie 

instrukcje zawarte w funkcji main() zostały wykonane i 
zako

ń

czone program ko

ń

czy swoje działanie. 

 
W zamieszczonym powy

ż

ej przykładzie funkcja main() zawiera 

funkcje biblioteczn

ą

 printf() , której argumentami jest tekst 

background image

 

wyprowadzany na urz

ą

dzenie wej

ś

ciowe , oraz specjalny znak 

steruj

ą

cy : 

 
\n - znak steruj

ą

cy przej

ś

cia do nast

ę

pnego wiersza. 

 
zasad

ą

 tego j

ę

zyka programowania jest to, 

ż

e ka

ż

da funkcja w 

tym main() zwraca wynik; domy

ś

lnie wynikiem jest liczba typu 

całkowitego (integer) 
 
wykorzystywana jest do tego celu instrukcja : 
 
return 0; 
 
Zwrócenie przez funkcj

ę

 warto

ś

ci 0 - oznacza i

ż

 zako

ń

czyła si

ę

 

ona poprawnie, ka

ż

da inna warto

ść

 całkowita wi

ę

ksza od zera 

oznacza zako

ń

czenie działania funkcji z bł

ę

dem. 

 
funkcja biblioteczna (stdlib.h) exit() - mo

ż

e by

ć

 równie

ż

 

u

ż

yta do zako

ń

czenia działania programu. 

 
Funkcja exit() nie zwraca 

ż

adnego wyniku, ale argument 

przekazany do funkcji wskazuje czy program zako

ń

czył si

ę

 

normalnie czy z bł

ę

dem. 

 
exit(0) – zako

ń

czenie poprawne 

 
exit(n) – zako

ń

czenie z bł

ę

dem n<>0 

 
  
 
#include <stdio.h> 
 
#include <stdlib.h> 
 
void main() 
 

 
printf(”Program w j

ę

zyku C\n”); 

 
exit(0); 
 

 
  
 
typ danych: void 
 
void - pusty, nijaki 
 

background image

 

słowo to pojawiaj

ą

ce si

ę

 przed nazw

ą

 funkcji oznacza, 

ż

e nie 

b

ę

dzie ona zwraca

ć

 

ż

adnej warto

ś

ci 

 
main() à zwraca domy

ś

lnie warto

ść

 typu integer 

 
void main() à funkcja main() nie zwraca 

ż

adnej warto

ś

ci 

 
  
linia instrukcji w j

ę

zyku C zako

ń

czona jest 

ś

rednikiem 

j

ę

zyk ten rozró

ż

nia małe i du

ż

e litery 

 
Podstawowe elementy programu 
 
 
Stałe i zmienne 
 
stała – nigdy nie zmienia swojej warto

ś

ci 

 
zmienna – mo

ż

e by

ć

 u

ż

ywana do reprezentowania ró

ż

nych warto

ś

ci 

 
Stałe i zmienne mog

ą

 wystepowa

ć

 razem w wyra

ż

eniach. 

 
i = 1; 
- jest stał

ą

 
i = 10; 
- jest stał

ą

 
i - mo

ż

e przyjmowa

ć

 ró

ż

ne warto

ś

ci (1,10, lub inne) zatem jest 

zmienn

ą

 
  
 
Wyra

ż

enie 

 
Wyra

ż

enie to kombinacja stałych, zmiennych i operatorów 

 
( 3 + 6 ) * 20 
 
4/2 
 
20 * ( 2 + 1 ) 
 
  
 
Operatory arytmetyczne 
 
+ - dodawanie 
- odejmowanie 
 
* - mno

ż

enie 

background image

 

 
/ - dzielenie 
 
% - reszta z dzielenia (dzielenie modulo) 
 
8 % 5 à 3 
 
* / % - operatory o wy

ż

szym priorytecie 

 
+ - - operatory o ni

ż

szym priorytecie 

 
Priorytet okre

ś

la kolejno

ść

 wykonywanych działa

ń

, chyba, 

ż

wystepuj

ą

 nawiasy, wtedy w pierwszej kolejno

ś

ci wykonywane s

ą

 

wyra

ż

enia w nawiasach. 

 
  
 
Instrukcje 
 
W j

ę

zyku C instrukcja to polecenie zako

ń

czone 

ś

rednikiem. 

 
i = 5; 
 
j = (12+4 ) * 2; 
 
k = i + j; 
 
return 0; 
 
exit(0); 
 
printf(”To jest program w C”); 
 
  
 
Bloki instrukcji 
 
Grupa instrukcji tworzy blok instrukcji, który jest traktowany 
przez kompilator jako pojedyncza instrukcja. 
 

 
i = 5; 
 
j = 8; 
 
k = i + j; 
 

 

background image

 

Blok instrukcji to sposób poł

ą

czenia kilku instrukcji 

prostych, tak aby zawsze były wykonywane razem – tak jak jedna 
instrrukcja. 
 
  
 
Struktura funkcji 
 
Funkcje w j

ę

zyku c mog

ą

 by

ć

 albo funkcjami bibliotecznymi, 

albo stworzonymi przez programist

ę

, albo przez innych 

programistów. 
 
Funkcja składa si

ę

 z: 

typu funkcji 
nazwy funkcji 
argumentów funkcji 
nawiasu otwieraj

ą

cego 

ciała funkcji 
nawiasu zamykaj

ą

cego 

 
int nazwa_funkcji(int x, int y) 
 

 
int rezult; 
 
rezult = x + y; 
 
return rezult; 
 

 
  
 
typ funkcji : 
 
to rodzaj warto

ś

ci wyniku, który funkcja zamierza zwróci

ć

 po 

jej wykonaniu. 
 
  
 
nazwa funkcji : 
 
nazwa funkcji musi by

ć

 zwi

ą

zana z zadaniem wykonywanym przez 

funkcje 
nazwa funkcji nie mo

ż

e rozpoczyna

ć

 si

ę

 do cyfry 

nazwa funkcji nie mo

ż

e rozpoczyna

ć

 si

ę

 od znaku * 

nazwa funkcji nie mo

ż

e rozpoczyna

ć

 si

ę

 od znaku operatora 

arytmetycznego 
nazwa funkcji nie mo

ż

e rozpoczyna

ć

 si

ę

 od znaku . 

nazwa funkcji nie mo

ż

e zawiera

ć

 (wewn

ą

trz) znaku - 

background image

 

nazwa funkcji nie mo

ż

e zawiera

ć

 (wewn

ą

trz) znaku ‘ 

 
argumenty przekazywane do funkcji 
dla prawidłowego wykonania pewne funkcje potrzebuj

ą

 

przekazania im pewnych informacji , przekazywanych w postaci 
tzw. argumentów 
argumenty umieszczane s

ą

 w nawiasach okr

ą

głych tu

ż

 po nazwie 

funkcji 
je

ż

eli do prawidłowego działania funkcji niezb

ę

dne jest 

podanie wi

ę

cej ni

ż

 jednego argumentu, wtedy tworzymy tzw. 

list

ę

 argumentów, w które argumenty oddzielone s

ą

 od siebie 

przecinkami 
je

ż

eli funkcja nie wymaga 

ż

adnych argumentów to lista 

argumentów jest pusta 
 
pocz

ą

tek i koniec funkcji : 

 
{ } znaki słu

żą

ce do zaznaczenia pocz

ą

tku i ko

ń

ca funkcji; 

 
pomi

ę

dzy nimi zawarte jest ciało funkcji; 

 
  
 
ciało funkcji : 
 
zawiera : 
deklaracje zmiennych 
instrukcje j

ę

zyka C 

 
wykonanie funkcji à wykonanie instrukcji stanowi

ą

cych jej 

ciało 
 
wywołanie funkcji polega na podaniu jej nazwy i okre

ś

leniu 

argumentów wywołania; 
 
// p_0 
 
# include <stdio.h>int dodaj(int x, int y) 
 

 
int wynik; 
 
wynik=x+y; 
 
return wynik; 
 

 
int main()  
 

background image

 


 
int suma; 
 
suma=dodaj(2,3); 
 
printf("Wynik dodawania 2 + 3 = %d\n",suma); 
 
return 0; 
 

 
// p_01 
 
# include <stdio.h># include <conio.h> 
 
int dodaj(int x, int y) 
 

 
int wynik; 
 
wynik=x+y; 
 
return wynik; 
 

 
int main()  
 

 
int suma; 
 
suma=dodaj(2,3); 
 
clrscr(); 
 
printf("Wynik dodawania 2 + 3 = %d\n",suma); 
 
return 0; 
 

 
// p_02 
 
# include <stdio.h> 
 
# include <conio.h> 
 
int dodaj(int ax,int ay); 

background image

 

 
int main() 
 

 
int suma; 
 
suma=dodaj(2,3); 
 
clrscr(); 
 
printf("Wynik dodawania 2 + 3 = %d\n",suma); 
 
return 0; 
 

 
int dodaj(int x, int y) 
 

 
int wynik; 
 
wynik=x+y; 
 
return wynik; 
 

 
  
 
  
 
  
 
Słowa kluczowe j

ę

zyka C 

 
 
auto break case char const continue  
 
default do double else enum extern  
 
float for goto if int long 
 
register return short signed sizeof static  
 
struct switch typedef union unsigned void  
 
volatile while 
 
słowa kluczowe j

ę

zyka C pisane s

ą

 małymi literami  

background image

 

10 

 
  
 
  
 
Typy danych 
 
Typ danych - char 
 
  
 
obiekty typu charakter to znaki : a, b, z, A,B,7,,0,2,W,w 
ka

ż

dy z tych znaków przechowywany jest w pami

ę

ci w postaci 

numerycznego kodu liczbowego 
tablica kodów ASCII 27 =128 
rozszerzona tablica kodów ASCII 28 =256 
obiekt typu char zajmuje 1 bajt (8 bitów) 
 
  
 
zmienne znakowe - mog

ą

 reprezentowa

ć

 ró

ż

ne znaki 

 
deklaracja zmiennej znakowe jest sposobem przyporz

ą

dkowania 

tej zmiennej okre

ś

lonego miejsca w pami

ę

ci o rozmiarze 

odpowiadaj

ą

cym typowi tej zmiennej 

 
char lista nazw zmiennych /oddzielone przecinkami/; 
 
char c1,c2,c_znak; 
 
Stałe znakowe 
 
znak uj

ę

ty w apostrofy (‘) jest nazywany stał

ą

 znakow

ą

 

 
‘a’ , ‘A’ , ‘b’ 
stałe znakowe (pojedyncze znaki ASCII) s

ą

 ujmowane w apostrofy 

(‘) ; 
ła

ń

cuchy znakowe (teksty) s

ą

 ujmowane w znaki (”); 

poszczególnym znakom przyporz

ą

dkowane s

ą

 ich kody ASCII; 

 
‘A’ à 65 
 
‘a’ à 97 
 
‘B’ à 66 
 
‘b’ à 98 
 
dlatego dla zmiennej x 
 
char x; 

background image

 

11 

 
x=’A’; i x=65 to równowa

ż

ne zapisy 

 
  
 
znak specjalny : \ 
 
tworzy wraz z innymi znakami znaki steruj

ą

ce: 

 
np.: 
 
\n - przej

ś

cie do nast

ę

pnej linii 

 
\b - cofni

ę

cie kursora o jeden znak w lewo 

 
\f - przej

ś

cie do nast

ę

pnej strony 

 
\r - powrót na pocz

ą

tek bie

żą

cego wiersza 

 
\t - tabulacja 
 
  
 
drukowanie znaków : 
 
do wyprowadzania znaków na ekran mo

ż

na stosowa

ć

 funkcj

ę

 

printf(); 
 
W funkcji tej do wyprowadzenia pojedynczego znaku słu

ż

y format 

: %c 
 
  
 
# include <stdio.h># include <conio.h>void main(void){char 
c1,c2; c1='a'; clrscr(); printf("Oto c1 %c \n",c1); c2='A'; 
c1='B'; printf("Oto c1 %c \n",c1); 
 
printf("Oto c2 %c \n",c2); 
 
getch(); 
 

 
  
 
# include <stdio.h># include <conio.h>int main(){char c1,c2; 
c1=97; c2=65; clrscr(); printf("Oto c1 %c \n",c1); printf("Oto 
c2 %c \n",c2);} 
 

background image

 

12 

Specyfikator formatu %c, u

ż

yty w funkcji printf(), okre

ś

la 

sposób wy

ś

wietlenia zmiennej - w tym przypadku jest to sposób 

wy

ś

wietlenia w postaci znaku; 

 
  
 
  
 
  
 
  
 
Typ danych int /integer/ 
typ danych int wykorzystywany jest dla danych numerycznych – 
całkowitych;  
liczby całkowite nie zawieraj

ą

 ani cz

ęś

ci ułamkowej, ani 

przecinka dziesi

ę

tnego;  

wynik dzielenie liczb całkowitych ulega obci

ę

ciu o cz

ęść

 

ułamkow

ą

w najprostszym przypadku obiekty typu int zajmuj

ą

 2 bajty / w 

innych systemach mo

ż

e to by

ć

 4 bajty/ 

zakres warto

ś

ci 16 bitowych liczb całkowitych (2bajty) 

 
32 767 (215 – 1) do -32 768 dla liczb ze znakiem  
 
lub 
do 216 dla liczb bez znaku 
 
deklarowanie zmiennych dla obiektów typu int 
 
int lista zmiennych; 
 
int x, zm_1,i; 
 
drukowanie numerycznych kodów znaków 
 
%d - jest specyfikatorem formatu, który zawarto

ść

 komórek 

pami

ę

ci interpretuje jako warto

ść

 typu integer 

 
// p_1 
 
# include <stdio.h># include <conio.h>void main(void){char 
c1,c2; c1='a'; clrscr(); printf("Oto c1 %c %d \n",c1,c1); 
c2='A'; c1='B'; printf("Oto c1 %c %d \n",c1,c1); 
 
printf("Oto c2 %c %d \n",c2,c2); 
 
getch(); 
 

 

background image

 

13 

//p_2 
 
# include <stdio.h># include <conio.h>int main(){char c1,c2; 
c1=97; c2=65; clrscr(); printf("Oto c1 %c %d \n",c1,c1); 
printf("Oto c2 %c %d \n",c2,c2); 
 

 
  
 
zmienne znakowe mog

ą

 by

ć

 wyprowadzane na ekran albo w postaci 

znaków, albo w postaci ich kodów numerycznych ; zale

ż

y to od 

specyfikatora formatu. 
 
  
 
  
 
typ danych - float 
 
zmienne przecinkowe (z pływaj

ą

cym przecinkiem) – float 

 
- stałe 6,56f lub 6,56F oznaczaj

ą

 stałe typu float 

 
6,56 domy

ś

lnie jest traktowane jako typ double 

typ float zajmuje 4 bajty pami

ę

ci 

co najmniej 6 miejsc znacz

ą

cych po przecinku 

deklaracja: 
 
float lista zmiennych; 
 
float y, zm_1, x; 
 
%f jest zmiennoprzecinkowym specyfikatorem formatu 
 
//p_3 
 
# include <stdio.h># include <conio.h>int main(){int i1,i2,d; 
i1=3; i2=2; d=i1/i2; clrscr(); printf("Oto wynik 3/2 = %d 
\n",d); getch();} 
 
  
 
//p_4 
 
# include <stdio.h># include <conio.h>void main(void){int 
int_1,int_2,int_3,int_4; 
 
float flt_1,flt_2,flt_3,flt_4; 
 
clrscr(); 

background image

 

14 

 
int_1=32/10; 
 
flt_1=32/10; 
 
int_2=32.0/10; 
 
flt_2=32.0/10; 
 
int_3=32/10.0; 
 
flt_3=32/10.0; 
 
int_4=32.0/10.0; 
 
flt_4=32.0/10.0; 
 
printf("Dzielenie całkowite 32/10 %d\n",int_1); 
 
printf("Dzielenie zmiennoprzecinkowe 32/10 %f\n",flt_1); 
 
printf("Dzielenie całkowite 32.0/10 %d\n",int_2); 
 
printf("Dzielenie zmiennoprzecinowe 32.0/10 %f\n",flt_2); 
 
printf("Dzielenie całkowite 32/10.0 %d\n",int_3); 
 
printf("Dzielenie zmiennoprzecinkowe 32/10.0 %f\n",flt_3); 
 
printf("Dzielenie całkowite 32.0/10.0 %d\n",int_4); 
 
printf("Dzielenie zmiennoprzecinkowe 32.0/10.0 %f\n",flt_4); 
 
getch(); 
 

 
  
 
typ danych - double 
w przeciwie

ń

stwie do typu float, typ zmiennopozycyjny double 

zajmuje dwa razy wi

ę

cej miejsca w pami

ę

ci (8 bajtów) 

co najmniej 10 miejsc znacz

ą

cych po przecinku 

 
zapis wykładniczy liczb 
 
w formacie wykładniczym liczba przedstawiona jest w postaci 
mantysy i wykładnika; cecha i mantysa rozdzielone s

ą

 litera E 

(e) 
 
mantysa E (e) wykładnik 

background image

 

15 

= 5e3 
 
-300 = -3e2 
 
przy wyprowadzaniu liczb w takim formacie na ekran, funkcja 
printf() u

ż

ywa specyfikatora: 

 
%e lub %E 
 
Identyfikatory 
 
s

ą

 to nazwy zmiennych i funkcji j

ę

zyka C 

 
Znaki, które mo

ż

na stosowa

ć

 przy nadawaniu nazw zmiennych: 

litery du

ż

e A,...,Z i małe a,...,z; 

cyfry 0,...,9 /cyfra nie mo

ż

e by

ć

 pierwszym znakiem nazwy/; 

znak podkre

ś

lenia (_); 

 
Znaki zabronione przy nadawaniu nazw zmiennych: 
nazwa zmiennej nie mo

ż

e zawiera

ć

 znaku jakiejkolwiek operacji 

arytmetycznej; 
nazwa zmiennej nie mo

ż

e zawiera

ć

 kropki (.); 

nazwa zmiennej nie mo

ż

e zawiera

ć

 apostrofu (‘); 

nazwa zmiennej nie mo

ż

e zawiera

ć

 

ż

adnego spo

ś

ród pozostałych 

symboli specjalnych : *,@,#,?, itp. 
nie mo

ż

na stosowa

ć

 słów kluczowych j

ę

zyka C, nazw funkcji 

bibliotecznych jako nazw zmiennych w programach pisanych w  
 
j

ę

zyku C; 

 
  
 
  
 
Obsługa standardowego wej

ś

cia/wyj

ś

cia 

 
 
Miejscem przechowywania informacji s

ą

 pliki. Poniewa

ż

 

informacje s

ą

 reprezentowane jako ci

ą

gi bitów pogrupowane po 8 

w bajty, j

ę

zyk C traktuje plik jako ci

ą

g bajtów.  

 
Ci

ą

g bajtów mo

ż

e by

ć

 nazwany plikiem b

ą

d

ź

 strumieniem. W 

j

ę

zyku C wszystkie strumienie danych i wszystkie pliki 

traktowane s

ą

 tak samo. 

 
W j

ę

zyku C mamy do czynienia z 3 strumieniami plikowymi: 

stdin - standardowe wej

ś

cie do odczytu 

stdout - standardowe wyj

ś

cie do zapisu 

stderr - standardowe wyj

ś

cie diagnostyczne dla komunikatów o 

ę

dach 

 

background image

 

16 

zazwyczaj stdin à klawiatura 
 
stdout , stderr à ekran monitora  
 
 
Wprowadzanie danych 
 
Funkcja getc() - wczytuje pojedynczy znak ze strumienia 
(pliku) wej

ś

ciowego , zwracaj

ą

c kod wczytanego znaku w postaci 

liczby całkowitej (int). 
 
int getc(FILE *stream); 
 
int getc(stdin); 
 
//P_5 
 
# include <stdio.h># include <conio.h>void main(void){ int c; 
clrscr(); printf("Naci

ś

nij klawisz : \n"); c=getc(stdin); 

printf("Nacisn

ą

łe

ś

 klawisz < %c > ,którego kod ASCII wynosi %d 

\n",c,c); getch();} 
 
  
 
  
 
Funkcja getchar() - jest równowa

ż

na funkcji getc(stdin); 

 
int getchar(void); 
 
//p_6 
 
# include <stdio.h># include <conio.h>void main(void){ int c; 
clrscr(); printf("Naci

ś

nij klawisz : \n"); c=getchar(); 

printf("Nacisn

ą

łe

ś

 klawisz < %c > ,którego kod ASCII wynosi %d 

\n",c,c); 
 
getch(); 
 

 
Wyprowadzanie danych 
 
Funkcja putc() - wysyła znak do wskazanego jej jako argument 
strumienia /pliku. 
 
int putc(int c, FILE *stream); 
 
int c - pierwszy argument funkcji to nazwa zmiennej 
numerycznej przechowuj

ą

cej kod znaku do przesłania; 

 

background image

 

17 

drugi argumnet to wska

ź

nik do pliku wyj

ś

ciowego 

 
je

ż

eli operacja si

ę

 powiodła funkcja zwraca numer kodu 

przesłanego znaku; w przeciwnym przypadku (bł

ą

d) funkcja 

zwraca EOF (-1) 
 
  
 
  
 
  
 
  
 
  
 
  
 
//P_7 
 
  
 
# include <stdio.h># include <conio.h>void main(void) 
 

 
int c; 
 
clrscr(); 
 
c=70; 
 
printf("Znak o kodzie ASCII 70 to \n"); 
 
putc(c,stdout); 
 
getch(); 
 

 
Funkcja putchar() - funkcja ta w przeciwie

ń

stwie do putc() 

potrzebuje tylko jednego argumentu tj. znaku przeznaczonego do 
wyprowadzenia; 
 
drugiego argumentu nie trzeba wprowadza

ć

 poniewa

ż

 jest on 

domy

ś

lny tj. stdout 

 
// p_8 
 

background image

 

18 

# include <stdio.h># include <conio.h>void main(void){ int c; 
clrscr(); c=70; printf("Znak o kodzie ASCII 70 to \n"); 
putchar(c); getch();} 
 
  
 
//p_9 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
clrscr(); 
 
putchar(65); 
 
putchar(10); 
 
putchar(66); 
 
putchar(10); 
 
putchar(67); 
 
putchar(10); 
 
getch(); 
 

 
Funkcja printf() 
 
int printf(const char *format_string, ...); 
 
const – stała 
 
char - typ znakowy 
 
* - wska

ź

nik (wskazanie) 

 
format_string - ła

ń

cuch formatuj

ą

cy 

 
... - nastepne elementy 
pierwszy element format_string to ła

ń

cuch znaków zawieraj

ą

cy 

równie

ż

 specyfikatory formatu (%c, %d, %f, itp.) 

background image

 

19 

cz

ęść

 druga to ewentualna lista wyra

ż

e

ń

, które powinny by

ć

 

sformatowane w cz

ęś

ci pierwszej zgodnie ze specyfikatorami 

formatu; 
 
ilo

ść

 tych wyra

ż

e

ń

 musi by

ć

 równa ilo

ś

ci specyfikatorów 

formatu w cz

ęś

ci pierwszej 

 
funkcja printf() zwraca (int) ilo

ść

 poprawnie sformatowanych 

wyra

ż

e

ń

, w przeciwnym przypadku zwraca warto

ść

 ujemn

ą

 

 
Specyfikatory formatu, które mo

ż

na stosowa

ć

 w wywołaniu 

funkcji printf() 
%c - znak (typ char) 
%d - liczba (typ int) 
%i - liczba (typ int) to samo co %d 
%f - liczba zmiennoprzecinkowa (typ float) 
%e - format wykładniczy z u

ż

yciem małej litery e 

%E - format wykładniczy z u

ż

yciem du

ż

ej litery E 

%g - zastosuj %f lub %e – wybierz format, w którym wynik 
b

ę

dzie krótszy 

%G - zastosuj % f lub %E – wybierz format, w którym wynik 
b

ę

dzie krótszy 

%o - liczba ósemkowa bez znaku 
%s - ła

ń

cuch znaków (string) 

%u - liczba całkowita (typu unsigned) jak int, ale bez znaku 
%x - liczba szesnastkowa bez znaku (z zastosowanie przyrostka 
x, małe litery) 
%X - liczba szesnastkowa bez znaku (z zastosowaniem przyrostka 
X, du

ż

e litery) 

%p - argument odpowiadaj

ą

cy wska

ź

nikowi (pointer) 

%n - rejestruj ilo

ść

 znaków wyprowadzon

ą

 do tego momentu 

%% - wyprowad

ź

 znak ‘%’ 

 
Zamiana liczb dziesi

ę

tnych na szesnastkowe - wykorzystanie 

formatu %x i %X 
 
//p_10 
 
# include <stdio.h># include <conio.h>void 
main(void){clrscr(); printf("Liczba 16 X Liczba 16 x Liczba 
10\n"); 
 
printf("%X %x %d\n",0,0,0); 
 
printf("%X %x %d\n",1,1,1); 
 
printf("%X %x %d\n",2,2,2); 
 
printf("%X %x %d\n",3,3,3); 
 
printf("%X %x %d\n",4,4,4); 

background image

 

20 

 
printf("%X %x %d\n",5,5,5); 
 
printf("%X %x %d\n",6,6,6); 
 
printf("%X %x %d\n",7,7,7); 
 
printf("%X %x %d\n",8,8,8); 
 
printf("%X %x %d\n",9,9,9); 
 
printf("%X %x %d\n",10,10,10); 
 
printf("%X %x %d\n",11,11,11); 
 
printf("%X %x %d\n",12,12,12); 
 
printf("%X %x %d\n",13,13,13); 
 
printf("%X %x %d\n",14,14,14); 
 
printf("%X %x %d\n",15,15,15); 
 
printf("%X %x %d\n",16,16,16); 
 
printf("%X %x %d\n",17,17,17); 
 
printf("%X %x %d\n",18,18,18); 
 
printf("%X %x %d\n",19,19,19); 
 
printf("%X %x %d\n",20,20,20); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
Minimalna szeroko

ść

 pola 

 
J

ę

zyk C umo

ż

liwia na wstawienie do specyfikatora formatu 

pomi

ę

dzy znak % a liter

ę

 specyfikatora liczby nazywanej 

specyfikatorem minimalnej szeroko

ś

ci pola 

 

background image

 

21 

np. %10f - wyprowadzenie w formacie zmiennoprzecinkowym z 
u

ż

yciem minimum 10 znaków (cyfr) 

 
  
 
//p_11 
 
# include <stdio.h># include <conio.h>void main(void){int 
n1,n2;clrscr(); n1=12; n2=12345; printf("%d\n",n1); 
printf("%d\n",n2); printf("%5d\n",n1); printf("%05d\n",n1); 
printf("%2d\n",n2); getch();} 
 
  
 
  
 
%5d - ustalenie na 5 minimalnej szeroko

ś

ci pola wyj

ś

ciowego 

 
%05d - jak wy

ż

ej z tym 

ż

e puste miejsca zostana wypełnione 

zerami 
 
%2d - gdy specyfikator formatu jest za mały w stosunku do 
długo

ś

ci liczby to liczba jest wyprowadzana w cało

ś

ci 

 
  
 
Wyrównanie pola wyj

ś

ciowego 

 
Znaki wyj

ś

ciowe s

ą

 wyrównywane do prawej strony. 

 
Aby to zmieni

ć

, i doprowadzi

ć

 do wyrównywania do lewej nale

ż

 
poprzedzi

ć

 specyfikator minimalnej szeroko

ś

ci pola znakiem 

minus (-); 
 
  
 
//p_12 
 
  
 
# include <stdio.h># include <conio.h> 
 
void main(void) 
 

 
int n1,n2; 
 
clrscr(); 
 

background image

 

22 

n1=12; 
 
n2=12345; 
 
printf("%-d\n",n1); 
 
printf("%-d\n",n2); 
 
printf("%-5d\n",n1); 
 
printf("%-05d\n",n1); 
 
printf("%-2d\n",n2); 
 
getch(); 
 

 
  
 
//p_13 
 
# include <stdio.h># include <conio.h>void main(void) 
 

 
int n1,n2,n3,n4,n5; 
 
clrscr(); 
 
n1=1; 
 
n2=12; 
 
n3=123; 
 
n4=1234; 
 
n5=12345; 
 
printf("%10d %-10d\n",n1,n1); 
 
printf("%10d %-10d\n",n2,n2); 
 
printf("%10d %-10d\n",n3,n3); 
 
printf("%10d %-10d\n",n4,n4); 
 
printf("%10d %-10d\n",n5,n5); 
 
getch(); 

background image

 

23 

 

 
  
 
Specyfikator precyzji 
 
Po specyfikatorze minimalnej szeroko

ś

ci pola mo

ż

na doda

ć

 

kropk

ę

 (.) i liczb

ę

 całkowit

ą

. Poł

ą

czenie .liczba tworzy 

specyfikator precyzji. 
 
Pozwala on okre

ś

li

ć

 : 

ilo

ść

 cyfr dziesi

ę

tnych po przecinku dla liczb 

zmiennoprzecinkowych; 
albo maksymalna szeroko

ść

 pola wyj

ś

ciowego /przypadek ten 

odnosi si

ę

 do liczb całkowitych i do ła

ń

cuchów tekstowych/ 

 
  
 
np.: 
 
%10.3f 
minimalna szeroko

ść

 pola wyj

ś

ciowego 10 znaków 

ilo

ść

 cyfr dziesi

ę

tnych po przecinku : 3 /domy

ś

lna ilo

ść

 cyfr 

po przecinku to 6/ 
 
%3.8d 
minimalna szeroko

ść

 pola wyj

ś

ciowego – 3 

maksymalna szeroko

ść

 pola wyj

ś

ciowego - 8 

 
  
 
//p_14 
 
# include <stdio.h># include <conio.h>void main(void){int 
n1;double d1;clrscr(); n1=123; d1=123.456789; printf("Format 
całkowity domy

ś

lny %d\n",n1); 

 
printf("j.w. ze spec. pracyzji %2.8d\n",n1); 
 
printf("Format zmiennoprzecinkowy domy

ś

lny %f\n",d1); 

 
printf("j.w. ze spec. praecyzji %10.2f\n",d1); 
 
getch(); 
 

 
//p_15 
 
# include <stdio.h># include <conio.h>void main(void){int n1; 

background image

 

24 

 
float d1; 
 
clrscr(); 
 
n1=123; 
 
d1=123.456789; 
 
printf("Format całkowity domy

ś

lny %d\n",n1); 

 
printf("j.w. ze spec. pracyzji %2.8d\n",n1); 
 
printf("Format zmiennoprzecinkowy domy

ś

lny %f\n",d1); 

 
printf("j.w. ze spec. precyzji %10.2f\n",d1); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
Operatory 
 
 
Operator przypisania 
 
= operator przypisania 
 
operand_lewostronny = operand_prawostronny 
 
warto

ść

 operandu prawostronnego zostaje przypisana operandowi 

lewostronnemu; przypisanie polega na umieszczeniu w obszarze 
pami

ę

ci zarezerwowanym dla operandu lewostronnego warto

ś

ci 

operandu prawostronnego; 
 
x = 10; 
 
y = a + 5; 
 

background image

 

25 

Operatory arytmetyczne i operator przypisania 
 
z = x + y; 
 
x = x + y; ß à x += y 
 
Poł

ą

czenie operatorów arytmetycznych z operatorem przypisania 

tworzy w j

ę

zyku C  

 
arytmetyczne operatory przypisania 
 
+= operator przypisania z dodawaniem 
 
-= operator przypisania z odejmowaniem 
 
*= operator przypisania z mni

ż

eniem 

 
/= operator przypisania z dzieleniem 
 
%= operator przypisania reszty z dzielenia 
 
  
 
x += y ß à x = x + y 
 
x -= y ß à x = x - y 
 
x *= y ß à x = x * y 
 
x /= y ß à x = x / y 
 
x %= y ß à x = x % y 
 
  
 
z = z * x + y i z *= x + y nie s

ą

 równowa

ż

ne ze wzgl

ę

du na 

kolejno

ść

  

 
operacji 
 
  
 
równowa

ż

ne s

ą

 : 

 
z *= x + y i z = z * ( x + y ) 
 
//p_16 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y,z;clrscr(); x=1; y=3; z=10; printf("x= %d y= %d z= 

background image

 

26 

%d\n",x,y,z); x=x+y; printf("\nx=x+y przypisuje zmiennej x 
warto

ść

 %d\n",x); 

 
x=1; 
 
x+=y; 
 
printf("\nx+=y przypisuje zmiennej x warto

ść

 %d\n",x); 

 
x=1; 
 
x=x-y; 
 
printf("\nx=x-y przypisuje zmiennej x warto

ść

 %d\n",x); 

 
x=1; 
 
x-=y; 
 
printf("\nx-=y przypisuje zmiennej x warto

ść

 %d\n",x); 

 
x=1; 
 
z=z*x+y; 
 
printf("\nz=z*x+y przypisuje zmiennej z warto

ść

 %d\n",z); 

 
z=10; 
 
z=z*(x+y); 
 
printf("\nz=z*(x+y) przypisuje zmiennej z warto

ść

 %d\n",z); 

 
z=10; 
 
z*=x+y; 
 
printf("\nz*=x+y przypisuje zmiennej z warto

ść

 %d\n",z); 

 
getch(); 
 

 
  
 
Jednoargumentowy operator zmiany znaku 
 
Operandem tego operatora mo

ż

e by

ć

 warto

ść

 numeryczna całkowita 

lub zmiennoprzecinkowa – stała b

ą

d

ź

 zmienna. 

 

background image

 

27 

Nie mo

ż

na myli

ć

 jednoargumentowego operatora (-) z 

dwuargumentowym operatorem (-) odejmowania. 
 
W wyra

ż

eniu: 

 
x - -y à pierwszy jest operatorem dwuargumentowym odejmowania, 
za

ś

 drugi minus operatorem jednoargumentowym zmiany znaku.  

 
tj. x – (-y) à x + y  
 
  
 
  
 
Zwi

ę

kszanie i zmniejszanie o 1. à Inkrementacja i 

dekrementacja. 
 
  
 
++ x ß à x = x+1 lub x += 1 
 
-- x ß à x = x-1 lub x -= 1 
 
Operatory inkrementacji i dekrementacji wystepuj

ą

 w j

ę

zyku C w 

dwóch wersjach ka

ż

dy : 

 
++ x - operator pre-inkrementacji 
 
x ++ - operator post-inkrementacji 
 
-- x - operator pre-dekrementacji 
 
x -- - operator post-dekrementacji 
 
W przepadku pre- najpierw nast

ę

puje dodanie lub odjecie 

jedynki a pó

ź

niej wykorzystanie zmiennej z now

ą

 warto

ś

ci

ą

 w 

programie; 
 
W przypadku post- najpierw nast

ę

puje wykorzystanie warto

ś

ci 

zmiennej w programie a dopiero pó

ź

niej jej zwi

ę

kszenie lub 

zmniejszenie o 1; 
 
  
 
y = x ++; 
 
1/ najpierw wykonane zostanie przypisanie y = x; 
 
2/ potem x = x + 1; 
 
praktycznie realizuje si

ę

 to w nast

ę

puj

ą

cy sposób: 

background image

 

28 

 
1/ program wykonuje kopie tymczasow

ą

 zmiennej x; 

 
2/ inkrementuje zmienn

ą

 x , a nie tymczasow

ą

 kopi

ę

 
3/ wykorzystuje tymczasowa kopie x do przypisania y = x; 
 
//p_17 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y,z,w,wynik;clrscr(); x=y=z=w=1; printf("x = %d y = %d z = 
%d w = %d\n",x,y,z,w); wynik=++x; printf("\n++x wynosi 
%d\n",wynik); wynik=y++; 
 
printf("\ny++ wynosi %d\n",wynik); 
 
wynik=--z; 
 
printf("\n--z wynosi %d\n",wynik); 
 
wynik=w--; 
 
printf("\nw-- wynosi %d\n",wynik); 
 
getch(); 
 

 
  
 
Operatory relacji 
 
Mi

ę

dzy wyra

ż

eniami w j

ę

zyku C mog

ą

 wyst

ę

powa

ć

 nast

ę

puj

ą

ce 

relacje: 
 
== równe 
 
!= ró

ż

ne od 

 
> wi

ę

ksze od 

 
< mniejsze od 
 
>= wi

ę

ksze lub równe 

 
<= mniejsze lub równe 
 
Wszystkie operatory relacji maj

ą

 ni

ż

szy priorytet ni

ż

 

operatory arytmetyczne, co oznacza 

ż

e najpierw zostan

ą

 

wykonane operacje arytmetyczne a nast

ę

pnie zostan

ą

 dokonane 

porównania warto

ś

ci. 

background image

 

29 

 
Uj

ę

cie operacji w nawiasy powoduje ich wykonanie w pierwszej 

kolejno

ś

ci. 

 
W grupie operatorów logicznych, operatory > , < , >= , <= maja 
wy

ż

szy priorytet ni

ż

 == oraz != . 

 
Je

ż

eli relacja jest prawdziwa to zwrócona zostanie warto

ść

 1, 

w przeciwnym przypadku warto

ść

 0. 

 
  
 
//p_18 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y;double z;clrscr(); x=7; y=25; z=24.46; 
 
printf("x = %d y = %d z = %.2f\n",x,y,z); 
 
printf("operacja %d >= %d daje wynik %d\n",x,y,x>=y); 
 
printf("operacja %d == %d daje wynik %d\n",x,y,x==y); 
 
printf("operacja %d < %.2f daje wynik %d\n",x,z,x<z); 
 
printf("operacja %d > %.2f daje wynik %d\n",y,z,y>z); 
 
printf("operacja %d != %d - 18 daje wynik %d\n",x,y,x!=y-18); 
 
printf("operacja %d + %d != %.2f daje wynik 
%d\n",x,y,z,x+y!=z); 
 
getch(); 
 

 
1 / 2 + 1 / 2 == 1 à logiczny wynik 0 1 / 2 à 0 
 
1.0 / 3.0 + 1.0 / 3.0 + 1.0 / 3.0 == 1 à logiczne 0 1.0 / 3.0 
à 0.3333333 
 
Operator rzutowania 
 
W j

ę

zyku C mo

ż

na zamieni

ć

 jeden typ danych na inny poprzez 

poprzedzenie operandu operatorem rzutowania. 
 
(typ_danych)x 
 
 
typ danych na który ma zosta

ć

 zamieniona warto

ść

 x 

 

background image

 

30 

  
 
(float)5 à 5.0 
 
x=1; 
 
(float)(x+2) à 3.0 
 
//p_19 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y;clrscr(); x=8; y=5;printf("x = %d y = %d \n",x,y); 
printf("operacja %d / %d daje wynik %d\n",x,y,x/y); 
printf("operacja float(%d) / %d daje wynik 
%f\n",x,y,float(x)/y); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
Operacje p

ę

tli 

 
 
P

ę

tla for ( ... ) 

 
for ( wyra

ż

enie1; wyra

ż

enie2; wyra

ż

enie3 ) 

 

 
instrukcja1; 
 
instrukcja2; 
 
instrukcja3; 
 
........... 
 
........... 
 

 

background image

 

31 

wyra

ż

enie1 - wyra

ż

enie inicjuj

ą

ce p

ę

tli /wykonuje si

ę

 tylko 

raz/ 
 
wyra

ż

enie2 - wyra

ż

enie warunkowe 1 à wykonuje si

ę

 p

ę

tla 

à nie wykonuje si

ę

 

 
wyra

ż

enie3 - wykonuje si

ę

 po ka

ż

dym przebiegu instrukcji 

p

ę

tli, przed  

 
sprawdzeniem warto

ś

ci wyra

ż

enia2; 

 
//p_20 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i; 
 
clrscr(); 
 
printf("Kod 16 D.L. Kod 16 m.l. Kod 10 \n"); 
 
for (i=0;i<16;i++) 
 
printf(" %X %x %d \n",i,i,i); 
 
getch(); 
 

 
  
 
for (i=0; i<8; i++) 
 

 
ciało p

ę

tli 

 

 
for (i=0; i<8; i++ ) 
 
suma+=i; 
 
  
 

background image

 

32 

for (i=0; i<8; i++ ); à p

ę

tla pusta 

 
  
 
rozbudowana p

ę

tla for 

 
for ( i=0, j=10; i<10, j>0; i++, j-- ) 
 

 

 
  
 
//p_21 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i,j; 
 
clrscr(); 
 
for (i=0,j=8;i<8;i++,j--) 
 
printf("%d + %d = %d\n",i,j,i+j); 
 
getch(); 
 

 
//p_22 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i,j; 
 
clrscr(); 
 
for (i=0,j=8;i<8,j>5;i++,j--) 

background image

 

33 

 
printf("%d + %d = %d\n",i,j,i+j); 
 
getch(); 
 

 
//p_23 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i,j; 
 
clrscr(); 
 
for (i=0,j=1;i<8;i++,j++) 
 
printf("%d - %d = %d\n",j,i,j-i); 
 
getch(); 
 

 
  
 
  
 
P

ę

tle niesko

ń

czone 

 
for (;;) 
 

 
ciało p

ę

tli 

 

 
  
 
for(;;); 
 
for(;1;); 
 
for (;1;) 
 

background image

 

34 


 
ciało p

ę

tli 

 

 
//p_24 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int c; 
 
clrscr(); 
 
printf("Wpisz znak - jesli wpiszesz znak <x> to koniec 
programu\n"); 
 
for (c=' ';c!='x';) 
 

 
c=getc(stdin); 
 
putchar(c); 
 

 
printf("\nKoniec programu\n"); 
 
getch(); 
 

 
  
 
P

ę

tla while 

 
while(wyra

ż

enie) 

 

 
instrukcja1; 
 
instrukcja2; 
 

background image

 

35 


 
Je

ż

eli wyra

ż

enie zwraca warto

ść

 niezerow

ą

 wykonywane s

ą

 

instrukcje wewn

ą

trz p

ę

tli. Po wykonaniu instrukcji p

ę

tli 

wyra

ż

enie sprawdzane jest ponownie i je

ż

eli zwróci warto

ść

 

niezerowa instrukcje wewn

ą

trz p

ę

tli wykonywane s

ą

 ponownie, a

ż

 

do chwili gdy po kolejnym sprawdzeniu wyra

ż

enie przyjmie 

warto

ść

 0. 

 
//p_25 
 
# include <stdio.h># include <conio.h> 
 
void main(void) 
 

 
int c; 
 
clrscr(); 
 
printf("Wpisz znak - jesli wpiszesz znak <x> to koniec 
programu\n"); 
 
while (c!='x') 
 

 
c=getc(stdin); 
 
putchar(c); 
 

 
printf("\nKoniec programu\n"); 
 
getch(); 
 

 
  
 
Niesko

ń

czona p

ę

tla while 

 
while(1) 
 

 
instrukcja1; 
 
instrukcja2; 

background image

 

36 

 

 
  
 
//p_26 
 
# include <stdio.h># include <conio.h>void main(void){int 
c;clrscr(); printf("Wpisz znak\n"); while (1) { c=getc(stdin); 
putchar(c); break; } printf("\nKoniec programu\n"); getch();} 
 
  
 
Petla do - while 
 
W p

ę

tlach for i while wyra

ż

enia warunkowe znajduj

ą

 si

ę

 w 

nagłówku p

ę

tli. W p

ę

tli do-while odwrotnie – wyra

ż

enie 

znajduje si

ę

 na ko

ń

cu p

ę

tli. Dzieki temu instrukcje znajduj

ą

ce 

si

ę

 wewn

ą

trz p

ę

tli b

ę

d

ą

 wykonywane przynajmniej jeden raz 

zanim dojdzie do sprawdzenia warunku. 
 
do 
 

 
instrukcja1; 
 
instrukcja2; 
 
} while (wyra

ż

enie); 

 
Instrukcja do-while zako

ń

czona jest srednikiem. 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
//p_26_1 
 
#include <stdio.h>main(){ int i; i = 65; do { printf("The 
numeric value of %c is %d.\n", i, i); 

background image

 

37 

 
i++; 
 
} while (i<72); 
 
return 0; 
 
}  
 
  
 
P

ę

tle zagnie

ż

d

ż

one 

 
Wstawianie jednej p

ę

tli wewn

ą

trz innej p

ę

tli nazywa si

ę

 

zagnie

ż

d

ż

eniem p

ę

tli. 

 
//p_27 
 
# include <stdio.h># include <conio.h>void main(void){int i,j; 
clrscr(); for(i=1;i<=3;i++) 
 

 
printf("Poczatek iteracji %d p

ę

tli zewnetrznej \n",i); 

 
for(j=1;j<=4;j++) 
 
printf("Iteracja %d petli wewnetrznej \n",j); 
 
printf("Koniec iteracji %d petli zewnetrznej \n",i); 
 

 
getch(); 
 

 
Zanim rozpocznie si

ę

 kolejna iteracja p

ę

tli zawn

ę

trznej, musi 

zosta

ć

 zako

ń

czone wykonywanie p

ę

tli wewn

ę

trznej. Gdy 

rozpocznie si

ę

 kolejne wykonanie p

ę

tli zewn

ę

trznej, p

ę

tla 

wewn

ę

trzna jest ponownie wykonywana zadan

ą

 ilo

ść

 razy. 

 
  
 
  
 
//p_28 
 
# include <stdio.h># include <conio.h>void main(void) 
 

background image

 

38 

 
int i,j; 
 
clrscr(); 
 
for(i=1;i<=3;i++) 
 

 
printf("Poczatek iteracji %d p

ę

tli zewnetrznej \n",i); 

 
for(j=1;j<=4;j++) 
 
printf("Iteracja %d petli wewnetrznej \n",j); 
 
printf("Koniec iteracji %d petli zewnetrznej \n",i); 
 

 
getch(); 
 

 
  
 
  
 
Operatory - cd 
 
Operator sizeof 
 
sizeof(wyra

ż

enie) 

 
wyra

ż

enie oznacza typ danych lub zmienn

ą

, warto

ść

 jest zwraca 

w bajtach; 
 
  
 
//p_29 
 
# include <stdio.h># include <conio.h>void main(void){char c=' 
';int i=0;float f=0.0f;double d=0.0;clrscr(); 
 
printf("Dane typu char zajmuj

Ą

: %d - bajt\n",sizeof(char)); 

 
printf("Zmienna typu char zajmuje %d - bajt\n",sizeof c); 
 
printf("Dane typu int zajmuj

Ą

: %d - bajty\n",sizeof(int)); 

 
printf("Zmienna typu int zajmuje %d - bajty\n",sizeof i); 
 

background image

 

39 

printf("Dane typu float zajmuj

Ą

: %d - bajty\n",sizeof(float)); 

 
printf("Zmienna typu float zajmuje %d - bajty\n",sizeof f); 
 
printf("Dane typu double zajmuj

Ą

: %d - 

bajt˘w\n",sizeof(double)); 
 
printf("Zmienna typu double zajmuje %d - bajt˘w\n",sizeof d); 
 
getch(); 
 

 
podaj

ą

c operatorowi sam typ danych np. sizeof(int) lub 

identyfikator zmiennej np. sizeof int_1; poniewa

ż

 

identyfikator zmiennej nie jest słowem kluczowym j

ę

zyka C 

zatem mo

ż

emy pomin

ąć

 nawiasy. 

 
Operatory logiczne 
 
&& - iloczyn logiczny (AND) 
 
| | - suma logiczna (OR) 
 
! - negacja logiczna (NOT) 
 
s

ą

 to operatory dwu (&& , || ) lub jednoargumentowe, których 

argumentami s

ą

 wyra

ż

enia b

ą

d

ź

 warto

ś

ci logiczne; 

 
Operator iloczynu logiczne (AND) 
 
wyr1 && wyr2 
 
  
 
wyr1 wyr2 wyr1 && wyr2 
 
1 1 1 
 
1 0 0 
 
0 1 0 
 
0 0 0 
 
//p_30 
 
# include <stdio.h> 
 
# include <conio.h> 
 

background image

 

40 

void main(void) 
 

 
int num=0; 
 
clrscr(); 
 
printf("Operator && zwraca: %d\n", (num%2==0)&&(num%3==0)); 
 
num =2; 
 
printf("Operator && zwraca: %d\n", (num%2==0)&&(num%3==0)); 
 
num=3; 
 
printf("Operator && zwraca: %d\n", (num%2==0)&&(num%3==0)); 
 
num=6; 
 
printf("Operator && zwraca: %d\n", (num%2==0)&&(num%3==0)); 
 
getch(); 
 

 
  
 
Operator sumy logicznej (OR) 
 
wyr1 | | wyr2 
 
  
 
wyr1 wyr2 wyr1 | | wyr2 
 
1 1 1 
 
1 0 1 
 
0 1 1 
 
0 0 0 
 
  
 
  
 
  
 
//p_31 

background image

 

41 

 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int num; 
 
clrscr(); 
 
printf("Wpisz jednocyfrow

ą

 liczbe podzieln

ą

 \n przez 2 i przez 

3\n"); 
 
for (num=1; (num%2!=0)||(num%3!=0);) 
 
num=getchar()-48; 
 
printf("Szukana liczba to : %d\n",num); 
 
getch(); 
 

 
Operator logicznej negacji  
 
! wyr 
 
  
 
wyr ! wyr  
 
1 0  
 
0 1  
 
 
//p_32 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int num; 
 

background image

 

42 

clrscr(); 
 
num=7; 
 
printf("Dana jest zmienna num o warto˜ci 7 \n"); 
 
printf("!(num<7) zwraca : %d\n",!(num<7)); 
 
printf("!(num>7) zwraca : %d\n",!(num>7)); 
 
printf("!(num==7) zwraca : %d\n",!(num==7)); 
 
getch(); 
 

 
  
 
  
 
//p_33 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int num; 
 
clrscr(); 
 
printf("Wpisz jednocyfrow

ą

 liczb

ę

 podzieln

ą

 \n przez 2 i przez 

3\n"); 
 
for (num=1; !((num%2==0)&&(num%3==0));) 
 
num=getchar()-48; 
 
printf("Szukana liczba to : %d\n",num); 
 
getch(); 
 

 
  
 
  
 

background image

 

43 

Logiczne operatory bitowe 
 
& - bitowy iloczyn logiczny AND (I) 
 
| - bitowa suma logiczna OR (LUB) 
 
^ - bitowa alternatywa wył

ą

czna XOR (ALBO) 

 
~ - bitowe uzupełnienie do 2 (komplementarne) 
 
>> - przesuni

ę

cie bitów w prawo 

 
<< - przesuni

ę

cie bitów w lewo 

 
  
 
  
 
HEX Binarnie Dziesi

ę

tnie 

 
0 0000 0 
 
1 0001 1 
 
2 0010 2 
 
3 0011 3 
 
4 0100 4 
 
5 0101 5 
 
6 0110 6 
 
7 0111 7 
 
8 1000 8 
 
9 1001 9 
 
A 1010 10 
 
B 1011 11 
 
C 1100 12 
 
D 1101 13 
 
E 1110 14 
 
F 1111 15 

background image

 

44 

 
  
 
  
 
x & y 
 
Operator & porównuje ka

ż

dy bit operandu x z odpowiednim bitem 

operandu y. Je

ż

eli oba bity s

ą

 równe 1 operator ustawia 1 na 

tej samej pozycji bitu wyniku. Je

ż

eli cho

ć

by jeden z 

porównywanych bitów jest równy 0 to bit wyniku jest 0. 
& 11 à 01 
 
  
 
x | y 
 
Operator bitowy sumy logicznej (alternatywy zwykłej) ustawia 
bit wyniku na 1 je

ż

eli cho

ć

by jeden z bitów operandu (lub oba) 

jest równy 1. 
| 11 à 11 
 
x ^ y 
 
Operator alternatywy wył

ą

cznej ustawia bit wyniku na 1 , 

je

ż

elili dokładnie jeden z bitów obu operandów jest równy 1. 

^ 11 à 10 
 
~ x  
 
Operator negacji (inwersji bitowej) – dokonuj

ą

cy operacji na 

pojedynczym operandzie - odwraca warto

ść

 ka

ż

dego bitu 

operandu. 
 
~ 01 à 10 
 
//p_34 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y,z;x=4321;y=5678;clrscr(); printf("Dana jezt zmienna x = %u 
, czyli 0x%04X\n",x,x); printf("oraz zmienna y = %u , czyli 
0x%04X\n",y,y); 
 
z=x&y; 
 
printf("x&y zwraca %6u , czyli 0x%04X\n",z,z); 
 
z=x|y; 
 
printf("x|y zwraca %6u , czyli 0x%04X\n",z,z); 
 

background image

 

45 

z=x^y; 
 
printf("x^y zwraca %6u , czyli 0x%04X\n",z,z); 
 
printf("~x zwraca %6u , czyli x%04X\n",~x,~x); 
 
getch(); 
 

 
  
 
  
 
Operatory przesuni

ę

cia bitowego 

 
>> przesuwa bity operandu w prawo 
 
<< przesuwa bity operandu w lewo 
 
x >> y 
 
x << y 
 
x – operand, którego bity b

ę

d

ą

 przesuwane 

 
y – ilo

ść

 miejsc o które nale

ż

y przesun

ąć

 bity operandu 

 
8 >> 2 à 1000>>2 à 0010 à 2 
 
5 << 1 à 0101<<1 à 1010 à 10 
 
//p_35 
 
# include <stdio.h># include <conio.h>void main(void){int 
x,y,z;x=255;y=5;clrscr(); printf("Dana jest zmienna x = %4d , 
czyli 0x%04X\n",x,x); printf("oraz zmienna y = %4d , czyli 
0x%04X\n",y,y); z=x>>y; printf("x>>y zwraca %6d , czyli 
0x%04X\n",z,z); 
 
z=x<<y; 
 
printf("x<<y zwraca %6d , czyli 0x%04X\n",z,z); 
 
getch(); 
 

 
y > 0 
 
x >> y ß à x / 2y 

background image

 

46 

 
x << y ß à x * 2y 
 
  
 
  
 
Operator warunkowy – jedynym operatorem trójargumentowym. 
 
?: - operator warunkowy 
 
x ? y : z 
 
operandy x , y , z 
 
x - wyra

ż

enie logiczne – wyra

ż

enie warunkowe 

 
y - wyra

ż

enie wynikowe , które jest wykonywane gdy x zwraca 

warto

ść

 niezerow

ą

 (np. 1) 

 
z - wyra

ż

enie wynikowe, które jest wykonywane gdy x zwraca 

warto

ść

 0. 

 
  
 
//p_36 
 
# include <stdio.h># include <conio.h>void main(void){int 
x;x=sizeof(int);clrscr(); printf("%s\n", (x==2) ? "Typ danych 
int ma 2 bajty.":"Typ int nie ma 2 bajtów"); 
printf("Maksymalna wartosc liczby typu int to : %d\n", (x!=2) 
? ~(1<<x*8-1): ~(1<<15)); 
 
getch(); 
 

 
  
 
  
 
 
Typy danych - modyfikatory 
 
  
 
  
 
Bit znaku 
 
 

background image

 

47 

Jeden bit liczby mo

ż

e by

ć

 wykorzystany po to aby wskazywał czy 

liczba jest dodatnia czy ujemna. Jest to tzw, bit znaku. 
 
  
 
Modyfikator signed 
 
Dla liczb całkowitych pierwszy od lewej bit jest u

ż

ywany jako 

bit znaku. Je

ż

eli liczby całkowite typu int maj

ą

 16 bitów, i 

pierwszy bit od prawej jest okre

ś

lany bitem na pozycji 0 to 

bit znaku znajduje si

ę

 na pozycji 15. Je

ż

eli jego warto

ść

 

wynosi 0 to liczba jest dodatnia, za

ś

 gdy 1 to liczba jest 

ujemna. 
 
Sposób implementacji liczb ujemnych zmiennopozycyjnych typu 
float i double na razie pominiemy. 
 
modyfikator signed jest u

ż

ywany dla wskazania, i

ż

 jeden bit 

danych jest bitem znaku; 
 
deklaracja int à jest domyslnie traktowana jako signed int 
 
deklaracja char à zakres warto

ś

ci 0 – 255 (28 – 1) 

 
deklaracja signed char à zakres warto

ś

ci  

 
od -128 (-27 ) 
 
do +127 (27 – 1) 
 
Aby zamieni

ć

 liczb

ę

 dwójkow

ą

 na równ

ą

 jej co do warto

ś

ci 

bezwzgl

ę

dnej lecz ujemn

ą

, nale

ż

y: 

 
liczba 12 345 à 0011 0000 0011 1001 
 
1/ znajdujemy kod odwrotny liczby: 
 
 
1100 1111 1100 0110 
 
2/ dodajemy 1 
 
1100 1111 1100 0111 
 
jest to kod dwójkowy liczby - 12 345 
 
  
 
  
 
  

background image

 

48 

 
Modyfikator unsigned 
 
modyfikator unsigned stosowany jest dla okre

ś

lenia , i

ż

 

pierwszy bit liczby nie jest jej bitem znaku; 
 
mo

ż

e on by

ć

 stosowany jako : 

 
unsigned int 
 
unsigned char 
 
unsigned int x; à x: 0 , 65 535 (216 – 1) 
 
Standard ANSI C pozwala na stosowanie przyrostków U i u przy 
stałych bez znaku: 
 
unsigned int x,y; 
 
x = 1234U; 
 
y = 0xABCFu; 
 
  
 
//p_37 
 
# include <stdio.h># include <conio.h>// funkcja druk_bin 
drukuje binarny podany dzisi

ę

tnie argument x typu intvoid 

druk_bin(int x){ int n; for (n=15;n>=0;n--) ((x>>n&1) ? 
putchar('1') : putchar('0')); 
 

 
void main(void) 
 

 
signed char ch; 
 
int x; 
 
unsigned int y; 
 
ch=0xFF; 
 
x=0xFFFF; 
 
y=0xFFFF; 
 
clrscr(); 

background image

 

49 

 
printf("\nDziesi

ę

tnie ze znakiem 0xFF to : %d",ch); 

 
printf("\nDziesi

ę

tnie ze znakiem 0xFFFF to : %d a binarnie 

:",x); 
 
druk_bin(0xFFFF); 
 
printf("\nDziesietnie bez znaku 0xFFFF to : %u",y); 
 
printf("\nDziesi

ę

tnie: 12345 to Hex: 0x%X i binarnie: 

",12345); 
 
druk_bin(12345); 
 
printf("\nDziesi

ę

tnie: -12345 to Hex: 0x%X i binarnie: ",-

12345); 
 
druk_bin(-12345); 
 
getch(); 
 

 
  
 
Modyfikatory rozmiaru danych 
 
 
Dla zmniejszenia lub zwi

ę

kszenia pami

ę

ci zajmowanej przez dane 

słu

żą

 modyfikatory short i long. 

 
  
 
  
 
Modyfikator short 
 
Modyyfikator short umo

ż

liwia np. w systemie 32 bitowym 

skrócenie danych in z 32 bitów do 16 bitów 
 
short x; oznacza short signed int x; 
 
unsigned short x; oznacza short unsigned int x; 
 
  
 
  
 
Modyfikator long 
 

background image

 

50 

Modyfikator long poszerza zakres warto

ś

ci iprzez to dane 

zajmuja wi

ę

cej miejsca w pami

ę

ci. 

 
Je

ż

eli zmienna typu int zajmuje domy

ś

lnie 16 bitów to 

modyfikator long int powi

ę

ksza wielko

ść

 tej zmiennej do 32 

bitów; 
 
long int x; à -2147483648 (-231 ) do 2147483647 (231 – 1) 
 
Standard ANSI C pozwala na dodawanie do stałych typu long 
przyrostków L i l . 
 
long int x,y; 
 
x=123456789L; 
 
y=0xABCD1234l; 
 
//p_38 
 
# include <stdio.h># include <conio.h>void 
main(void){clrscr(); printf(" Rozmiar int: %d \n 
",sizeof(int)); printf("Rozmiar short int: %d \n 
",sizeof(short int)); printf("Rozmiar long int: %d \n 
",sizeof(long int)); 
 
printf("Rozmiar float: %d \n ",sizeof(float)); 
 
printf("Rozmiar double: %d \n ",sizeof(double)); 
 
printf("Rozmiar long double: %d \n ",sizeof(long double)); 
 
getch(); 
 

 
  
 
short int - 2 bajty - 16 bitów - liczby całkowite krótkie 
 
long int - 4 bajty - 32 bity - liczby całkowite długie 
 
float - 4 bajty - 32 bity - liczby zmiennoprzecinkowe krótkie 
 
double - 8 bajtów – 64 bity - liczby zmiennoprzecinkowe o 
podwójnej  
 
precyzji 
 
long double - 10 bajtów - 80 bitów - liczby zmiennoprzecinkowe 
długie 

background image

 

51 

 
  
 
Specyfikatory formatu h l L 
 
  
 
%hd %hi 
 
dziesietnie, liczba całkowita krótka - short int 
 
  
 
%hu 
 
dziesi

ę

tnie, liczba całkowita krótka bez znaku - short 

unsigned int 
 
  
 
  
 
  
 
%ld %Ld 
 
dziesi

ę

tnie, całkowita długa - long int 

 
  
 
%lu %Lu 
 
dziesi

ę

tnie, całkowita długa bez znaku - long unsigned int 

 
  
 
//P_39 
 
# include <stdio.h># include <conio.h>void main(void) 
 

 
short int x; 
 
unsigned int y; 
 
long int s; 
 
unsigned long int t; 
 
x=0xFFFF; 

background image

 

52 

 
y=0xFFFFU; 
 
s=0xFFFFFFFFl; 
 
t=0xFFFFFFFFL; 
 
clrscr(); 
 
printf("Short int 0xFFFF to: %hd\n",x); 
 
printf("Unsigned int 0xFFFF to: %u\n",y); 
 
printf("Long int 0xFFFFFFFF to: %ld\n",s); 
 
printf("Unsigned long int 0xFFFFFFFF to %lu\n",t); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Funkcje matematyczna 
 
 
  
 
Grupy funkcji matematycznych 
 
Trygonometryczne i hiperboliczne : sin() , cos() , cosh() 
,...... 
 

background image

 

53 

Wykładnicze i logarytmiczne : exp() , pow() , log10() , ..... 
 
Pozostałe : ceil() , fabs() , floor() , .... 
 
Wykorzystanie funkcji sin(), cos(), tan(); 
 
argumentem funkcji jest k

ą

t x w radianach 

 
radiany = stopnie * (3.141593 / 180.0 ) 
 
#include <math.h> 
 
double sin(double x); 
 
double cos(double x); 
 
double tan(double x); 
 
  
 
//p_40 
 
# include <stdio.h># include <conio.h># include <math.h>void 
main(void){double x;x=45.0;x*=3.141593/180.0;clrscr(); 
printf("Sinus 45 : %f\n",sin(x)); printf("Cosinus 45 : 
%f\n",cos(x)); 
 
printf("Tangens 45 : %f\n",tan(x)); 
 
getch(); 
 

 
  
 
  
 
Wywołanie funkcji : pow() i sqrt(); 
 
#include <math.h> 
 
double pow(double a, double b); 
 
double sqrt(double x); 
 
  
 
//p_41 
 

background image

 

54 

# include <stdio.h># include <conio.h># include <math.h>void 
main(void){double x,y,z;x=64.0;y=3.0;z=0.5;clrscr(); 
printf("64 x 64 x 64 : %7.0f\n",pow(x,y)); 
 
printf("Pierw. kw. z 64 : %2.0f\n",sqrt(x)); 
 
printf("64 do pot

ę

gi 1/2 : %2.0f\n",pow(x,z)); 

 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
Sterowanie programem 
 
 
Instrukcja warunkowa if 
 
if (wyra

ż

enie) 

 

 
blok instrukcji 
 

 
  
 
//p_42 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i; 
 

background image

 

55 

clrscr(); 
 
printf("Liczby caˆkowite podzielne przez 2 i przez 3\n"); 
 
printf("\tw zakresie od 0 do 100 \n"); 
 
for (i=0;i<=100;i++) 
 
if((i%2==0)&&(i%3==0)) 
 
printf(" %d\n",i); 
 
getch(); 
 

 
Instrukcja warunkowa if-else 
 
if (wyra

ż

enie) 

 

 
blok instrukcji 
 

 
else 
 

 
blok instrukcji 
 

 
  
 
//p_43 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i; 
 
clrscr(); 
 
printf("Liczby parzyste Liczby nieparzyste\n"); 

background image

 

56 

 
for (i=0;i<10;i++) 
 
if(i%2==0) 
 
printf("%d",i); 
 
else 
 
printf("%30d\n",i); 
 
getch(); 
 

 
  
 
Zagnie

ż

d

ż

one instrukcje warunkowe if 

 
  
 
//p_44 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i; 
 
clrscr(); 
 
for (i=-5;i<=5;i++) 
 
if(i>0) 
 
if(i%2==0) 
 
printf("%d to liczba parzysta \n",i); 
 
else 
 
printf("%d to liczba nieparzysta \n",i); 
 
else 
 
if (i==0) 
 

background image

 

57 

printf("To jest zero\n"); 
 
else 
 
printf("Liczba ujemna %d\n",i); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
Instrukcja switch 
 
switch (wyra

ż

enie) 

 

 
case wyra

ż

enie1: 

 
instrukcja1; 
 
case wyra

ż

enie2: 

 
instrukcja2; 
 
........... 
 
default: 
 
instrukcja-domyslna; 
 

 
Najpierw sprawdzana jest warto

ść

 wyra

ż

enia (wyra

ż

enie 

sterujace) 
 
Je

ż

eli warto

ść

 wyra

ż

enia jest równa wyra

ż

enie1 to wykonywana 

jest instrukcja1, je

ż

eli jest równa wyra

ż

enie2 to wykonywana 

jest isntrukcja2, itd. 
 

background image

 

58 

wyra

ż

enie1, wyra

ż

enie2 i pozostałe wyra

ż

enia s

ą

 wyra

ż

eniami 

stałowarto

ś

ciowymi; 

 
Je

ż

eli warto

ść

 zwrócona przez wyra

ż

enie steruj

ą

ce nie jest 

równa warto

ś

ci któregokolwiek z wyra

ż

e

ń

 stałowarto

ś

ciowych, 

zostanie wykonana instrukcja domyslna. 
 
  
 
//p_45 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int day; 
 
clrscr(); 
 
printf("Wpisz numer dnia z zakresu od 1 do 3\n"); 
 
day=getchar(); 
 
switch(day) 
 

 
case '1': 
 
printf("Dzie

ń

 1\n"); 

 
case '2': 
 
printf("Dzie

ń

 2\n"); 

 
case '3': 
 
printf("Dzie

ń

 3\n"); 

 
default: 
 

 

 
getch(); 
 

background image

 

59 


 
  
 
Instrukcja break 
 
  
 
//p_45p 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int day; 
 
clrscr(); 
 
printf("Wpisz numer dnia z zakresu od 1 do 3\n"); 
 
day=getchar(); 
 
switch(day) 
 

 
case '1': 
 
printf("Dzie

ń

 1\n"); 

 
break; 
 
case '2': 
 
printf("Dzien 2\n"); 
 
break; 
 
case '3': 
 
printf("Dzie

ń

 3\n"); 

 
break; 
 
default: 
 

background image

 

60 

 

 
getch(); 
 

 
//p_46 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int day; 
 
clrscr(); 
 
printf("Wpisz numer dnia tygodnia od 1 do 7\n"); 
 
day=getchar(); 
 
switch(day) 
 

 
case '1': 
 
printf("Dzie

ń

 1 - Niedziela\n"); 

 
break; 
 
case '2': 
 
printf("Dzie

ń

 2 - Poniedziaˆek\n"); 

 
break; 
 
case '3': 
 
printf("Dzie

ń

 3 - Wtorek\n"); 

 
break; 
 
case '4': 
 
printf("Dzie

ń

 4 - 

Ś

roda\n"); 

 

background image

 

61 

break; 
 
case '5': 
 
printf("Dzie

ń

 5 - Czwartek\n"); 

 
break; 
 
case '6': 
 
printf("Dzie

ń

 6 - Pi

ą

tek\n"); 

 
break; 
 
case '7': 
 
printf("Dzie

ń

 7 - Sobota\n"); 

 
break; 
 
default: 
 
printf("Liczba spoza zakresu 1 - 7"); 
 
break; 
 

 
getch(); 
 

 
Przerwanie p

ę

tli niesko

ń

czonej 

 
for(;;) 
 

 
instr1; 
 
instr2; 
 
...... 
 

 
  
 
while(1) 
 

background image

 

62 

 
instr1; 
 
instr2; 
 
...... 
 

 
  
 
//p_47 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int c; 
 
clrscr(); 
 
printf("Wpisz znak:\n"); 
 
printf("x + <Enter> = Koniec programu\n"); 
 
while (1) 
 

 
c=getc(stdin); 
 
if(c=='x') 
 
break; 
 

 
printf("Program zostaˆ przerwany - Koniec \n"); 
 
getch(); 
 

 
  
 
Instrukcja continue 
 

background image

 

63 

Czasem zamist przerywa

ć

 p

ę

tl

ę

, trzeba tylko pomin

ąć

 pewn

ą

 

grup

ę

 instrukcji, ale p

ę

tla powinna wykonywa

ć

 si

ę

 dalej. 

 
Instrukcja continue powoduje natychmiastowy skok na pocz

ą

tek 

p

ę

tli i poj

ę

cie próby ponownego wykonania p

ę

tli od pocz

ą

tku. 

 
//p_48 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int i,sum; 
 
clrscr(); 
 
sum=0; 
 
for(i=1;i<8;i++) 
 

 
if((i==3) || (i==5)) 
 
continue; 
 
sum+=i; 
 

 
printf("Suma liczb 1 2 3 4 6 i 7 wynosi: %d\n",sum); 
 
getch(); 
 

 
  
 
Instrukcja goto 
 
etykieta: 
 
instrukcja1; 
 
instrukcja2; 
 
......... 

background image

 

64 

 
goto etykieta; 
 
etykieta pokazuje w które miejsce w programie ma nastapi

ć

 skok 

po wykonaniu instrukcji goto; 
 
etykieta wyst

ę

puje w dwóch miejscach: 

 
1/ ze znakiem : w miejscu do którego nastepuje skok (etykietaJ  
 
2/ po instrukcji goto (goto etykieta:) 
 
  
 
  
 
  
 
  
 
Wska

ź

niki 

 
 
  
 
  
 
adres w pami

ę

ci = zmienna = stała 

 
 
 
warto

ść

 lewostronna warto

ść

 prawostronna 

 
zmiennej zmiennej 
 
 
  
 
  
 
deklaracja nadaje zmiennej warto

ść

 lewostronn

ą

 – 

przyporz

ą

dkowuj

ą

c jej adres w pami

ę

ci; 

 
 
int x; 
 
 
podstawienie nadaje zmiennej warto

ść

 prawostronn

ą

 – umiesza w 

zarezerwowanym dla zmiennej obszarze pami

ę

ci dane; 

 
 

background image

 

65 

x=10; 
 
 
  
 
Operator adresowy & 
 
 
Operator adresowy zwraca warto

ść

 lewostronn

ą

 zmiennej 

 
 
long int x,y; 
 
y=&x; 
 
przypisuje zmiennej y adres zmiennej x; 
 
  
 
  
 
  
 
  
 
  
 
  
 
// p_49 
 
# include <stdio.h># include <conio.h>void main(void){char 
c;int x;float y;clrscr(); printf("c: adres=0x%p, 
zawarto

ść

=%c\n",&c,c); printf("x: adres=0x%p, 

zawarto

ś

c=%d\n",&x,x); printf("y: adres=0x%p, 

zawarto

ś

c=%5.2f\n",&y,y); 

 
c='A'; 
 
x=7; 
 
y=123.45; 
 
printf("c: adres=0x%p, zawarto

ść

=%c\n",&c,c); 

 
printf("x: adres=0x%p, zawarto

ś

c=%d\n",&x,x); 

 
printf("y: adres=0x%p, zawarto

ść

=%5.2f\n",&y,y); 

 
getch(); 
 

background image

 

66 


 
  
 
specyfikator formatu %p /’pointer’/ u

ż

ywany jest dla 

wyprowadzania adresów zmiennych; 
 
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Deklaracja wska

ź

ników 

 
 
Wska

ź

nik to zmienna, w której przechowywany jest adres innej 

zmiennej. 
 
 
warto

ść

 lewostronna warto

ść

 prawostronna 

 
wska

ż

nika to jego = wska

ź

nik = to adres innej zmiennej 

 
adres 
 
 
 
  
 
słu

ż

y do odwołania si

ę

 

 

background image

 

67 

do samego wska

ź

nika 

 
 
  
 
deklaracja wska

ż

nika 

 
 
typ danych * nazwa_wska

ź

nika 

 
 
  
 
typ danych , których adres operator jednoargumentowy 
 
przechowywał b

ę

dzie wska

ź

nik 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
// p_50 
 

background image

 

68 

# include <stdio.h># include <conio.h>void main(void){char 
c,*ptr1;int x,*ptr2;float y,*ptr3;clrscr(); c='A'; x=7; 
y=123.45; printf("c: adres=0x%p, zawarto

ść

=%c\n",&c,c); 

 
printf("x: adres=0x%p, zawarto

ść

=%d\n",&x,x); 

 
printf("y: adres=0x%p, zawarto

ść

=%5.2f\n",&y,y); 

 
ptr1=&c; 
 
printf("ptr_c adres=0x%p, zawiera=0x%p\n",&ptr1,ptr1); 
 
printf("*ptr_c => %c\n",*ptr1); 
 
ptr2=&x; 
 
printf("ptr_x adres=0x%p, zawiera=0x%p\n",&ptr2,ptr2); 
 
printf("*ptr_x => %d\n",*ptr2); 
 
ptr3=&y; 
 
printf("ptr_y adres=0x%p, zawiera=0x%p\n",&ptr3,ptr3); 
 
printf("*ptr_y => %5.2f\n",*ptr3); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  

background image

 

69 

 
  
 
  
 
  
 
  
 
Operator dereferencji * /operator jednoargumentowy – unarny/ 
 
Poł

ą

czenie oparatora dereferencji * oraz nazwy wska

ź

nika 

powoduje odwołanie do prawostronnej warto

ś

ci zmiennej 

wskazywanej. 
 
char c; - deklaracja zmiennej 
 
 
char *ptrc; - deklaracja wska

ź

nika 

 
 
ptrc=&c; - zainicjowanie wska

ź

nika 

 
 
  
 
odwołanie do zmiennej c: 
 
 
przez nazw

ę

 c - bezpo

ś

rednie 

 
 
przez *ptrc - posrednie ; przez wska

ź

nik 

 
 
printf(”%c”,c) to samo co printf(”%c”,*ptrc) 
 
 
int x=1234, *ptrx; 
 
ptrx=&x; 
 
printf(”%d”,(*ptrx+1)); à 1235 
 
 
  
 
Wska

ż

nik pusty - to wska

ź

nik o prawostronnej warto

ś

ci = 0; 

 
 
char *ptrc; 

background image

 

70 

 
int *ptrx; 
 
ptrc=ptrx=0; 
 
puste wska

ź

niki 

 
  
 
  
 
  
 
  
 
  
 
Modyfikowanie zawarto

ś

ci zmiennej przez wska

ź

niki: 

 
 
// p_51 
 
# include <stdio.h># include <conio.h>void main(void){char 
c,*ptr_c;clrscr(); c='A'; printf("c: adres=0x%p, 
zawarto

ść

=%c\n",&c,c); 

 
ptr_c=&c; 
 
printf("ptr_c adres=0x%p, zawiera=0x%p\n",&ptr_c,ptr_c); 
 
printf("*ptr_c => %c\n",*ptr_c); 
 
*ptr_c='B'; 
 
printf("ptr_c adres=0x%p, zawiera=0x%p\n",&ptr_c,ptr_c); 
 
printf("*ptr_c => %d\n",*ptr_c); 
 
printf("c: adres=0x%p, zawiera=%c\n",&c,c); 
 
getch(); 
 

 
  
 
Wskazanie tego samego adresu. 
 
 
Ten sam adres w pami

ę

ci mo

ż

e by

ć

 wskazywany przez wi

ę

cej ni

ż

 

jeden wska

ź

nik. 

background image

 

71 

 
 
char p1,p2; 
 
char zmienna; 
 
p1=&zmienna; 
 
p2=&zmienna; 
 
//p_52 
 
# include <stdio.h># include <conio.h>void main(void){int 
x;int *ptr_1,*ptr_2,*ptr_3;clrscr(); x=1234; 
 
printf("x: adres=0x%p, zawarto˜†=%d\n",&x,x); 
 
ptr_1=&x; 
 
printf("ptr_1 adres=0x%p, zawiera=0x%p\n",&ptr_1,ptr_1); 
 
printf("*ptr_1 => %d\n",*ptr_1); 
 
ptr_2=&x; 
 
printf("ptr_2 adres=0x%p, zawiera=0x%p\n",&ptr_2,ptr_2); 
 
printf("*ptr_2 => %d\n",*ptr_2); 
 
ptr_3=ptr_1; 
 
printf("ptr_3 adres=0x%p, zawiera=0x%p\n",&ptr_3,ptr_3); 
 
printf("ptr_3 => %d\n",*ptr_3); 
 
getch(); 
 

 
  
 
Tablice 
 
 
Zestaw danych tego samego typu, posiadaj

ą

cych podobne 

przeznaczenie nazywany jest tablic

ą

 
Ka

ż

da zmienna wchodz

ą

ca w skł

ą

d tablicy nazywa si

ę

 jej 

elementem. Do wszystkich elementów tablicy mo

ż

na odwoływac si

ę

 

poprzez t

ę

 sama nazw

ę

 tablicy, zajmuj

ą

 one poło

ż

one koło 

siebie miejsca w pami

ę

ci. 

background image

 

72 

 
Deklaracja tablicy : 
 
typ_danych nazwa_tablicy[rozmiar_tablicy]; 
 
 
  
 
  
 
wspólny typ identyfikator ilo

ść

 elementów tablicy 

 
  
 
np. tablica danych numerycznych 10-elementowa 
 
int tab[10]; 
 
  
 
Indeksowanie elementów tablicy : 
 
int tab[9]; 
 
element – 1 tab[0] 
 
element - 2 tab[1] 
 
.......... 
 
element - 9 tab[8] 
 
  
 
wyra

ż

enia umieszczone w nawiasach umo

ż

liwiaj

ą

 odwołanie do 

elementów tablicy - s

ą

 nazywane referencjami do elementów 

tablicy; 
 
  
 
Inicjowanie tablic 
 
1/ przez referencje do elementów i operator podstawienia : 
 
 
tab[6]=12; 
 
2/ jednoczesnie : 
 
int tab[5] = {2,4,3,66,1}; 
 

background image

 

73 

 
//p_53 
 
# include <stdio.h># include <conio.h>void main(void){int 
i;int Tab[10];clrscr(); for(i=0;i<10;i++) 
 

 
Tab[i]=i+1; 
 
printf("Element tablicy Tab[%d] ma warto

ść

: %d. \n",i,Tab[i]); 

 

 
getch(); 
 

 
Rozmiar tablicy 
 
 
Obszar pami

ę

ci zajmowany przez tablic

ę

 – adres jej pierwszego 

i ostatniego elementu. 
 
 
// p_54 
 
# include <stdio.h># include <conio.h>void main(void){int 
total;int list[10];clrscr(); total=sizeof(int)*10; 
printf("Element typu int zajmuje %d - bajty \n",sizeof(int)); 
 
printf("Cała tablica zajmuje %d bajt˘w \n",total); 
 
printf("Adres pierwszego elementu tablicy: 0x%x\n",&list[0]); 
 
printf("Adres ostatniego elementu tablicy : 0x%x\n",&list[9]); 
 
getch(); 
 

 
- operator adresowy & zwraca adres elementu tablicy 
 
typ_danych nazwa_tablicy[rozmiar_tablicy]; 
 
Ilo

ść

 bajtów zajmowanych przez tablic

ę

 to : 

 
sizeof(typ_danych) * rozmiar_tablicy 
 
lub 
 

background image

 

74 

sizeof(nazwa_tablicy) 
 
  
 
  
 
Wska

ź

nikowanie tablic 

 
//p_55 
 
# include <stdio.h># include <conio.h>void main(void){int 
*ptr_int;int list_int[10];int i;clrscr(); for(i=0;i<10;i++) 
list_int[i]=i+1; ptr_int=list_int; printf("Adres startowy 
tablicy 0x%p\n",ptr_int); 
 
printf("Warto

ść

 pierwszego elementu tablicy %d\n",*ptr_int); 

 
ptr_int=&list_int[0]; 
 
printf("Adres pierwszego elementu : 0x%p\n",ptr_int); 
 
printf("Warto

ść

 pierwszego elementu : %d\n",*ptr_int); 

 
getch(); 
 

podstawienie pod wska

ź

nik adres pierwszego elementu tablicy 

 
p_tab=&tab[0]; 
podstawienie pod wska

ź

nik nazwy tablicy; 

 
p_tab=tab; 
wykorzystanie nazwy tablicy jako adresu jej pierwszego 
elementu 
 
  
 
  
 
// p_55p 
 
# include <stdio.h># include <conio.h>void main(void) 
 

 
int *ptr_int; 
 
int list_int[10]; 
 
int i; 
 

background image

 

75 

clrscr(); 
 
for(i=0;i<10;i++) 
 
list_int[i]=i+1; 
 
ptr_int=list_int; 
 
printf("Adres startowy tablicy 0x%p\n",ptr_int); 
 
printf("Warto

ść

 pierwszego elementu tablicy %d\n",*ptr_int); 

 
ptr_int=&list_int[0]; 
 
printf("Adres pierwszego elementu : 0x%p\n",ptr_int); 
 
printf("Adres drugiego elementu : 0x%p\n",ptr_int+1); 
 
printf("Warto

ść

 pierwszego elementu : %d\n",*ptr_int); 

 
printf("Warto

ść

 drugiego elementu : %d\n",*(ptr_int+1)); 

 
getch(); 
 

 
Tablice znakowe 
 
Tablice znakowe posiadaj

ą

 elementy, z których ka

ż

dy zajmuje 1 

bajt; zatem rozmiar tablicy jest jednocze

ś

nie obszarem w 

bajtach zajmowanym przez tablic

ę

 
W j

ę

zyku C ła

ń

cuchy znaków (teksty) s

ą

 okre

ś

lane jako 

jednowymiarowe tablice znakowe, w których ostatni element to 
tzw. znak zerowy, oznaczany symbolicznie ‘\0’ o kodzie ASCII = 
0. 
 
  
 
//p_56 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
char tab_ch[7]={'W','i','t','a','j','!','\0'}; 
 

background image

 

76 

int i; 
 
clrscr(); 
 
for(i=0;i<7;i++) 
 
printf("Tab_ch[%d] zawiera %c\n",i,tab_ch[i]); 
 
// Metoda I 
 
printf("Wszystkie elementy razem - metoda I: \n"); 
 
for(i=0;i<7;i++) 
 
printf("%c",tab_ch[i]); 
 
// Metoda II 
 
printf("\nWszystkie elementy razem - metoda II: \n"); 
 
printf("%s\n",tab_ch); 
 
getch(); 
 

 
  
 
Znak zerowy ‘\0’ 
 
Jest to pojedynczy znak specjalny okre

ś

laj

ą

cy koniec ła

ń

cucha 

znakowego. Funkcja printf() przetwarzaj

ą

c ła

ń

cuch znaków w 

formacie %s przetwarza znak po znaku, a

ż

 do napotkania znaku 

zerowego. Zank zerowy uto

ż

samiany z fałszem mo

ż

e by

ć

 równie

ż

 

stosowany to testowania warto

ś

ci logicznej w p

ę

tlach 

steruj

ą

cych. 

 
  
 
//p_57 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
char tab_ch[18]={'C',' ', 
 

background image

 

77 

't','o',' ', 
 
'j','

ę

','z','y','k',' ', 

 
'p','r','o','g','r','.','\0'}; 
 
int i; 
 
clrscr(); 
 
for(i=0;tab_ch[i]!='\0';i++) 
 
printf("%c",tab_ch[i]); 
 
getch(); 
 

 
  
 
Tablice wielowymiarowe 
 
typ_danych 
nazwa_tablicy[rozmiar_tab1][rozmiar_tab2]....[rozm_tabN]; 
 
N - jest całkowite i dodatnie 
 
  
 
tablica dwuwymiarowa 2 x 3 : 
 
int tab [2][3]; 
 
inicjowanie : 
 
tab[0][0] = 1; 
 
tab[0][1] = 2; 
 
tab[0][2] = 3; 
 
tab[1][0]= 4; 
 
tab[1][1] = 5; 
 
tab[1][2] = 6; 
 
lub  
 
int tab[2][3] = {1,2,3,4,5,6}; 
 

background image

 

78 

lub 
 
int tab[2][3] = { {1,2,3},{4,5,6}}; 
 
/p_58 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int tab[3][5]={1,2,3,4,5, 
 
10,20,30,40,50, 
 
100,200,300,400,500}; 
 
int i,j; 
 
clrscr(); 
 
for(i=0;i<3;i++) 
 

 
printf("\n"); 
 
for(j=0;j<5;j++) 
 
printf("%6d",tab[i][j]); 
 

 
getch(); 
 

 
//p_59 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int tab[3][5]={1,2,3,4,5,10,20,30,40,50,100,200,300,400,500}; 

background image

 

79 

 
int i,j; 
 
clrscr(); 
 
for(i=0;i<3;i++) 
 

 
printf("\n"); 
 
for(j=0;j<5;j++) 
 
printf("%6d",tab[i][j]); 
 

 
getch(); 
 

 
//p_60 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int 
tab[3][5]={{1,2,3,4,5},{10,20,30,40,50},{100,200,300,400,500}}

 
int i,j; 
 
clrscr(); 
 
for(i=0;i<3;i++) 
 

 
printf("\n"); 
 
for(j=0;j<5;j++) 
 
printf("%6d",tab[i][j]); 
 

 

background image

 

80 

getch(); 
 

 
//p_61 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
int 
tab[][5]={{1,2,3,4,5},{10,20,30,40,50},{100,200,300,400,500}}; 
 
int i,j; 
 
clrscr(); 
 
for(i=0;i<3;i++) 
 

 
printf("\n"); 
 
for(j=0;j<5;j++) 
 
printf("%6d",tab[i][j]); 
 

 
getch(); 
 

 
  
 
  
 
  
 
Tablice bezwymiarowe 
 
Mo

ż

emy deklarowac tablic

ę

 bez wpisywania jej rozmiaru w 

nawiasach kwadratowych. Kompilator mo

ż

e sam obliczy

ć

 rozmiar 

tablicy je

ż

eli zadeklarowana zostanie jako bezwymiarowa, 

 
int tab[] = {12,45,56,78,34,2,34,5,6,78,98}; 
 

background image

 

81 

w przypadku tablic wielowymiarowych bez wymiaru mo

ż

na 

pozostawi

ć

 tylko jeden wymiar (pierwszy z lewej); 

 
int tab_2[ ][4] = { 
 
‘a’,’A’, 
 
‘b’,’B’, 
 
‘c’,’C’, 
 
‘d’,’D’}; 
 
  
 
//p_62 
 
# include <stdio.h> 
 
# include <conio.h> 
 
void main(void) 
 

 
char tab_ch[]={'C',' ', 
 
't','o',' ', 
 
'j','

ę

','z','y','k','\0'}; 

 
int 
tab[][5]={{1,2,3,4,5},{10,20,30,40,50},{100,200,300,400,500}}; 
 
clrscr(); 
 
printf("Rozmiar tablicy tab_ch[] wynosi %d 
bajt˘w.\n",sizeof(tab_ch)); 
 
printf("Rozmiar tablicy tab[][5] wynosi %d 
bajt˘w.\n",sizeof(tab)); 
 
getch(); 
 

 
  
 
  
 
  

background image

 

82 

 
  
 
  
 
  
 
  
 
Ła

ń

cuchy znakowe 

 
 
Ła

ń

cuch znakowy czyli string to tablica znakowa, której 

ostatnim elementem jest znak ‘\0’. 
 
Szereg znaków uj

ę

ty w cudzysłów (” ”) jest nazywany stał

ą

 

ła

ń

cuchow

ą

 lub stał

ą

 tekstow

ą

, kompilator mo

ż

e automatycznie 

doda

ć

 znacznik ko

ń

ca [\0]. 

 
char tab1[5] = {‘J’,’a’,’n’,’e’,’k’}; 
 
char tab2[6] = {‘J’,’a’,’n’,’e’,’k’,’\0’}; 
 
tab1 - jest traktowana jako tablica znakowa 
 
tab2 - jest teraz tak

ż

e traktowana jako ła

ń

cuch znakowy 

poniewa

ż

 posiada znacznik ko

ń

ca ła

ń

cucha; 

 
char tab3[6] = ”Janek”; 
 
kompilator automatycznie doda znak ‘\0’; 
 
inicjowanie tablicy przy pomocy stałej ła

ń

cuchowej oraz 

inicjacja tab2 s

ą

 równowa

ż

ne; 

 
  
 
Stałe ła

ń

cuchowe i stałe znakowe 

 
Stała ła

ń

cuchowa to szereg znaków uj

ę

tych w znak (” ”); 

 
Stał

ą

 znakowa to pojedynczy znak umieszczony w (‘ ’); 

 
char znak = ‘x’; 
 
char string = ”x”; 
 
zadeklarowanie zmiennej znakowej znak powoduje zarezerwowanie 
w pami

ę

ci 1 bajtu; 

 

background image

 

83 

zadeklarowanie zmiennej ła

ń

cuchowej string powoduje 

zarezerwowanie 2 bajtów : dla znaku ‘x’ i dla znacznika ko

ń

ca 

ła

ń

cucha; 

 
Ła

ń

cuch znakowy jest traktowany jako wska

ź

nik do zmiennej typu 

char (wskazuj

ą

cy pierwszy znak ła

ń

cucha). 

 
Dlatego identyfikator ła

ń

cucha znakowego mo

ż

na przypisa

ć

 

wska

ź

nikowi wprost bez stosowania operatora adresowego; 

 
char *ptr_str; 
 
ptr_str = ”Ła

ń

cuch znakowy”; 

 
Za

ś

 stałej znakowej nie mo

ż

na w ten sposób przypisa

ć

 
char *ptr_str; 
 
ptr_str = ‘x’; /operator przypisania próbuje przypisa

ć

 

prawostronna  
 
warto

ść

 (‘x’), natomiast wska

ź

nik oczekuje warto

ś

ci 

lewostronnej (adresu)/ 
 
Natomiast prawidłowe jest : 
 
char *ptr_str; 
 
*ptr_str = ‘x’; 
 
  
 
wykorzystanie wska

ź

nika do przypisania mu ła

ń

cucha znaków 

 
// p_63 
 
# include <stdio.h># include <conio.h>void main(void){char 
str1[]={'S','t','a','ł','a',' ', 
'ł','a','

ń

','c','u','c','h','o','w','a','\0'};char 

str2[]="Druga stała ła

ń

cuchowa";char *ptr_str; 

 
int i; 
 
clrscr(); 
 
// wydruk str1 
 
for(i=0;str1[i];i++) // str1[i]=='\0' - synonim fałszu 
 
printf("%c",str1[i]); 
 

background image

 

84 

printf("\n"); 
 
// wydruk str2 
 
for(i=0;str2[i];i++) 
 
printf("%c",str2[i]); 
 
printf("\n"); 
 
// przypisanie ła

ń

cucha do wska

ź

nika 

 
ptr_str="Przypisanie ła

ń

cucha do wska

ź

nika"; 

 
for(i=0;*ptr_str;i++) à i jest zb

ę

dne 

 
printf("%c",*ptr_str++); 
 
getch(); 
 

 
Długo

ść

 ła

ń

cucha znaków 

 
Ile znaków zawiera ła

ń

cuch ? 

 
Funkcja strlen() 
 
#include <string.h> 
 
size_t strlen(const char *s) 
 
 
  
 
  
 
  
 
  
 
ilo

ś

c bajtów wska

ź

nik do ła

ń

cucha znaków 

 
zajmowanych przez /identyfikator ła

ń

cucha/ 

 
ła

ń

cuch 

 
  
 
  
 

background image

 

85 

//p_64 
 
# include <stdio.h># include <conio.h># include <string.h>void 
main(void){char str1[]={'S','t','a','ł','a',' ', 
 
'ł','a','

ń

','c','u','c','h','o','w','a','\0'}; 

 
char str2[]="Druga stała ła

ń

cuchowa"; 

 
char *ptr_str="Przypisanie ła

ń

cucha do wska

ź

nika"; 

 
clrscr(); 
 
printf("Długo

ść

 str1 wynosi: %d bajt˘w\n",strlen(str1)); 

 
printf("Długo

ść

 str2 wynosi: %d bajt˘w\n",strlen(str2)); 

 
printf("Długo

ść

 ła

ń

cucha przypisanego wska

ź

nikowi: %d 

bajt˘w\n",strlen(ptr_str)); 
 
getch(); 
 

 
  
 
  
 
Kopiowanie ła

ń

cuchów – strcpy() 

 
  
 
#include <string.h> 
 
char *strcpy(char *dest, const char *src); 
 
src à dest 
 
kopiowanie ła

ń

cuchów bez u

ż

ycia wska

ź

ników 

 
// p_65 
 
# include <stdio.h># include <conio.h># include <string.h>void 
main(void) 
 

 
char str1[]="Kopiowanie ła

ń

cuchów"; 

 
char str2[25]; 
 

background image

 

86 

char str3[25]; 
 
int i; 
 
clrscr(); 
 
// kopiowanie przy pomocy strcpy() 
 
strcpy(str2,str1); 
 
// kopiowanie bez uzycia strcpy() 
 
for(i=0;str1[i];i++) 
 
str3[i]=str1[i]; 
 
str3[i]='\0'; 
 
printf("Zawarto

ść

 str2 : %s\n",str2); 

 
printf("Zawarto

ść

 str3 : %s\n",str3); 

 
getch(); 
 

 
kopiowanie ła

ń

cuchów z wykorzystaniem wska

ź

ników 

 
// p_65p 
 
# include <stdio.h># include <conio.h># include <string.h>void 
main(void){char str1[]="Kopiowanie ła

ń

cuchów"; 

 
char str2[25]; 
 
char str3[25]; 
 
int i; 
 
clrscr(); 
 
// kopiowanie przy pomocy strcpy() 
 
strcpy(str2,str1); 
 
// kopiowanie bez uzycia strcpy() 
 
for(i=0;*(str1+i);i++) 
 
*(str3+i)=*(str1+i); 
 

background image

 

87 

*(str3+i)='\0'; 
 
printf("Zawarto

ść

 str2 : %s\n",str2); 

 
printf("Zawarto

ść

 str3 : %s\n",str3); 

 
getch(); 
 

 
  
 
Odczyt i zapis ła

ń

cuchów znakowych 

 
gets() - odczyt ła

ń

cuchów tekstowych ze standardowego 

strumienia wej

ś

ciowego stdin 

 
#include <stdio.h> 
 
char *gets(char *s); 
 
s – identyfikator tablicy znakowej, w której przechowywane s

ą

 

znaki wczytane ze standardowego wej

ś

cia; 

 
gets() ko

ń

czy swoje działanie po wczytaniu ze standardowego 

wej

ś

cia znaku przej

ś

cia do nast

ę

pnej linii (naci

ś

ni

ę

cie 

Entera), albo po wczytaniu EOF – (koniec pliku) . Funkcja 
dodaje do tablicy znakowej znacznik ‘\0’ i zwraca wska

ź

nik do 

tablicy s, do której zapisała znaki, lub wska

ź

nik pusty je

ś

li 

operacja nie powiodła si

ę

 
puts() - zapis ł

ąń

cuchów tekstowych do standardowego 

strumienia wyj

ś

ciowego stdout 

 
#include <stdio.h> 
 
char puts(const char *s) 
 
s – tablica (lub wska

ź

nik) odwołuj

ą

ca si

ę

 do ła

ń

cucha 

znakowego, który ma zosta

ć

 wysłany do standardowego strumienia 

(urz

ą

dzenia) wyj

ś

ciowego. 

 
Funkcja puts() likwiduje znacznik ko

ń

ca ła

ń

cucha tekstowego, 

dodaj

ą

c w jego miejsce znak przej

ś

cia do nowego wiersza. 

 
  
 
  
 
we wprowadzonym tek

ś

cie zamiana małych liter na du

ż

e – bez 

wska

ź

ników 

background image

 

88 

 
//p_66 
 
# include <stdio.h># include <conio.h># include <string.h>void 
main(void){char str[80];int i;clrscr(); printf("Wprowad

ź

 

ła

ń

cuch do max. 80 znaków\n"); 

 
gets(str); 
 
i=0; 
 
while(str[i]) 
 

 
if((str[i]>=97)&&(str[i]<=122)) 
 
str[i]-=32; 
 
i++; 
 

 
printf("Wprowadzony tekst po zamianie małych liter na du

ż

\n"); 
 
puts(str); 
 
getch(); 
 

 
  
 
we wprowadzonym tek

ś

cie zamiana małych liter na du

ż

e – ze 

wska

ź

nikami 

 
//p_66p 
 
  
 
# include <stdio.h> 
 
# include <conio.h> 
 
# include <string.h> 
 
void main(void) 
 

 

background image

 

89 

char str[80]; 
 
int i; 
 
clrscr(); 
 
printf("Wprowad

ź

 ła

ń

cuch do max. 80 znak˘w\n"); 

 
gets(str); 
 
i=0; 
 
while(*(str+i)) 
 

 
if((*(str+i)>=97)&&(*(str+i)<=122)) 
 
*(str+i)-=32; 
 
i++; 
 

 
printf("Wprowadzony tekst po zamianie małych liter na du

ż

\n"); 
 
puts(str); 
 
getch(); 
 

 
  
 
  
 
Specyfikator %s w funkcji printf() à wydrukowanie na ekranie 
ła

ń

cucha znakowego. 

 
  
 
Funkcja scanf() 
 
Podobnie jak printf() funkcja scanf() słu

ż

y do wczytywania 

danych ró

ż

nego typu. 

 
# include <stdio.h> 
 
int scanf(const char *format,[adres,......]); 
 

background image

 

90 

w ła

ń

cuchu formatuj

ą

cym mog

ą

 znale

źć

 si

ę

 wszystkie 

specyfikatory formatu, w tym %s. Je

ż

eli działanie funkcji 

scanf() jest poprawne funkcja zwraca liczb

ę

 wczytanych 

elementów (nie bajtów), ze strumienia stdin.  
 
W przypadku bł

ę

du zwraca EOF. 

 
U

ż

ycie specyfikatora formatu %s nakazuje funkcji scanf() 

wczyta

ć

 dane ze standardowego wej

ś

cia traktuj

ą

c je jako 

ła

ń

cuch znaków. Wczytywanie danych przez funkcje scanf() 

zostaje zako

ń

czone je

ż

eli w strumieniu znaków wej

ś

ciowych 

pojawi si

ę

 jeden z nastepuj

ą

cych znaków : spacja, znak nowego 

wiersza, tabulator, tabulacja pionowa, FF – znak ko

ń

ca strony. 

Znaki wczytywane przez funkcj

ę

 s

ą

 przechowywane w tablicy 

znakowej, która musi zosta

ć

 wskazana funkcji jako jej 

argument. Tablica powinna by

ć

 wystarczaj

ą

co du

ż

a aby pomie

ś

ci

ć

 

wszystkie wczytane znaki. 
 
Po zako

ń

czeniu wczytania ła

ń

cucha znaków jako ostatni element 

tablicy znakowej zostaje automatyczne dodany znacznik ‘\0’. 
 
  
 
//p_67 
 
# include <stdio.h># include <conio.h># include <string.h>void 
main(void) 
 

 
char str[80]; 
 
int i; 
 
clrscr(); 
 
printf("Wprowad

ź

 ła

ń

cuch do max. 80 znak˘w\n"); 

 
gets(str); 
 
i=0; 
 
while(str[i]) 
 

 
if((str[i]>=97)&&(str[i]<=122)) 
 
str[i]-=32; 
 
i++; 

background image

 

91 

 

 
printf("Wprowadzony tekst po zamianie małych liter na du

ż

\n"); 
 
puts(str); 
 
printf("\n%s",str); 
 
getch(); 
 

 
  
 
  
 
//p_68 
 
# include <stdio.h># include <conio.h># include <string.h> 
 
void main(void){char str[80];int i;clrscr(); printf("Wprowad

ź

 

ła

ń

cuch do max. 80 znak˘w\n");// gets(str); 

 
scanf("%s",&str); 
 
i=0; 
 
while(str[i]) 
 

 
if((str[i]>=97)&&(str[i]<=122)) 
 
str[i]-=32; 
 
i++; 
 

 
printf("Wprowadzony tekst po zamianie małych liter na du

ż

\n"); 
 
puts(str); 
 
printf("\n%s",str); 
 
getch(); 
 

background image

 

92 

 
  
 
//p_69 
 
  
 
# include <stdio.h># include <conio.h> 
 
# include <string.h> 
 
void main(void) 
 

 
char str[80]; 
 
int x,y; 
 
float z; 
 
clrscr(); 
 
printf("Po wpisaniu danych dowolnego typu naci

ś

nij 

<Enter>\n"); 
 
printf("Wpisz dwie liczby całkowite:\n"); 
 
scanf("%d %d",&x,&y); 
 
printf("Wpisz liczb

ę

 zmiennoprzecinkow

ą

: \n"); 

 
scanf("%f",&z); 
 
printf("Wpisz ła

ń

cuch znaków: \n"); 

 
scanf("%s",str); 
 
printf("Wpisałe

ś

 nast

ę

puj

ą

ce dane: \n"); 

 
printf("%d %d\n%f\n%s\n",x,y,z,str); 
 
getch(); 
 

 
Po napotkaniu spacji wczytywanie znaków funkcja scanf() 
zostaje przerwane. 
 

background image

 

93 

Funkcja scanf nie wczytuje znaków z wej

ś

cia dopóki nie 

zostanie naci

ś

niety klawisz ENTER ( do tego czasu znaki 

znajduj

ą

 si

ę

 w buforze wej

ś

ciowym ). 

 
  
 
  
 
Widoczno

ść

 zmiennych 

 
 
W zło

ż

onym programie mog

ą

 by

ć

 zmienne, z których korzystaj

ą

 

ż

ne funkcje, a z drugiej strony u

ż

ycie niektórych zmiennych 

mo

ż

e ogranicza

ć

 si

ę

 tylko do pojedynczych funkcji. Oznacza to 

ż

e widoczno

ść

 i dost

ę

pno

ść

 tych zmiennych mo

ż

e by

ć

 

ograniczona, a warto

ś

ci przypisane tym zmiennym mog

ą

 by

ć

 

ukryte z punktu widzenia innych funkcji. 
 
W j

ę

zyku C mo

ż

na deklaruj

ą

c zmienn

ą

 okre

ś

li

ć

 zakres jej 

dost

ę

pno

ś

ci i widoczno

ś

ci. Zmienne dost

ę

pne tylko lokalnie s

ą

 

dost

ę

pne tylko wewn

ą

trz tego bloku programu , w którym zostały 

zadeklarowane. 
 
Zmienne lokalne /blokowe/ 
 
Zmienna zadeklarowana wewnatrz bloku programu ma zasi

ę

blokowy. Jest ona dostepna od miejsca zadeklarowania do ko

ń

ca 

bloku w którym zastała zadeklarowana. Takie zmienne nazywaj

ą

 

si

ę

 lokalnymi lub blokowymi. 

 
  
 
//p_70 
 
# include <stdio.h># include <conio.h># include <string.h> 
 
void main(void) 
 

 
int i=32; 
 
clrscr(); 
 
printf("W bloku zewnetrznym i=%d\n",i); 
 

 
int i,j; 
 
printf("W bloku wewn

ę

trznym \n"); 

background image

 

94 

 
for (i=0,j=10;i<=10;i++,j--) 
 
printf("i=%2d, j=%2d\n",i,j); 
 

 
printf("Znowu w bloku zewn

ę

trznym: i=%d\n",i); 

 
getch(); 
 

 
P

ę

tla for modyfikuje i wyprowadza warto

ś

ci zmiennych lokalnych 

bloku wewn

ę

trznego, jednak

ż

e po zako

ń

czeniu i wyj

ś

ciu z tego 

bloku lokalna zmienna i (wewn

ę

trzna) przestaje by

ć

 dost

ę

pna. 

Ponownie widoczna jest zewn

ę

trzna zmienna i, która nie uległa 

zmianie. Dzi

ę

ki umiej

ę

tno

ś

ci ograniczania zakresu dost

ę

pno

ś

ci 

zmiennych , nie nast

ą

piło ani nadpisanie warto

ś

ci ani 

konflikt. 
 
Zmienne widoczne w obr

ę

bie funkcji 

 
Zmienne wewn

ę

trzne funkcji to takie zmienne, które s

ą

 dost

ę

pne 

i aktywne tylko pomi

ę

dzy pocz

ą

tkiem a ko

ń

cem danej funkcji.  

 
W j

ę

zyku C tylko goto label ma taki zasi

ę

g. Je

ż

eli etykieta 

przyporz

ą

dkowana instrukcji goto jako docelowy adres skoku 

b

ę

dzie nazywa

ć

 si

ę

 start, to w obrebie funkcji main() jest 

widoczna i dostepna z dowolnego punktu, czyli jej adres 
widoczno

ś

ci to cała funkcja 

 
int main() 
 

 
int i; 
 
.... 
 
start: 
 
..... 
 
goto start; 
 
..... 
 
return 0; 
 

background image

 

95 

 
Etykieta start jest widoczna od poczatku do konca funkcji 
main(), dlatego w obr

ę

bie funkcji main() nie mo

ż

e wystapi

ć

 

druga etykieta o nazwie start: (natomiast zmienne i mog

ą

 

wyst

ę

powa

ć

 lokalnie wewn

ą

trz zagnie

ż

d

ż

onych bloków). 

 
  
 
Zmienne widoczne w całym programie 
 
Je

ż

eli zmienna została zadeklarowana przed funkcj

ą

 main() to 

jej zasi

ę

giem widoczno

ś

ci jest cały program. Zmienne takie 

nazywaj

ą

 si

ę

 zmiennymi globalnymi. 

 
  
 
int a = 0; 
 
float b = 2.0; 
 
int main() 
 

 
int i; 
 
return 0; 
 

 
//p_71 
 
# include <stdio.h># include <conio.h># include <string.h>// 
deklaracje zmiennych globalnychint x=1234;double 
y=1.234567;void fun_1(){ printf("Wewn

ą

trz funkcji \n x=%d, 

y=%f\n",x,y); 
 

 
void main(void) 
 

 
int x=4321; 
 
clrscr(); 
 
fun_1(); 
 
printf("Blok główny funkcji main() \n x=%d, y=%f\n",x,y); 
 

background image

 

96 


 
double y=7.654321; 
 
fun_1(); 
 
printf("Blok zagnie

ż

dzony funkcji main() \n x=%d, 

y=%f\n",x,y); 
 

 
getch(); 
 

 
Z wn

ę

trza funkcji widoczne s

ą

 zmienne globalne. 

 
Deklaracja lokalnej zmiennej x przysłania zmienn

ą

 globalna w 

obr

ę

bie bloku funkcji. 

 
  
 
  
 
Specyfikatory i modyfikatory klasy pami

ę

ci 

 
W j

ę

zyku C s

ą

 cztery specyfikatory i dwa modyfikatory, które 

mog

ą

 by

ć

 u

ż

ywane do okre

ś

lania czasu 

ż

ycia zmiennej. 

 
Specyfikator auto 
 
Specyfikator auto okre

ś

la, 

ż

e lokalizacja zmiennej w pami

ę

ci 

jest tymczasowa tzn. kiedy zmienna przestanie by

ć

 widoczna i 

dost

ę

pna w programie, zmienna mo

ż

e zosta

ć

 przemieszczona w 

inne miejsce w programie albo skasowana. 
 
 
Tylko zmienne o lokalnym zakresie dost

ę

pno

ś

ci mog

ą

 by

ć

 

deklarowane jako zmienne auto. Auto jest rzadko u

ż

ywanym 

słowem kluczowym, poniewa

ż

 zmienne o blokowym zakresie 

dostepno

ś

ci, s

ą

 w sposób domy

ś

lny traktowane jako tymczasowe 

(auto). 
 
 
  
 
Specyfikator static 
 
Specyfikator static (zmienna statyczna) mo

ż

e by

ć

 stosowany 

wobec zmiennych dost

ę

pnych w zakresie bloku lub w zakresie 

programu. Je

ż

eli zmienna wewn

ą

trz funkcji zostanie 

background image

 

97 

zadeklarowana jako statyczna istnieje ona w sposób ci

ą

gły w 

czasie. Miejsce w pami

ę

ci przeznaczona dla przechowywania tej 

zmiennej nie podlega likwidacji, gdy zmienna ta wyjdzie poza 
zakres swojej widoczno

ś

ci (warto

ść

 zmiennej jest przechowywana 

dalej pod tym samym adresem, mimo 

ż

e jest niewidoczna). Po 

powrocie przez program do zakresu widoczno

ś

ci zmiennej nadal 

znajduje si

ę

 tam jej ostatnio zapisana warto

ść

 
//p_72 
 
# include <stdio.h># include <conio.h>int sumuj(int x,int 
y){static int licznik=1;printf("Wywołanie funkcji, stan 
licznika : %d, \n",licznik++); 
 
return(x+y); 
 

 
int main(void) 
 

 
int i,j; 
 
clrscr(); 
 
for(i=0,j=5;i<5;i++,j--) 
 
printf("dodawanie liczb: %d oraz %d suma: %d. 
\n",i,j,sumuj(i,j)); 
 
getch(); 
 

 
//p_73 
 
# include <stdio.h># include <conio.h>int sumuj(int x,int 
y){int licznik=1; 
 
printf("Wywołanie funkcji, stan licznika : %d, \n",licznik++); 
 
return(x+y); 
 

 
int main(void) 
 

 
int i,j; 

background image

 

98 

 
clrscr(); 
 
for(i=0,j=5;i<5;i++,j--) 
 
printf("dodawanie liczb: %d oraz %d suma: %d. 
\n",i,j,sumuj(i,j)); 
 
getch(); 
 

 
//p_74 
 
# include <stdio.h> 
 
# include <conio.h> 
 
int sumuj(int x,int y) 
 

 
static int licznik=1; 
 
printf("Wywołanie funkcji, stan licznika : %d, \n",++licznik); 
 
return(x+y); 
 

 
int main(void) 
 

 
int i,j; 
 
clrscr(); 
 
for(i=0,j=5;i<5;i++,j--) 
 
printf("dodawanie liczb: %d oraz %d suma: %d. 
\n",i,j,sumuj(i,j)); 
 
getch(); 
 

 
  
 
  
 

background image

 

99 

  
 
Zakresy dost

ę

pno

ś

ci : 

 
zasi

ę

g blokowy 

zasi

ę

g w obr

ę

bie funkcji 

zasi

ę

g w obr

ę

bie programu 

zasi

ę

g w obrebie pliku 

 
W j

ę

zyku C zmienna globalna zadeklarowana jako static jest 

nazywana zmienn

ą

 o zasi

ę

gu obejmuj

ą

cym cały plik. Jest ona 

dost

ę

pna od punktu zadeklarowania a

ż

 do ko

ń

ca pliku. Słowo 

plik oznacza 

ź

ródłowy plik programu, czyli plik tekstowy 

zawieraj

ą

cy tekst programu. ( Wi

ę

kszo

ść

 du

ż

ych programów 

składa si

ę

 z wielu plików 

ź

ródłowych) 

 
 
int x = 0; 
 
static int y = 0; 
 
static float z = 0.0; 
 
int main() 
 

 
int i; 
 
... 
 
... 
 
return 0; 
 

 
  
 
Zasi

ę

g programu --------------------à  

 
Zasi

ę

g pliku --------------à  

 
Zasi

ę

g funkcji --------à  

 
Zasi

ę

g blokowy -----à  

 
  
 
Specyfikator register 
 

background image

 

100 

Ka

ż

dy komputer ma pewn

ą

 ilo

ść

 rejestrów do przechowywania 

danych i wykonywania operacji arytmetycznych i logicznych. 
Poniewa

ż

 rejestry s

ą

 umieszczone w pami

ę

ci procesora zatem 

dost

ę

p do nich jest du

ż

o szybszy ni

ż

 do pami

ę

ci RAM gdzie 

znajduj

ą

 si

ę

 zmienne programu. Aby przy

ś

pieszy

ć

 dost

ę

p do 

pewnych zmiennych mo

ż

emy je umie

ś

ci

ć

 bezpo

ś

rednio w pami

ę

ci 

procesora, czyli w rejestrze. 
 
 
Kompilator mo

ż

e zignorowa

ć

 tak

ą

 sugesti

ę

, je

ż

eli nie ma 

dostepnego rejestru, b

ą

d

ź

 inne ograniczenia uniemo

ż

liwiaj

ą

 mu 

takie postepowanie. 
 
 
Pobranie adresu zmiennej zadeklarowanej jako rejestrowa jest 
nielegalne. 
 
 
int main() 
 

 
register int i; 
 
for (i=0;i<max;i++) 
 

 
...... 
 

 
return 0; 
 

 
Specyfikator extern 
 
Zmienna globalna widoczna jest we wszystkich plikach 

ź

ródłowych tworz

ą

cych program. Jak zmienna zadeklarowana jako 

globalna w jednym pliku dyskowym (A) mo

ż

e by

ć

 widoczna i 

dost

ę

pna w innym pliku dyskowym (B). Sk

ą

d kompilator ma 

wiedzie

ć

ż

e w pliku B chodzi o t

ę

 sam

ą

 zmienn

ą

, która została 

zadeklarowana jako globalna w pliku A. 
 
 
Aby w pliku B odwoła

ć

 si

ę

 do zmiennych globalnych 

zadeklarowanych w A, nale

ż

y w pliku B zadeklarowa

ć

 te zmienne 

jako zmienne zewn

ę

trzne, u

ż

ywaj

ą

c specyfikatora extern. 

 
plik A 

background image

 

101 

 
int a,b; 
 
int main() 
 

 
return 0; 
 

 
  
 
plik B 
 
int c; 
 
extern int a; 
 
int main() 
 

 
extern int b; 
 
int i; 
 
return 0; 
 

 
Zasady deklarowania i odwoływania si

ę

 do zmiennych 

zewn

ę

trznych : 

 
Deklaruj

ą

c zmienna globaln

ą

pomin

ąć

 słowo extern 

zainicjowa

ć

 zmienn

ą

 przy deklaracji 

 
Kiedy w innym pliku odwołujemy si

ę

 do tej zmiennej: 

u

ż

y

ć

 słowa extern 

nie inicjowa

ć

 zmiennej w deklaracji 

 
  
 
Modyfikatory sposobów odwoływania si

ę

 do zmiennych. 

 
Modyfikator const 
 
Je

ż

eli zmienna zostanie zadeklarowana z u

ż

yciem modyfikatora 

const, po jednorazowym zainicjowaniu jej warto

ść

 nie mo

ż

zosta

ć

 zmieniona. 

background image

 

102 

 
const double pi = 3.141593; 
 
const char str[ ] = ”Tablica znakowa”; 
 
str[0] = ‘x’; à bł

ą

 
Modyfikator volatile - dane ulotne 
 
Zmienn

ą

 której warto

ść

 mo

ż

e by

ć

 zmieniana w trakcie programu 

bez stosowania operacji przypisania nale

ż

y zadeklarowa

ć

 jako 

ulotn

ą

 – volatile. 

 
Mo

ż

na np. zadeklarowa

ć

 zmienn

ą

 globalna do zapami

ę

tania znaku 

wprowadzanego przez uzytkownika z klawiatury. W procesie 
optymalizacji kodu kompilator mo

ż

e t

ą

 zmienna potraktowa

ć

 tak 

jak inne zmienne , których warto

ś

ci ustalane s

ą

 operacjami 

podstawienia. Zadeklarowanie jej jako ulotn

ą

 zabezpieczy j

ą

 

przed tym procesem i jej zmiana warto

ś

ci b

ę

dzie mo

ż

liwa 

jedenie poprzez wprowadzenie nowego znaku z klawiatury. 
 
void read_keyboard() 
 

 
volatile char keyboard_ch; 
 
....... 
 

 
  
 
Funkcje 
 
 
Deklaracja a definicja funkcji 
 
Deklaracja zmiennej lub funkcji okre

ś

la interpretacj

ę

 i 

atrybuty zestawu identyfikatorów; 
 
 
Definicja wymaga od kompilatora zarezerwowania pami

ę

ci dla 

zmiennej lub funkcji okre

ś

lonej danym identyfikatorem; 

 
 
Deklaracja zmiennej jest jej definicj

ą

 
Deklaracja funkcji nie stanowi jej definicji. Deklaracja 
funkcji odwołuje si

ę

 do jej definicji (znajduj

ą

cej si

ę

 w innym 

background image

 

103 

miejscu), okre

ś

la natomiast jakiego typu warto

ść

 zostanie 

zwrócona przez funkcj

ę

 
 
Definicja funkcji okre

ś

la co ta funkcja robi, podaj

ą

jednocze

ś

nie liczb

ę

 i typy argumentów przekazywanych do 

funkcji. 
 
Zadeklarowanie funkcji nie jest równoznaczne z jej definicj

ą

Je

ż

eli definicja funkcji jest umieszczona przed miejscem 

pierwszego wywołania funkcji, to nie musimy funkcji wcze

ś

niej 

deklarowa

ć

. W przeciwnym razie musimy przed pierwszym 

wywołaniem funkcji umie

ś

ci

ć

 jej deklaracj

ę

 
 
Typ warto

ś

ci zwracanej przez funkcj

ę

 
Funkcja mo

ż

e by

ć

 zadeklarowana i zwraca

ć

 dane dowolnego typu 

(za wyj

ą

tkiem tablicy i funkcji). Instrukcja return z 

definicji funkcji zwraca jedn

ą

 warto

ść

, którejm typ powinien 

by

ć

 zgodny z typem zadeklarowanym przed nazw

ą

 funkcji. 

 
Domy

ś

lnym typem jest typ int. 

 
 
specyfikator_typu_danych nazwa_funkcji(); 
 
  
 
Prototyp funkcji 
 
Deklaracja funkcji zawiera tak

ż

e liczb

ę

 i typy argumentów 

przekazywanych do funkcji. 
 
Liczba i typ argumentów funkcji nazywa si

ę

 prototypem funkcji. 

 
 
  
 
Ogólna forma deklaracji: 
 
spec_typu_danych nazwa_funkcji ( spec_typ_danych argument1, 
 
spec_typ_danych argument2, 
 
spec_typ_danych argument3, 
 
..................................................); 
 
nazwy : argument1, argument2 itd. s

ą

 opcjonalne 

 

background image

 

104 

Wywołanie funkcji 
 
Po wywołaniu funkcji wykonanie programu przenosi si

ę

 do kodu 

funkcji, a

ż

 do zako

ń

czenia jego wykonania. Po powrocie z 

funkcji i ewentualnym zwrocie warto

ś

ci , wykonanie programu 

jest podejmowane pocz

ą

wszy od nastepnej intrukcji nastepuj

ą

cej 

po wywołaniu funkcji. 
 
Wywołanie funkcji to wyra

ż

enie, które mo

ż

e by

ć

 u

ż

ywane jako 

samodzielna instrukcja, lub jako element wewn

ą

trz innych 

wyra

ż

e

ń

 
//p_75 
 
# include <stdio.h># include <conio.h>int funkcja1(int x,int 
y);double funkcja2(double x,double y){printf("Jeste

ś

my w 

funkcji2\n");return (x-y);}void main(void){int x1=80;int 
y1=10;double x2=100.123456; 
 
double y2=10.123456; 
 
clrscr(); 
 
printf("Wywołanie funkcja1(%d,%d).\n",x1,y1); 
 
printf("Funkcja1 zwraca : %d. \n",funkcja1(x1,y1)); 
 
printf("Wywołanie funkcja2(%f,%f).\n",x2,y2); 
 
printf("Funkcja2 zwraca : %f.\n",funkcja2(x2,y2)); 
 
getch(); 
 

 
int funkcja1(int x,int y) 
 

 
printf("Jeste

ś

my w funkcji1.\n"); 

 
return(x+y); 
 

 
  
 
  
 
  
 

background image

 

105 

  
 
Prototypy funkcji : 
 
1/ Funkcja przy wywołaniu nie pobiera 

ż

adnych argumentów –  

 
bezargumantowa; 
 
2/ Funkcja pobiera stał

ą

 okre

ś

lon

ą

 liczb

ę

 argumentów; 

 
3/ Funkcja pobiera zmienn

ą

 liczb

ę

 argumentów; 

 
  
 
Funkcje bezargumentowe 
 
int c; 
 
c = getchar(); 
 
deklaracja: int getchar(void); 
 
Dla wszystkich funkcji bezargumentowych w ich deklaracji 
(prototypie) stosowany jest typ danych void. 
 
 
//p_76 
 
#include <stdio.h>#include <conio.h>#include <time.h>void 
data_czas(void);main(){ printf("Przed wywołaniem \n"); 
data_czas(); printf("Po wywołaniu \n"); return 0;}void 
data_czas(void){time_t t; printf("Wewn

ą

trz funkcji data_czas() 

\n"); 
 
time(&t); 
 
printf("Aktualna data i czas : %s",asctime(localtime(&t))); 
 
getch(); 
 

 
  
 
Funkcja data_czas() wykorzystuje zmienna t typu time_t i 
posługuje si

ę

 funkcjami bibliotecznymi zadeklarowanymi w pliku 

nagłówkowym time.h tj. time(), localtime(), asctime(); 
 
Funkcje czasowe daj

ą

 nam 3 rodzaje czasów : 

 

background image

 

106 

1/ czas kalendarzowy – czas bie

żą

cy w oparciu o kalendarz 

gregoria

ń

ski 

 
2/ czas lokalny – czas kalendarzowy w okre

ś

lonej strefie 

czasowej 
 
3/ czas zimowy/letni – czas strefowy z uwzgl

ę

dnieniem 

przesuni

ę

cia zimowego/letniego. 

 
  
 
Funkcja time() zwraca czas kalendarzowy 
 
#include <time.h> 
 
time_t time(time_t *timer); 
 
time_t - tzw. typ arytmetyczny, stosowany da zapisu czasu 
 
timer - zmienna typu wska

ź

nik wskazuj

ą

ca miejsce w pami

ę

ci, w 

którym powinny zosta

ć

 zapisane dane dotycz

ą

ce daty i czasu 

zwracane przez funkcje; 
 
Je

ż

eli dane dotycz

ą

ce czasu kalendarzowego s

ą

 niemo

ż

liwe do 

odczytania na danym komputerze to funkcja zwraca –1. 
 
  
 
Funkcja localtime() zwraca czas lokalny po przekształceniu 
czasu kalendarzowego 
 
#include <time.h> 
 
struct tm *localtime(const time_t *timer); 
 
tm - struktura danych, zawieraj

ą

ca składniki czasu 

kalendarzowego 
 
timer - wska

ź

nik do adresu pami

ę

ci, gdzie przechowywany jest 

czas kalendarzowy zwrócony wcze

ś

niej przez funkcje time(); 

 
aby przekształci

ć

 dane dotycz

ą

ce daty i czasu w strukturze tm 

w ła

ń

cuch znaków nale

ż

y wywoła

ć

 funkcje asctime(); 

 
#include <time.h> 
 
char *acstime(const strunct tm *timeptr) 
 
timeprt - wska

ź

nik odwołuj

ą

cy si

ę

 do struktury tm zwróconej 

przez funkcje localtime(); 
 

background image

 

107 

  
 
Funkcje o stałej liczbie argumentów 
 
int function_1(int x, int y); 
 
Deklaruj

ą

c funkcj

ę

 o stałej liczbie argumentów, nale

ż

y poda

ć

 

typy wszystkich argumentów (zalecane jest równie

ż

 podanie ich 

nazw); 
 
  
 
Funkcje o zmiennej liczbie argumentów 
 
np. printf() 
 
int printf(const char *format , argument1,argument2,.....); 
 
wielokropek jest oznaczeniem dla kompilatora C , 

ż

e ilo

ść

 

argumentów funkcji mo

ż

e by

ć

 zmienna; 

 
typ_danych nazwa_funkcji(typ_danych arg1,...); 
 
wielokropek oznacza tu pozastałe argumenty, które nie zostały 
wymienione na li

ś

cie argumentów; 

 
printf(const char * format,...); 
 
W pliku stdarg.h zadeklarowane zostały trzy podprogramy, które 
pozwalaj

ą

 na tworzenie i obsług

ę

 funkcji o zmiennej liczbie 

argumentów : 
 
 
va_start() 
 
va_arg() 
 
va_end() 
 
Aby zainicjowa

ć

 tablic

ę

, która jest niezb

ę

dna do działania 

makrorozkazów va_arg() oraz va_end() nale

ż

y zawsze najpierw 

wywoła

ć

 makro va_start(). 

 
Plik nagłówkowy stdarg.h zawiera tak

ż

e typ danych va_list, 

który okre

ś

la typ tablicy odpowiedni do przechowywania danych 

potrzebnych do działania makropolece

ń

 va_start() , va_arg() , 

va_end() . 
 
 
#include <stdarg.h> 
 

background image

 

108 

void va_start(va_list tab, lastfix); 
 
tab - inicjowana tym poleceniem tablica 
 
lastfix - okre

ś

la ostatni argument funkcji przed wielokropkiem 

w  
 
deklaracji 
 
Poprzez u

ż

ycie makropolecenia va_arg() mo

ż

na obsługiwa

ć

 

wyra

ż

enia okre

ś

lajace typ i warto

ść

 nastepnego argumentu 

funkcji. Makro va_arg() mo

ż

e by

ć

 u

ż

yte do pobrania kolejnego 

argumentu przekazywanego do funkcji, 
 
#include <stdarg.h> 
 
typ_danych va_arg()(va_list tab, typ_danych); 
 
tab - tablica zainicjowana w momencie działania makra 
va_start() 
 
typ_danych - typ danych argumentu przesłanego do funkcji 
 
Aby zapewni

ć

 normalny i poprawny zwrot warto

ś

ci przez funkcj

ę

 

o zmiennej liczbie argumentów, nale

ż

y zastosowa

ć

 makro 

va_end(), po tym jak wszystkie argumenty zostan

ą

 przetworzone. 

 
#include (stdarg.h> 
 
void va_end(va_list tab); 
 
//p_76_0 
 
/* Funkcja ze zmienn

ą

 liczb

ą

 argumentów */#include 

<stdio.h>#include <stdarg.h>double AddDouble(int x, ...);main 
(){ double d1 = 1.5; double d2 = 2.5; double d3 = 3.5; double 
d4 = 4.5;  
 
printf("Wprowadzony argument: %2.1f\n", d1); 
 
printf("Wynik zwrócony przez AddDouble() jest: %2.1f\n\n", 
 
AddDouble(1, d1)); 
 
printf("Wprowadzone argumenty: %2.1f and %2.1f\n", d1, d2); 
 
printf("Wynik zwrócony przez AddDouble() jest: %2.1f\n\n", 
 
AddDouble(2, d1, d2)); 
 

background image

 

109 

printf("Wprowadzone argumenty: %2.1f, %2.1f and %2.1f\n", d1, 
d2, d3); 
 
printf("Wynik zwrócony przez AddDouble() jest: %2.1f\n\n", 
 
AddDouble(3, d1, d2, d3)); 
 
printf("Wprowadzone argumenty: %2.1f, %2.1f, %2.1f, and 
%2.1f\n", d1, d2, d3, d4); 
 
printf("Wynik zwrócony przez AddDouble() jest: %2.1f\n", 
 
AddDouble(4, d1, d2, d3, d4)); 
 
return 0; 
 

 
double AddDouble(int x, ...) 
 

 
va_list arglist;  
 
int i; 
 
double result = 0.0; 
 
printf("Liczba argumentów jest: %d\n", x); 
 
va_start (arglist, x);  
 
for (i=0; i<x; i++) 
 
result += va_arg(arglist, double); 
 
va_end (arglist); 
 
return result; 
 

 
  
 
  
 
Zastosowania wska

ź

ników 

 
  
 
  

background image

 

110 

 
Arytmetyka wska

ź

ników 

 
Skalarny wymiar wska

ź

nika 

 
spec_typu_danych *nazwa_wsk; 
 
nazwa_wsk + n  
 
oznacza w bajtach 
 
nazwa_wsk + n * sizeof(spec_typu_danych); 
 
  
 
//p_76_1 
 
/* arytmetyka wska

ź

ników */ 

 
#include <stdio.h> 
 
#include <conio.h> 
 
main() 
 

 
char *ptr_ch; 
 
int *ptr_int; 
 
double *ptr_db; 
 
clrscr(); 
 
/* char wsk. ptr_ch */ 
 
printf("Warto

ść

 ptr_ch: 0x%p\n", ptr_ch); 

 
printf(" ptr_ch + 1: 0x%p\n", ptr_ch + 1); 
 
printf(" ptr_ch + 2: 0x%p\n", ptr_ch + 2); 
 
printf(" ptr_ch - 1: 0x%p\n", ptr_ch - 1); 
 
printf(" ptr_ch - 2: 0x%p\n", ptr_ch - 2); 
 
/* int wsk. ptr_int */ 
 
printf("Warto

ść

 ptr_int: 0x%p\n", ptr_int); 

 

background image

 

111 

printf(" ptr_int + 1: 0x%p\n", ptr_int + 1); 
 
printf(" ptr_int + 2: 0x%p\n", ptr_int + 2); 
 
printf(" ptr_int - 1: 0x%p\n", ptr_int - 1); 
 
printf(" ptr_int - 2: 0x%p\n", ptr_int - 2); 
 
/* double wsk ptr_db */ 
 
printf("Warto

ść

 ptr_db: 0x%p\n", ptr_db); 

 
printf(" ptr_db + 1: 0x%p\n", ptr_db + 1); 
 
printf(" ptr_db + 2: 0x%p\n", ptr_db + 2); 
 
printf(" ptr_db - 1: 0x%p\n", ptr_db - 1); 
 
printf(" ptr_db - 2: 0x%p\n", ptr_db - 2); 
 
getch(); 
 
return 0; 
 

 
  
 
Odejmowanie wska

ź

ników 

 
typy odejmowanych wska

ź

ników musz

ą

 by

ć

 takie same; 

 
  
 
// p_76_2 
 
/* odejmowanie wska

ź

ników */ 

 
#include <stdio.h> 
 
#include <conio.h> 
 
main() 
 

 
int *ptr_int1, *ptr_int2; 
 
clrscr(); 
 
printf(" ptr_int1: 0x%p\n", ptr_int1); 

background image

 

112 

 
ptr_int2 = ptr_int1 + 5; 
 
printf(" ptr_int2 = ptr_int1 + 5: 0x%p\n", ptr_int2); 
 
printf(" ptr_int2 - ptr_int1: %d\n", ptr_int2 - ptr_int1); 
 
ptr_int2 = ptr_int1 - 5; 
 
printf(" ptr_int2 = ptr_int1 - 5: 0x%p\n", ptr_int2); 
 
printf(" ptr_int2 - ptr_int1: %d\n", ptr_int2 - ptr_int1); 
 
getch(); 
 
return 0; 
 

 
  
 
  
 
Dost

ę

p do tablic i elementów tablic za pomoc

ą

 wska

ź

ników: 

nazwa tablicy jest wska

ź

nikiem do jej 1 elementu; 

dodanie liczby całkowitej do nazwy tablicy jest dost

ę

pem do 

jej elementu o indeksie równym liczbie całkowitej 
 
  
 
  
 
// p_76_3 
 
/* dostep do tablic i elementów tablic za pomoc

ą

 wska

ź

ników */ 

 
#include <stdio.h> 
 
#include <conio.h> 
 
main() 
 

 
char str[] = "It's a string!"; 
 
char *ptr_str; 
 
int list[] = {1, 2, 3, 4, 5}; 
 
int *ptr_int; 

background image

 

113 

 
 
/* dost

ę

p do tablicy znaków */ 

 
clrscr(); 
 
ptr_str = str; 
 
printf("Przed zmian

ą

 str : %s\n", str); 

 
printf("Przed zmian

ą

 str[5] : %c\n", str[5]); 

 
*(ptr_str + 5) = 'A'; 
 
printf("Po zmianie, str[5] : %c\n", str[5]); 
 
printf("Po zmianie, str : %s\n", str); 
 
/* dostep do tablicy liczb */ 
 
ptr_int = list; 
 
printf("Przed zmian

ą

, list[2] : %d\n", list[2]); 

 
*(ptr_int + 2) = -3; 
 
printf("Po zmianie, list[2] : %d\n", list[2]); 
 
getch(); 
 
return 0; 
 

 
  
 
  
 
  
 
Przekazywanie tablicy jako argumentu do funkcji 
 
jest metoda na proste przekazanie wi

ę

kszej ilo

ś

ci argumentów 

do funkcji 
 
//p_76_4 
 
/* przekazywanie tablicy jako argumentu do funkcji */#include 
<stdio.h>#include <conio.h>int AddThree(int list[]);main(){ 
int sum, list[3]; clrscr(); printf("Wprowad« 3 liczby :\n"); 
 

background image

 

114 

scanf("%d%d%d", &list[0], &list[1], &list[2]); 
 
sum = AddThree(list);  
 
printf("Ich suma wynosi : %d\n", sum); 
 
getch(); 
 
return 0; 
 

 
int AddThree(int list[]) 
 

 
int i; 
 
int result = 0; 
 
 
for (i=0; i<3; i++) 
 
result += list[i]; 
 
return result; 
 

 
  
 
  
 
Przekazywanie wska

ź

ników jako argumentów do funkcji 

 
Nazwa tablicy po której nie nast

ę

puje indeks jest wska

ź

nikiem 

do pierwszego elementu. Zatem adres do pierwszego elementu 
tablicy b

ę

d

ą

cy wska

ź

nikiem mo

ż

e by

ć

 przekazany do funkcji tak 

jak tablica. 
 
//p_76_5 
 
/* przekazywanie wska

ź

ników jako argumentów do funkcji 

*/#include <stdio.h>#include <conio.h>void ChPrint(char 
*ch);int DataAdd(int *list, int max); 
 
main() 
 

 
char str[] = "It's a string!"; 

background image

 

115 

 
char *ptr_str; 
 
int list[5] = {1, 2, 3, 4, 5}; 
 
int *ptr_int; 
 
 
/* przypisanie adresu do wska

ź

nika */ 

 
clrscr(); 
 
ptr_str = str; 
 
ChPrint(ptr_str);  
 
ChPrint(str); 
 
/* przypisanie adresu do wska

ź

nika */ 

 
ptr_int = list; 
 
printf("The sum returned by DataAdd(): %d\n",  
 
DataAdd(ptr_int, 5)); 
 
printf("The sum returned by DataAdd(): %d\n",  
 
DataAdd(list, 5)); 
 
getch(); 
 
return 0; 
 

 
void ChPrint(char *ch) 
 

 
printf("%s\n", ch); 
 

 
int DataAdd(int *list, int max) 
 

 
int i; 
 
int sum = 0; 

background image

 

116 

 
 
for (i=0; i<max; i++) 
 
sum += list[i]; 
 
return sum; 
 

tablice znakowe i liczbowe przekazywane s

ą

 do funkcji 

wska

ź

nikiem 

 
poprzez: 
 
ptr = n_tablicy 
 
lub 
 
n_tablicy 
 
  
 
  
 
Przekazywanie tablic wielowymiarowych do funkcji 
 
Mo

ż

na przekaza

ć

 nazw

ę

 tablicy lub wska

ź

nik zawieraj

ą

cy adres 

startowy tablicy wielowymiarowej. 
 
//p_76_6 
 
/* przekazywanie tablic wielowymiarowych jako argumentów do 
funkcji */#include <stdio.h>#include <conio.h>/* deklaracje 
funkcji */ 
 
int DataAdd1(int list[][5], int max1, int max2); 
 
int DataAdd2(int *list, int max1, int max2); 
 
/* funkcja main() */ 
 
main() 
 

 
int list[2][5] = {1, 2, 3, 4, 5, 
 
5, 4, 3, 2, 1}; 
 
int *ptr_int; 
 

background image

 

117 

clrscr(); 
 
printf("Suma otrzymana przez DataAdd1(): %d\n", 
 
DataAdd1(list, 2, 5)); 
 
ptr_int = &list[0][0]; 
 
printf("Suma otrzymana przez DataAdd2(): %d\n", 
 
DataAdd2(ptr_int, 2, 5)); 
 
getch(); 
 
return 0; 
 

 
/* definicja funkcji Data Add1 */ 
 
int DataAdd1(int list[][5], int max1, int max2) 
 

 
int i, j; 
 
int sum = 0; 
 
 
for (i=0; i<max1; i++) 
 
for (j=0; j<max2; j++) 
 
sum += list[i][j]; 
 
return sum; 
 

 
/* definicja funkcji DataAdd2 */ 
 
int DataAdd2(int *list, int max1, int max2) 
 

 
int i, j; 
 
int sum = 0; 
 
 
for (i=0; i<max1; i++) 

background image

 

118 

 
for (j=0; j<max2; j++) 
 
sum += *(list + i*max2 + j); 
 
return sum; 
 
}  
do funkcji przekazywana jest tablica 
 
Add1 à przez warto

ść

 /nazw

ę

 
Add2 à przez wska

ź

nik 

 
W przykładach p_76_4 do p_76_6 deklaracje wymiaru tablic w 
programie głównym i w funkcjach. 
 
  
 
  
 
Tablice wska

ź

ników 

 
deklaracja tablicy wska

ź

ników 

 
int *ptr_int[5]; 
 
  
 
//p_76_7 
 
/* Tablice wska

ź

ników */#include <stdio.h>#include <conio.h>/* 

deklaracje funkcji */ 
 
void StrPrint1(char **str1, int size); 
 
void StrPrint2(char *str2); 
 
/* funkcja main() */ 
 
main() 
 

 
char *str[4] = {"To jest zdanie 1;", 
 
"To jest zdanie 2;", 
 
"To jest zdanie 3;", 
 
"To jest zdanie 4.\n" 

background image

 

119 

 
}; 
 
int i, size; 
 
clrscr(); 
 
size = 4; 
 
StrPrint1(str, size); 
 
for (i=0; i<4; i++) 
 
StrPrint2(str[i]); 
 
getch(); 
 
return 0; 
 

 
/* definicja funkcji */ 
 
void StrPrint1(char **str1, int size) 
 

 
int i; 
 
 
for (i=0; i<size; i++) 
 
printf("%s\n", str1[i]); 
 

 
/* definicja funkcji */ 
 
void StrPrint2(char *str2) 
 

 
printf("%s\n", str2); 
 

 
  
deklarujemy i inicjujemy tablice składaj

ą

c

ą

 si

ę

 z wielu ci

ą

gów 

znaków 
mo

ż

emy ja potraktowac jako tablic

ę

 dwuwymiarow

ą

 

 

background image

 

120 

1 wymiar – ilo

ść

 stringów 

 
2 wymiar – ilo

ść

 znaków w stringu 

mo

ż

emy ja równie

ż

 potraktowac jako tablice wska

ź

ników do 

poszczególnych stringów 
tablica jest wyprowadzana na ekran przez dwie funkcje 
 
StrPrint1 (wska

ź

nik do tablicy wska

ź

ników, wymiar) 

 
 
  
 
nazwa tablicy 
 
str – w programie głównym jest nazw

ą

 tablicy b

ę

d

ą

c

ą

 tablic

ą

 

wska

ź

ników do stringów; 

 
jest zatem jako nazwa tablicy wska

ź

nikiem do jej pierwszego 

elementu zatem jest wska

ź

nikiem do wska

ź

nika 

 
wywołanie StrPrint1(str,size) 
 
Funkcja StrPrint1(char **str1, int size) 
 
StrPrint2 - argumentem funkcji jest pojedynczy ła

ń

cuch 

/string/; 
 
Zatem argumentem wywołania jest wska

ź

nik do stringa i w 

tablicy [i] 
 
Wywołanie StrPrint2(str[i]) 
 
Deklaracja StrPrint(char *str2) 
 
  
 
  
 
  
 
 
Wska

ź

nik do funkcji 

 
Poniewa

ż

 funkcja ma warto

ść

 lewostronn

ą

 w postaci adresu 

startowego w pami

ę

ci, podobnie zatem jak w przypadku tablic 

mo

ż

na zadeklarowa

ć

 i zainicjowa

ć

 wska

ź

nik przy pomocy 

lewostronnej warto

ś

ci (adresu) funkcji. 

 
//p_76_8 
 
/* wska

ź

nik do funkcji */ 

background image

 

121 

 
#include <stdio.h> 
 
#include <conio.h> 
 
/* deklaracja funkcji */ 
 
int StrPrint(char *str); 
 
/* main() function */ 
 
main()  
 

 
char str[22] = "Wskazanie funkcji."; 
 
int (*ptr)(char *str); 
 
clrscr(); 
 
ptr = StrPrint; 
 
if (!(*ptr)(str)) 
 
printf("OK!\n"); 
 
getch(); 
 
return 0; 
 

 
/* definicja funkcji */ 
 
int StrPrint(char *str) 
 

 
printf("%s\n", str); 
 
return 0; 
 

 
  
 
funkcja zwraca typ int pobiera wska

ź

nik do znaku: 

 
  
 

background image

 

122 

deklaracja funkcji 
 
int StrPrint(char *str) 
 
deklaracja wska

ź

nika do funkcji 

 
int (*ptr)(char *str) 
 
 
  
 
  
 
deklaracja wska

ź

nika - wska

ź

nik uj

ę

ty w nawiasy okr

ą

głe 

wskazuje funk. 
 
  
 
  
 
  
 
  
 
  
 
typ (*nazwa_wska

ź

nika)(typ argumentu funkcji) 

 
 
  
 
zgodny z typem funkcji wska

ź

nik funkcji 

 
  
 
  
 
ptr = StrPrint à przypisanie lewostronnej warto

ś

ci funkcji 

 
wska

ź

nikowi 

 
  
 
(*ptr)(str) à wywołanie funkcji wskazywanej przez wska

ź

nik 

 
ptr z argumentem str à jest to przekazanie 
 
do funkcji tablicy str 
 
Funkcja drukuje ła

ń

cuch znaków, a po zako

ń

czeniu zwraca 0 

(return 0;) if(!0) à wydruk OK 

background image

 

123 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 

background image

 

124 

  
 
  
 
  
 
  
 
Dynamiczne przyporz

ą

dkowanie pami

ę

ci 

 
Je

ż

eli chcemy w trakcie realizacji programu zarz

ą

dza

ć

 pami

ę

ci

ą

 

dostepn

ą

 do jego realizacji to mamy do dyspozycji nastepuj

ą

ce 

funkcje z biblioteki stdlib.h : 
 
1/ malloc() 
 
2/ calloc() 
 
3/ realloc() 
 
4/ free() 
 
  
 
Funkcja malloc() 
 
Słu

ż

y do przyporz

ą

dkowania okreslonego obszaru pami

ę

ci 

 
#include <stdlib.h> 
 
void *malloc(size_t size); 
 
size – wielko

ść

 obszaru pami

ę

ci w bajtach przeznaczony do 

przyporz

ą

dkowania 

 
funkcja zwraca wska

ź

nik typu void (nieokre

ś

lony), wskazuj

ą

cy 

pocz

ą

tkowy adres zarezerwowanego obszaru pami

ę

ci à typ tego 

wska

ż

nika jest automatycznie poddawany konwersji i zmieniany 

na typ wska

ź

nika, który znajduje si

ę

 po lewej stronie 

operatora przypisania. 
 
Funkcja zwraca wska

ź

nik pusty, gdy operacja zarezerwowania 

żą

danego obszaru pami

ę

ci sko

ń

czy si

ę

 niepowodzeniem. Dlatego 

zawsze przed u

ż

yciem takiego wska

ź

nika nale

ż

y sprzwdzi

ć

 czy 

nie jest pusty. 
 
 
//p_76_9 
 

background image

 

125 

/ U

ż

ycie funkcji malloc() */#include <stdio.h> #include 

<stdlib.h>#include <string.h>/* function declaration */void 
StrCopy(char *str1, char *str2);/* main() function */main(){ 
 
char str[] = "U

ż

ycie malloc() do rezerwacji pami

ę

ci."; 

 
char *ptr_str; 
 
int termination; 
 
/* call malloc() */  
 
ptr_str = malloc( strlen(str) + 1);  
 
if (ptr_str != NULL){ 
 
StrCopy(str, ptr_str);  
 
printf("Ła

ń

cuch okre

ś

lony wska

ź

nikiem ptr_str:\n%s\n",  

 
ptr_str); 
 
termination = 0; 
 

 
else{ 
 
printf("malloc() function failed.\n"); 
 
termination = 1; 
 

 
return termination; 
 
}  
 
/* function definition */ 
 
void StrCopy(char *str1, char *str2) 
 

 
int i; 
 
 
for (i=0; str1[i]; i++) 
 
str2[i] = str1[i]; 
 

background image

 

126 

str2[i] = '\0'; 
 

 
Zadaniem funkcji malloc() jest zarezerwowanie pami

ę

ci dla 

ła

ń

cucha znaków. Wska

ź

nik zwracany przez funkcj

ę

 malloc() jest 

wykorzystywany w operacji kopiowania ła

ń

cuchów. 

 
Je

ż

eli po wykorzystaniu przyporz

ą

dkowanej dynamicznie pami

ę

ci 

ta nie zostanie zwolniona, a w dalszej cz

ęś

ci programu 

nast

ą

pi

ą

 kolejne operacje przyporz

ą

dkowania pami

ę

ci to pami

ę

ci 

mo

ż

e po prostu zabrakn

ąć

 
Dynamicznie przyporz

ą

dkowan

ą

 pami

ęć

 zwalnia funkcja free(). 

 
 
  
 
Funkcja free() 
 
poniewa

ż

 pami

ęć

 dost

ę

pna w ka

ż

dym komputerze jest ograniczona, 

nale

ż

y przyporz

ą

dkowa

ć

 tylko tyle pami

ę

ci ile jest jest jej 

rzeczywi

ś

cie potrzebne, a po wykorzystaniu j

ą

 zwolni

ć

 
//p_76_10 
 
/ Use the free() function */#include <stdio.h> #include 
<stdlib.h>/* function declarations */ void DataMultiply(int 
max, int *ptr);void TablePrint(int max, int *ptr);/* main() 
function */main(){ int *ptr_int, max; 
 
int termination; 
 
char key = 'c'; 
 
max = 0; 
 
termination = 0;  
 
while (key != 'x'){ 
 
printf("Enter a single digit number:\n"); 
 
scanf("%d", &max);  
 
/* call malloc() */  
 
ptr_int = malloc(max * max * sizeof(int));  
 
if (ptr_int != NULL){ 
 

background image

 

127 

DataMultiply(max, ptr_int);  
 
TablePrint(max, ptr_int); 
 
free(ptr_int);  
 

 
else{ 
 
printf("malloc() function failed.\n"); 
 
termination = 1; 
 
break; 
 

 
printf("\nPress x-key to quit; other key to continue.\n"); 
 
scanf("%s", &key);  
 

 
printf("\nBye!\n"); 
 
return termination; 
 
}  
 
/* function definition */ 
 
void DataMultiply(int max, int *ptr) 
 

 
int i, j; 
 
 
for (i=0; i<max; i++) 
 
for (j=0; j<max; j++) 
 
*(ptr + i * max + j) = (i+1) * (j+1); 
 

 
/* function definition */ 
 
void TablePrint(int max, int *ptr) 
 

background image

 

128 


 
int i, j; 
 
printf("The multiplication table of %d is:\n",  
 
max); 
 
printf(" "); 
 
for (i=0; i<max; i++) 
 
printf("%4d", i+1); 
 
printf("\n "); 
 
for (i=0; i<max; i++) 
 
printf("----", i+1);  
 
for (i=0; i<max; i++){ 
 
printf("\n%d|", i+1); 
 
for (j=0; j<max; j++) 
 
printf("%3d ", *(ptr + i * max + j));  
 

 

 
Działanie programu ma na celu zbudowanie dwuwymiarowej 
numerycznej tablicy n x n z elementami zaczerpni

ę

tymi z 

tabliczki mno

ż

enia. P

ę

tle w programie b

ę

d

ą

 powtarzane, a

ż

 do 

naci

ś

ni

ę

cia znaku ‘x’, lub niepowodzenia w przyporz

ą

dkowaniu 

pami

ę

ci przez funkcj

ę

 malloc(). 

 
Aby zademonstrowa

ć

 działanie funkcji free(), program dokonuje 

tymczasowego obszaru pami

ę

ci, do przechowywania elementów 

tabliczki mno

ż

enia. Zaraz po wydrukowaniu na ekran pami

ęć

 ta 

zostaje zwolniona poprzez działanie funkcji free(). 
 
 
  
 
Funkcja calloc() 
 
Funkcja ta podobnie jak malloc() mo

ż

na stosowa

ć

 do 

dynamicznego przyporz

ą

dkowania pami

ę

ci. Funkcja calloc() 

background image

 

129 

pobiera dwa argumenty i po zarezerwowaniu pami

ę

ci powoduje 

dodatkowo wyzerowanie bajtów wchodz

ą

cych w skład tego obszaru. 

 
#include <stdlib.h> 
 
void *calloc(size_t nitem, size_t size); 
 
nitem – oznacza ilo

ść

 elementów, które chcemy przechowa

ć

 w 

pami

ę

ci 

 
size – rozmiar pojedynczego elementu w bajtach 
 
calloc() zwraca równie

ż

 wska

ź

nik typu void 

 
//p_76_11 
 
/* 17L03.c: Use the calloc() function */ 
 
#include <stdio.h>  
 
#include <stdlib.h> 
 
/* main() function */ 
 
main() 
 

 
float *ptr1, *ptr2; 
 
int i, n; 
 
int termination = 1; 
 
n = 5;  
 
ptr1 = malloc(n * sizeof(float));  
 
ptr2 = calloc(n, sizeof(float));  
 
if (ptr1 == NULL)  
 
printf("malloc() failed.\n"); 
 
else if (ptr2 == NULL) 
 
printf("calloc() failed.\n"); 
 
else{ 
 
for (i=0; i<n; i++) 

background image

 

130 

 
printf("ptr1[%d]=%5.2f, ptr2[%d]=%5.2f\n",  
 
i, *(ptr1 + i), i, *(ptr2 + i)); 
 
free(ptr1); 
 
free(ptr2); 
 
termination = 0; 
 

 
return termination; 
 
}  
 
Aby sprawdzi

ć

 czy pami

ęć

 zarezerwowana przez funkcj

ę

 calloc() 

zostaje wyzerowana , pocz

ą

tkowa zawarto

ść

 pami

ę

ci zostaje 

wydrukowana i porównana z zawarto

ś

cia pami

ę

ci rezerwowanej 

funkcj

ą

 malloc(). 

 
  
 
Funkcja realloc() 
 
Funkcja ta pozwala na zmiane rozmiaru bloku w dynamicznie 
przyporz

ą

dkowanym obszarze pami

ę

ci, który został uprzednio 

zarezerwowany przez funkcje malloc(), calloc() i realloc(). 
 
 
#include <stdlib.h> 
 
void *realloc(void *block, size_t size) 
blok - wska

ź

nik do obszaru pami

ę

ci uprzednio przyporz

ą

kowanego 

dynamicznie; 
size – rozmiar bloku pami

ę

ci, który powinien zosta

ć

 

przeorganizowany 
 
Funkcja zwraca wska

ź

nik typu void, albo wska

ź

nik zerowy. 

 
Funkcja realloc() wywołana z pierwszym argumentem zerowym jest 
równowa

ż

na funkcji malloc(). 

 
ptr_flt = realloc(NULL, 10*sizeof(float)); 
 
ptr_flt = malloc(10*sizeof(float)); à s

ą

 równowa

ż

ne 

 
J

ęż

eli funkcja realloc() b

ę

dzie miała 2 argument równy zero to 

jest równowa

ż

na fnkcji free(); 

 

background image

 

131 

free(prt); 
 
realloc(prt,0); à sa równowa

ż

ne 

 
  
 
//p_76_12 
 
/* 17L04.c: Use the realloc() function */#include <stdio.h> 
#include <stdlib.h>#include <string.h>/* function declaration 
*/void StrCopy(char *str1, char *str2); 
 
/* main() function */ 
 
main() 
 

 
char *str[4] = {"There's music in the sighing of a reed;", 
 
"There's music in the gushing of a rill;", 
 
"There's music in all things if men had ears;", 
 
"There earth is but an echo of the spheres.\n" 
 
}; 
 
char *ptr; 
 
int i; 
 
 
int termination = 0; 
 
ptr = malloc(strlen((str[0]) + 1) * sizeof(char)); 
 
if (ptr == NULL){  
 
printf("malloc() failed.\n"); 
 
termination = 1; 
 

 
else{ 
 
StrCopy(str[0], ptr); 
 
printf("%s\n", ptr); 
 

background image

 

132 

for (i=1; i<4; i++){ 
 
ptr = realloc(ptr, (strlen(str[i]) + 1) * sizeof(char)); 
 
if (ptr == NULL){  
 
printf("realloc() failed.\n"); 
 
termination = 1; 
 
break; 
 
}  
 
else{ 
 
StrCopy(str[i], ptr); 
 
printf("%s\n", ptr); 
 

 

 
}  
 
free(ptr); 
 
return termination; 
 
}  
 
/* funciton definition */ 
 
void StrCopy(char *str1, char *str2) 
 

 
int i; 
 
 
for (i=0; str1[i]; i++) 
 
str2[i] = str1[i]; 
 
str2[i] = '\0'; 
 

 
Funkcja ma za zadanie przyporz

ą

dkowa

ć

 dynamicznie blok pami

ę

ci 

do przechowywania ła

ń

cucha znakowego. W przykł

ą

dzie wyst

ę

puj

ą

 

background image

 

133 

4 ła

ń

cuchy znakowe o ró

ż

nej długo

ś

ci. Aby przystosowa

ć

 

wielko

ść

 poprzednio przyporz

ą

dkowanego obszaru pami

ę

ci do 

nastepnego ła

ń

cucha znaków stosowana jest funkcja realloc(). 

 
Wykorzystano tablic

ę

 wska

ź

ników str do 4 ła

ń

cuchów tekstowych. 

 
Obszar pami

ę

ci zostaje przyporz

ą

dkowany, a jego rozmiar 

dostosowany do aktualnych potrzeb w oparciu o długo

ść

 ka

ż

dego 

ł

ąń

cucha znaków. Obie stosowane funkcje malloc() i realloc() 

dokonuj

ą

 przydziału obszaru pami

ę

ci i regulacji jego rozmiaru 

w sposób dynamiczny – tzn w ruchu programu. 
 
 
  
 
  
 
  
 
  
 
  
 
Wyliczeniowy typ danych 
 
 
  
 
Wyliczeniowy typ danych umo

ż

liwia skojarzenie nazw 

symbolicznych ze stałymi numerycznymi typu integer. 
 
  
 
Deklaracja: 
 
  
 
enum nazwa {lista wyliczeniowa} lista zmiennych; 
 
  
 
  
 
enum – słowo kluczowe; 
 
nazwa – nazwa typu wyliczeniowego; 
 
lista zmiennych – nazwy zmiennych danego typu wyliczeniowego; 
 

background image

 

134 

lista wyliczeniowa – identyfikatory – zdefiniowane stałe 
tekstowe, u

ż

ywane do reprezentacji numerycznych stałych 

całkowitych; 
 
 
  
 
wariant 1: 
 
enum auto {sedan, pick_up, sport} krajowe, zagraniczne; 
 
wariant 2: 
 
enum auto {sedan, pick_up, sport}; 
 
auto krajowe, zagraniczne; 
 
  
 
  
 
  
 
  
 
  
 
Przypisanie warto

ś

ci liczbowych do typu wyliczeniowego. 

 
  
 
Standardowo gdy programista nie zadeklaruje inaczej: 
 
Stała symboliczna wymieniona na pocz

ą

tku listy wyliczeniowej 

ma przypisan

ą

 warto

ść

 0, nast

ę

pne kolejno i 1 wi

ę

ksz

ą

 
Sposób przyporz

ą

dkowania stałych int w programie: 

 
enum auto {sedan=60, pick_up=30, sport=10}; 
 
//p_77 
 
#include <stdio.h>#include <conio.h>void main(void){enum jezyk 
{human=100,animal=50,computer};enum dni 
{pon,wto,sro,czw,pio,sob,nie};clrscr();printf("human %d, 
animal %d, computer %d\n",human,animal,computer); 
 
printf("pon %d\n",pon); 
 
printf("wto %d\n",wto); 
 

background image

 

135 

printf("sro %d\n",sro); 
 
printf("czw %d\n",czw); 
 
printf("pio %d\n",pio); 
 
printf("sob %d\n",sob); 
 
printf("nie %d\n",nie); 
 
getch(); 
 

 
  
 
powy

ż

szy przykład ilustruje automatyczne i r

ę

czne 

przyporz

ą

dkowanie stałym symbolicznym warto

ś

ci numerycznych 

typu int; 
 
  
 
  
 
  
 
  
 
/p_78 
 
#include <stdio.h>#include <conio.h>void main(void){enum 
money_units{grosik=1,piatka=5,dycha=10,polowka=50,zlocisz=100}
; int money_units[5]={zlocisz,polowka,dycha,piatka,grosik}; 
 
char *unit_name[5]={"złocisz(-ów)","połów(-ka/ek)","dycha(-
ch)","pi

ą

tka(-ek)","grosik(-ow)"}; 

 
int cent,tmp,i; 
 
clrscr(); 
 
printf("Wpisz sum

ę

 w groszach:\n"); 

 
scanf("%d",&cent); 
 
printf("Odpowiada to zestawowi monet:\n"); 
 
tmp=0; 
 
for(i=0;i<5;i++) 
 

background image

 

136 


 
tmp=cent/money_units[i]; 
 
cent-=tmp*money_units[i]; 
 
if(tmp) 
 
printf("%d %s ",tmp,unit_name[i]); 
 

 
printf("\n"); 
 
getch(); 
 

 
Zadaniem programu jest wykorzystanie typu wyliczeniowego do 
reprezentacji sumy wprowadzonej przez u

ż

ytkownika za pomoc

ą

 

zestawu monet. 
typ wyliczeniowy money_units wykorzystywany jest do 
przyporz

ą

dkowanie stałym symbolicznym warto

ś

ci monet złocisz –

100 (gr) , dycha – 10 (gr) itd; 
deklarowana tablica numeryczna typu int inicjowana jest 
stałymi symbolicznymi typu wyliczeniowego – co odpowiada : 
 
int money_units[5]={100,50,10,5,1} à po zadeklarowaniu typu 
wyliczeniowego mo

ż

na stosowa

ć

 stałe symboliczne z listy 

wyliczeniowej zamiast odpowiadaj

ą

cych im warto

ś

ci 

numerycznych; 
delaracja tablicy zło

ż

onej ze wska

ź

ników do ła

ń

cuchów 

tekstowych umo

ż

liwi wyprowadzanie opisów; 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Definiowanie typów u

ż

ytkownika. 

 
  

background image

 

137 

 
typedef int liczba_2bajty; 
 
liczba_2bajty i,j,k,l; ß à int i,j,k,l; 
 
  
 
Definicja typu typedef tworzy synonim deklaracji typu i musi 
wyst

ą

pi

ć

 w programie zanim ten synonim zostanie u

ż

yty. 

umo

ż

liwia uproszczenie nazwy skomplikowanego typu danych do 

pojedynczego słowa; 
po dokonaniu jednokrotnej korekty definicji synonimu, mo

ż

na 

u

ż

ywac tego nowego synonimu wielokrotnie w przyszłosci; 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  

background image

 

138 

 
  
 
  
 
  
 
Przekazywanie do funkcji main() argumentów z wiersza polece

ń

 
  
 
Argumenty z wiersza polece

ń

 przekazujemy podczas uruchamiania 

wersji exe programu napisanego w j

ę

zyku C. 

 
Maj

ą

c program o nazwie prog.c à prog.exe 

 
C:> prog argument1, argument2, argument3 
 
Argumenty 1-3 sa argumentami z wiersza polece

ń

 

 
Funkcja main() posiada dwa wbudowane argumenty , które mog

ą

 

by

ć

 wykorzystane do pobierania parametrów z wiersza polece

ń

 

systemu operacyjnego /trzeci odnosi si

ę

 do otoczenia 

systemowego/. 
 
Pierwszy nazywa si

ę

 argc – słu

ż

y on do przechowywania 

całkowitej liczby parametrów przekazywanych do funkcji main() 
z wiersza polece

ń

 
Drugi argv – jest wska

ź

nikiem do tablicy wska

ź

ników – ła

ń

cuchy 

znaków. Ka

ż

dy element tej tablicy wskazuje jeden argument z 

wiersza polece

ń

, traktowany jako ła

ń

cuch znaków; 

 
  
 
  
 
typ_wy main(int argc, char *argv[]) 
 

 

 
Przy wywołaniu prog.exe argc=4 gdy

ż

 nazwa programu jest 

uznawana jako pierwszy argument z wiersza polece

ń

 
argv[0]=”c:\programy\prog.exe” 
 
argv[1]=”argument1” 
 
argv[2]=”argument2” 

background image

 

139 

 
argv[3]=”argument3” 
 
  
 
//p_79 
 
#include <stdio.h>#include <conio.h>void main(int argc,char 
*argv[]){ int i; clrscr(); printf("%d\n",argc); 
printf("%d\n",argc); for(i=0;i<argc;i++) 
printf("%s\n",argv[i]); getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  

background image

 

140 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Struktura – ł

ą

czenie ró

ż

nych typów danych 

 
Struktura jest poł

ą

czeniem w cało

ść

 danych ró

ż

nych typów, tak 

aby mogły stanowi

ć

 jeden moduł. 

 
Róznica mi

ę

dzy strukturami a tablicami: 

w obr

ę

bie struktury mog

ą

 znajdowa

ć

 ró

ż

ne typy; 

ka

ż

dy element w strukturze ma swoj

ą

 własna nazw

ę

 
Elementy danych wchodz

ą

ce w skł

ą

d struktury – pola struktury; 

 
  
 
Deklarowanie struktur 
 
  
 
struct nazwa_struct{ 
 
typ zmienna1; 
 
typ zmienna2; 
 
typ zmienna3; 
 
}; 
 
struct auto{ 
 
int rok; 
 
char model[8]; 
 
int moc_silnika; 
 
float masa; 

background image

 

141 

 
}; 
 
  
 
  
 
Definiowanie struktur 
 
  
 
struct auto sedan,pick_up,sport; 
 
  
 
  
 
  
 
struct auto{ 
 
int rok; 
 
char model[8]; 
 
int moc_silnika; 
 
float masa; 
 
} seadan, pick_up, sport; 
 
  
 
  
 
Odwoływanie si

ę

 do elementów struktur – operator .  

 
  
 
zmienna_struktury.nazwa_pola 
 
ptr=sport.model; 
 
//p_80 
 
#include <stdio.h>#include <conio.h>void main(void){struct 
komputer { float koszt; int rok; int cpu_cz; char cpu_typ[16]; 
} model; clrscr(); printf("Podaj typ CPU: \n"); 
gets(model.cpu_typ); printf("Podaj cz

ę

st. CPU w MHz: \n"); 

 
scanf("%d",&model.cpu_cz); 

background image

 

142 

 
printf("Podaj rok produkcji: \n"); 
 
scanf("%d",&model.rok); 
 
printf("Podaj cene jego zakupu: \n"); 
 
scanf("%f",&model.koszt); 
 
printf("Oto wprowadzone dane: \n"); 
 
printf("Rok produkcji : %d \n",model.rok); 
 
printf("Cena zakupu : %6.2f \n",model.koszt); 
 
printf("Typ CPU : %s \n",model.cpu_typ); 
 
printf("Szybko

ść

 CPU w MHZ : %d \n",model.cpu_cz); 

 
getch(); 
 

 
powy

ż

szy program demonstruje dowołania do poszczególnych pól 

struktury 
 
  
 
Inicjowanie struktur 
 
Poni

ż

szy program przedstawia sposób inicjowania struktury, a 

nast

ę

pnie aktualizacj

ę

 zawarto

ś

ci pól danych przez 

u

ż

ytkownika. 

 
  
 
  
 
//p_81 
 
#include <stdio.h>#include <conio.h>void main(void){struct 
pracownik 
 

 
int nr; 
 
char nazwisko[32]; 
 
}; 
 

background image

 

143 

struct pracownik info = { 0001,"J.Nowak"}; 
 
clrscr(); 
 
printf("Wydruk pól struktury\n"); 
 
printf("Nazwisko pracownika: %s\n",info.nazwisko); 
 
printf("Numer ID #: %04d\n",info.nr); 
 
printf("Podaj swoje nazwisko: ? \n"); 
 
gets(info.nazwisko); 
 
printf("Podaj swój numer: ? \n"); 
 
scanf("%d",&info.nr); 
 
printf("Wprowadziłe

ś

 dane: \n"); 

 
printf("Nazwisko pracownika: %s\n",info.nazwisko); 
 
printf("Numer ID #: %04d\n",info.nr); 
 
getch(); 
 

 
  
 
  
 
definicja, deklaracja i zainicjowanie struktury w pojedy

ń

czej 

instrukcji 
 
struct pracownik 
 

 
int nr; 
 
char nazwisko[30]; 
 
} info = {0001,”J.Nowak”}; 
 
  
 
  
 
  
 

background image

 

144 

  
 
Struktury a funkcje 
 
J

ę

zyk C pozwala przekaza

ć

 cał

ą

 struktur

ę

 jako argument do 

funkcji, jak równie

ż

 funkcja mo

ż

e zwrócic struktur

ę

 jako 

warto

ść

 
Demonstruje to poni

ż

szy przykład. 

 
//p_82 
 
#include <stdio.h>#include <conio.h>struct komputer { float 
koszt; int rok; int cpu_cz; char cpu_typ[16]; }; typedef 
struct komputer SC; SC PobierzDane(SC s); 
 
void main(void) 
 

 
SC model; 
 
clrscr(); 
 
model=PobierzDane(model); 
 
  
 
printf("Dane, które wprowadziłe

ś

: \n"); 

 
printf("Rok: %d \n",model.rok); 
 
printf("Cena: %6.2f \n",model.koszt); 
 
printf("CPU typ: %s \n",model.cpu_typ); 
 
printf("Predko

ść

 : %d MHz \n",model.cpu_cz); 

 
getch(); 
 

 
SC PobierzDane(SC s) 
 

 
printf("Podaj typ CPU: \n"); 
 
gets(s.cpu_typ); 
 
printf("Podaj cz

ę

st. CPU w MHz: \n"); 

background image

 

145 

 
scanf("%d",&s.cpu_cz); 
 
printf("Podaj rok produkcji: \n"); 
 
scanf("%d",&s.rok); 
 
printf("Podaj cene jego zakupu: \n"); 
 
scanf("%f",&s.koszt); 
 
return s; 
 

 
  
 
  
 
Wska

ź

niki do struktur 

 
Podobnie jak przekazuje si

ę

 funkcjom wska

ź

niki do tablic, tak 

mo

ż

na przekaza

ć

 im równie

ż

 w postaci argumentu wska

ź

nik 

wskazuj

ą

cy struktur

ę

 
W przeciwie

ń

stwie do przekazywania całej struktury w formie 

argumentu do funkcji , co powodowało na u

ż

ytek funkcji 

tworzenie kopii całej struktury, przekazanie do funkcji 
wska

ź

nika powoduje jedynie przekazanie jej adresu w pami

ę

ci, 

pod którym zlokalizowana jest struktura. Funkcja mo

ż

posługiwac si

ę

 tym adresem , odwołuj

ą

c si

ę

 bezpo

ś

rednio do pól 

struktury, a nie do kopii struktury. 
 
Prezentuje to poni

ż

szy program. 

 
//p_83 
 
#include <stdio.h>#include <conio.h>struct komputer { float 
koszt; int rok; int cpu_cz; 
 
char cpu_typ[16]; 
 
}; 
 
typedef struct komputer SC; 
 
void PobierzDane(SC *ptr_s); 
 
void main(void) 
 

background image

 

146 

 
SC model; 
 
clrscr(); 
 
  
 
PobierzDane(&model); 
 
  
 
printf("Dane, które wprowadziłe

ś

: \n"); 

 
printf("Rok: %d \n",model.rok); 
 
printf("Cena: %6.2f \n",model.koszt); 
 
printf("CPU typ: %s \n",model.cpu_typ); 
 
printf("Predko

ść

 : %d MHz \n",model.cpu_cz); 

 
getch(); 
 

 
void PobierzDane(SC *ptr_s) 
 

 
float pomoc; 
 
printf("Podaj typ CPU: \n"); 
 
gets((*ptr_s).cpu_typ); 
 
printf("Podaj cz

ę

st. CPU w MHz: \n"); 

 
scanf("%d",&(*ptr_s).cpu_cz); 
 
printf("Podaj rok produkcji: \n"); 
 
scanf("%d",&(*ptr_s).rok); 
 
  
 
printf("Podaj cene jego zakupu: \n"); 
 
scanf("%f",&pomoc); 
 
(*ptr_s).koszt=pomoc; 
 

background image

 

147 

// scanf("%f",&(*ptr_s).koszt); 
 

 
  
 
(*ptr_s).pole à odwołanie si

ę

 do pola struktury  

 
co mo

ż

na zast

ą

pic przez 

 
ptr_s à pole 
 
  
 
natomiast wyra

ż

enie: &(*ptr_s).pole przez: &(ptr_s à pole) 

 
ilustruje to poni

ż

szy przykład: 

 
//p_84 
 
#include <stdio.h>#include <conio.h>struct komputer { 
 
float koszt; 
 
int rok; 
 
int cpu_cz; 
 
char cpu_typ[16]; 
 
}; 
 
typedef struct komputer SC; 
 
void PobierzDane(SC *ptr_s); 
 
void main(void) 
 

 
SC model; 
 
clrscr(); 
 
  
 
PobierzDane(&model); 
 
  
 
printf("Dane, kt˘re wprowadzi

e

: \n"); 

background image

 

148 

 
printf("Rok: %d \n",model.rok); 
 
printf("Cena: %6.2f \n",model.koszt); 
 
printf("CPU typ: %s \n",model.cpu_typ); 
 
printf("Predko

ść

 : %d MHz \n",model.cpu_cz); 

 
getch(); 
 

 
void PobierzDane(SC *ptr_s) 
 

 
float pomoc; 
 
printf("Podaj typ CPU: \n"); 
 
gets(ptr_s->cpu_typ); 
 
printf("Podaj cz

ę

st. CPU w MHz: \n"); 

 
scanf("%d",&(ptr_s->cpu_cz)); 
 
printf("Podaj rok produkcji: \n"); 
 
scanf("%d",&(ptr_s->rok)); 
 
  
 
printf("Podaj cene jego zakupu: \n"); 
 
scanf("%f",&pomoc); 
 
ptr_s->koszt=pomoc; 
 
// scanf("%f",&(*ptr_s.koszt)); 
 

 
  
 
  
 
  
 
  
 

background image

 

149 

  
 
  
 
  
 
  
 
  
 
Tablice struktur 
 
W j

ę

zyku C mo

ż

na zadeklarowa

ć

 tablic

ę

, której elementami b

ę

d

ą

 

struktury. 
 
Nale

ż

y nazw

ę

 tablicy (identyfikator) poprzedzi

ć

 nazw

ą

 typu 

struktur. 
 
struct x tablica[8]; 
 
jest deklaracj

ą

 8-elementowej jednowymiarowej tablicy, której 

elementami s

ą

 struktury typu x. 

 
  
 
//p_85 
 
#include <stdio.h>#include <conio.h>struct wiersz { int 
start_year; int end_year; char autor[16]; char str1[64]; char 
str2[64]; char str3[64]; }; typedef struct wiersz WS; 
 
void WyswietlDane(WS *ptr_s); 
 
void main(void) 
 

 
WS poemat[2]= 
 

 
{1641, 
 
1716, 
 
"Autor1", 
 
"Wiersz01", 
 
"Wiersz02", 
 

background image

 

150 

"Wiersz03" 
 
}, 
 
{1729, 
 
1781, 
 
"Autor2", 
 
"Wiersz11", 
 
"Wiersz12", 
 
"Wiersz13" 
 

 
}; 
 
int i; 
 
clrscr(); 
 
for(i=0;i<2;i++) 
 
WyswietlDane(&poemat[i]); 
 
getch(); 
 

 
void WyswietlDane(WS *ptr_s) 
 

 
printf("%s\n",ptr_s->str1); 
 
printf("%s\n",ptr_s->str2); 
 
printf("%s\n",ptr_s->str3); 
 
printf("---%s\n",ptr_s->autor); 
 
printf(" (%d-%d)\n\n",ptr_s->start_year,ptr_s->end_year); 
 

 
  
 
  

background image

 

151 

 
  
 
Struktury zagnie

ż

dzone 

 
Struktury nazywane sa strukturami zagnie

ż

dzonymi je

ś

li co 

najmniej jedno z pól struktury jest struktur

ą

 
struct x 
 

 
int a; 
 
float b; 
 
}; 
 
struct y 
 

 
int i; 
 
char ch[10]; 
 
x strukt_wew 
 
}; 
 
struktura y stanowi strukture zło

ż

ona z zagnie

ż

dzona wewn

ą

trz 

struktur

ą

 x 

 
//p_86 
 
#include <stdio.h>#include <conio.h>struct dzial { int kod; 
char nazwa[32]; char stanowisko[16]; }; typedef struct dzial 
DZ; 
 
struct pracownik 
 

 
DZ d; 
 
int id; 
 
char nazwisko[32]; 
 
}; 
 

background image

 

152 

typedef struct pracownik PRAC; 
 
void InfoWyswietl(PRAC *ptr); 
 
void InfoWprowadz(PRAC *ptr); 
 
void main(void) 
 

 
PRAC info = 
 

 
{ 01, 
 
"Marketing", 
 
"Manager" 
 
}, 
 
0001, 
 
"J.Nowak" 
 
}; 
 
clrscr(); 
 
printf("Przykład: \n"); 
 
InfoWyswietl(&info); 
 
InfoWprowadz(&info); 
 
printf("\nOto dane, które wprowadziłe

ś

: \n"); 

 
InfoWyswietl(&info); 
 
getch(); 
 

 
void InfoWyswietl(PRAC *ptr) 
 

 
printf("Nazwisko: %s \n",ptr->nazwisko); 
 
printf("Numer : %04d \n",ptr->id); 

background image

 

153 

 
printf("Nazwa działu : %s \n ",ptr->d.nazwa); 
 
printf("Numer działu : %02d \n",ptr->d.kod); 
 
printf("Stanowisko: %s \n",ptr->d.stanowisko); 
 

 
void InfoWprowadz(PRAC *ptr) 
 

 
printf("\n Wpisz swoje dane: \n"); 
 
printf("Nazwisko: \n"); 
 
gets((*ptr).nazwisko); 
 
printf("Funkcja: \n"); 
 
gets((*ptr).d.stanowisko); 
 
printf("Nazwa działu: \n"); 
 
gets((*ptr).d.nazwa); 
 
printf("Numer działu: \n"); 
 
scanf("%d",&(ptr->d.kod)); 
 
printf("Twój numer ID : \n"); 
 
scanf("%d",&(ptr->id)); 
 

 
  
 
dost

ę

p do danych ptr à nazwa_zm_str_wew.nazwa_pola 

 
  
 
  
 
Forward reference – wyprzedzaj

ą

ce odwoływanie si

ę

 do struktur 

 
Je

ż

eli jednym z elementów struktury jest wska

ź

nik do struktur 

innego typu, który to typ struktur nie został jeszcze 
zadeklarowany, to struktura taka nazywa si

ę

 struktura ze 

wskazaniem wyprzedzaj

ą

cym – forward referencing structure. 

background image

 

154 

 
struct x 
 

 
int i; 
 
char ch[10]; 
 
struct y *ptr; 
 
}; 
 
 
oczywi

ś

cie przy zało

ż

eniu 

ż

e typ struktury y nie został 

jeszcze zadeklarowany; 
 
je

ż

eli wska

ź

nik b

ę

d

ą

cy elementem struktury wskazuje na ni

ą

 

sam

ą

, to struktura taka nazywa si

ę

 auto referencyjn

ą

 
struct x 
 

 
int i; 
 
char ch[10]; 
 
struct x *ptr; 
 
}; 
 
  
 
//p_87 
 
#include <stdio.h>#include <conio.h>struct dane 
 

 
char name[16]; 
 
struct date *p; 
 
struct date *d; 
 
}; 
 
struct date 
 

background image

 

155 

 
int rok; 
 
char szkola[32]; 
 
char stopien[8]; 
 
}; 
 
typedef struct dane DAN; 
 
typedef struct date DAT; 
 
void InfoWyswietl(DAN *ptr); 
 
void main(void) 
 

 
DAT pier = 
 

 
1985, 
 
"Politechnika", 
 
"in

ľ

 
}; 
 
DAT drug = 
 

 
1988, 
 
"AGH", 
 
"mgr in

ľ

 
}; 
 
DAT *pp,*pd; 
 
pp=&pier; 
 
pd=&drug; 
 
DAN prac = 
 

background image

 

156 


 
"Marek", 
 
pp, 
 
pd 
 
//&pier, 
 
//&drug 
 
}; 
 
clrscr(); 
 
printf("To sa dane Marka: \n"); 
 
InfoWyswietl(&prac); 
 
getch(); 
 

 
void InfoWyswietl(DAN *ptr) 
 

 
printf("Imie: %s \n",ptr->name); 
 
printf("Nazwa szkoły: %s \n",ptr->p->szkola); 
 
printf("Data uzyskania tytułu %d \n",ptr->p->rok); 
 
printf("Stopie

ń

: %s \n",ptr->p->stopien); 

 
printf("Nazwa szkoły: %s \n",ptr->d->szkola); 
 
printf("Data uzyskania tytułu %d \n",ptr->d->rok); 
 
printf("Stopie

ń

: %s \n",ptr->d->stopien); 

 

 
  
 
  
 
nowy sposób odwołania do pola : ptr à d à stopien 
 
  

background image

 

157 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Unie 
 

background image

 

158 

  
 
Unia jest to blok pami

ę

ci u

ż

ywany do przechowywania róznych 

elementów danych. 
 
W j

ę

zyku C unia jest podobna do struktury , z tym wyj

ą

tkiem 

ż

dane zawarte w unii nakładaj

ą

 si

ę

 wzajemnie na siebie – 

poniewa

ż

 dziel

ą

 mi

ę

dzy siebie ten sam obszar pami

ę

ci. 

 
Deklarowanie unii 
 
union auto { 
 
int rok; 
 
char model[8]; 
 
int moc_silnika; 
 
float waga; 
 
}; 
 
union – słowo kluczowe /okresla kategorie typu danych/ 
 
auto - nazwa typu danych 
 

 
} - struktura wewn

ę

trzna unii zawieraj

ą

ca jej pola nazywane 

równie

ż

 jej elementami; poniewa

ż

 elementy unii mog

ą

 si

ę

 

nawzajem nakładac zatem nazwa element jest zasadniejsza od 
nazwy pole; 
 
  
 
  
 
Definiowanie zmiennych unii 
 
  
 
union auto sedan, pick_up, sport; 
 
union auto { 
 
int rok; 
 
char model[8]; 
 
int moc_silnika; 

background image

 

159 

 
float waga; 
 
} sedan, pick_up, sport; 
 
je

ż

eli poł

ą

czymy deklaracj

ę

 typu unii i definicj

ę

 zmiennych 

danego typu w pojedyncz

ą

 instrukcj

ę

 mo

ż

emy w tej instrukcji 

pomin

ąć

 identyfikator typu unii: (słowo auto) 

 
union { 
 
int rok; 
 
char model[8]; 
 
int moc_silnika; 
 
float waga; 
 
} sedan, pick_up, sport; 
 
podobnie jak w przypadku elementów struktury, tak i w 
przypadku do elementów składowych unii mo

ż

e by

ć

 stosowany 

operator . 
 
sedan.year=1997; 
 
po zadeklarowaniu wska

ź

nika do zmiennych unii 

 
union auto *ptr; 
 
ptr à year = 1997; 
 
//p_88 
 
#include <stdio.h>#include <string.h> 
 
#include <conio.h> 
 
void main(void) 
 

 
union menu 
 

 
char nazwa[20]; 
 
double cena; 
 

background image

 

160 

} danie; 
 
clrscr(); 
 
printf("Zawarto

ść

 unii\n"); 

 
strcpy(danie.nazwa,"kotlet schabowy"); 
 
printf("Nazwa dania: %s\n",danie.nazwa); 
 
danie.cena=12.95; 
 
printf("Cena dania: %5.2f\n",danie.cena); 
 
printf("Ko

ń

cowa zawarto

ść

 unii %s",danie.nazwa); 

 
getch(); 
 

 
  
przykład powy

ż

szy pokazuje sposób dost

ę

pu do elementów unii; 

ostatnia instrukcja printf jest dowodem nakładania w pami

ę

ci 

elementów unii na siebie; 
 
potwierdzaj

ą

 to dwa poni

ż

sze przykłady: 

 
//p_89 
 
#include <stdio.h>#include <string.h>#include <conio.h>void 
main(void){ union menu { char nazwa[20]; double cena; } danie; 
clrscr(); printf("Zawarto

ść

 unii\n"); danie.cena=12.95; 

 
printf("Cena dania: %5.2f\n",danie.cena); 
 
strcpy(danie.nazwa,"kotlet schabowy"); 
 
printf("Nazwa dania: %s\n",danie.nazwa); 
 
printf("Ko

ń

cowa zawarto

ś

c unii %s\n",danie.nazwa); 

 
printf("Cena dania: %5.2f\n",danie.cena); 
 
getch(); 
 

 
  
 
//p_90 
 

background image

 

161 

#include <stdio.h>#include <string.h>#include <conio.h>void 
main(void){ union menu { char nazwa[20]; double cena; } danie; 
clrscr(); printf("Zawarto

ś

c unii\n"); danie.cena=12.95; 

printf("Cena dania: %5.2f\n",danie.cena); 
strcpy(danie.nazwa,"kotlet schabowy"); 
 
printf("Nazwa dania: %s\n",danie.nazwa); 
 
printf("Koäcowa zawarto

ść

 unii %5.2f ",danie.cena); 

 
getch(); 
 

 
  
 
Inicjowanie unii 
 
Elementy danych unii nakładaj

ą

 si

ę

 nawzajem na siebie w 

obr

ę

bie tego samego obszaru pami

ę

ci. Obszar ten jest 

wykorzystywany do zapisu ró

ż

nych danych w ró

ż

nym czasie. 

Rozmiar unii odpowiada rozmiarowi najwi

ę

kszego spo

ś

ród jej 

elementów. Daltego nie ma sensu inicjowanie wszystkich 
elementów unii jednoczesnie, poniewa

ż

 warto

ść

 ostatnio 

inicjowanego elementu nadpisze si

ę

 na warto

ść

 poprzednich. 

Element unii inicjuje si

ę

 tylko wtedy gdy jeste

ś

my gotowi do 

jego wykorzystania. Bie

żą

ca warto

ść

 zawarta w unii jest zawsze 

warto

ś

cia ostatniego elementu przypisanego unii. 

 
union u { 
 
char ch; 
 
int x; 
 
} n_unia; 
 
  
 
n_unia.ch=’H’; 
 
n_unia.x=365; 
 
 
najpierw pami

ę

c przeznaczona na elementy unii zawierała ‘H’ 

potem warto

ś

c 365. 

 
union u { 
 
char ch; 
 

background image

 

162 

int x; 
 
} n_unia = {‘H’); 
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
co si

ę

 stanie gdy zainicjujemy wszystkie elementy unii 

jednoczesnie ? 
 
//p_91 
 
#include <stdio.h>#include <string.h>#include <conio.h>void 
main(void){ union sprawa { int rok; int dzial; int id; } info; 
info.rok=1999; info.dzial=234; info.id=1234; clrscr(); 
printf("Rok: %d\n",info.rok); 
 
printf("Numer dziaˆu: %d\n",info.dzial); 
 
printf("Numer identyfikacyjny: %d\n",info.id); 
 
getch(); 
 

 
  
 
wynik jest oczywisty à 1234 
 
  
 
  
 
Rozmiar unii 
 

background image

 

163 

Wielko

ść

 unii jest równa obszarowi zajmowanemu przez 

najwi

ę

kszy jej element. 

 
W przeciwie

ń

stwie do unii, w strukturze wszystkie elementy 

(pola) struktury mog

ą

 by

ć

 zainicjowane jednocze

ś

nie i nie 

nakładaja si

ę

 nawzajem. Dzieje si

ę

 tak dlatego, 

ż

e ka

ż

dy 

element struktury ma własny obszar pami

ę

ci. Rozmiar struktury 

to suma rozmiarów wszystkich jej elementów (pól), a nie jak w 
przypadku unii rozmiar jej najwi

ę

kszego elementu. 

 
Pokazuje to przykład: 
 
  
 
//p_92 
 
#include <stdio.h>#include <string.h>#include <conio.h> 
 
void main(void) 
 

 
union u 
 

 
double x; 
 
int y; 
 
} a_union; 
 
struct s 
 

 
double x; 
 
int y; 
 
} a_struct; 
 
clrscr(); 
 
printf("Rozmiar double: %d-bajtowe \n",sizeof(double)); 
 
printf("Rozmiar int : %d-bajtowe \n",sizeof(int)); 
 
printf("Rozmiar unii a_union: %d-bajtowe \n",sizeof(a_union)); 
 

background image

 

164 

printf("Rozmiar struktury a_struct: %d-bajtowe 
\n",sizeof(a_struct)); 
 
getch(); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Zastosowania unii 
 
Odwoływanie si

ę

 do tego samego obszaru pami

ę

ci na dwa ró

ż

ne 

sposoby 
 
Np.: 
 
//p_93 
 

background image

 

165 

#include <stdio.h>#include <string.h>#include <conio.h>union u 
{ char ch[2]; int num; };int InicjalizacjaUnii(union u 
val);void main(void){ union u val; 
 
int x; 
 
x=InicjalizacjaUnii(val); 
 
clrscr(); 
 
printf("Dwie stałe znakowe zawarte w unii: \n"); 
 
printf("%c \n",x & 0x00FF); /*młodszy bajt*/ 
 
printf("%c \n",x>>8); /*starszy bajt*/ 
 
getch(); 
 

 
int InicjalizacjaUnii(union u val) 
 

 
val.ch[0]='H'; 
 
val.ch[1]='i'; 
 
return val.num; /*posługujemy sie elementem numerycznym unii 
*/ 
 
/*do przesłania danych do f. main()*/ 
 

 
  
 
  
 
  
 
  
 
  
 
Uelastycznienie struktur 
 
  
 
Zagnie

ż

dzenie unii wewn

ą

trz struktury powoduje, 

ż

e w polach 

struktur mog

ą

 by

ć

 przechowywane dane ró

ż

nych typów. 

background image

 

166 

 
Przykład: 
 
//p_94 
 
#include <stdio.h>#include <conio.h>#include <string.h>struct 
ankieta { char name[20]; char c_d_p; int wiek; int 
hour_per_week; union { char cable[16]; char sat[16]; 
 
} dostawca; 
 
}; 
 
void DataEnter(struct ankieta *s); 
 
void DataDisplay(struct ankieta *s); 
 
void main(void) 
 

 
struct ankieta tv; 
 
clrscr(); 
 
DataEnter(&tv); 
 
DataDisplay(&tv); 
 
getch(); 
 

 
void DataEnter(struct ankieta *ptr) 
 

 
char jest_tak[4]; 
 
printf("Czy korzystasz w domu z telewizji kablowej T/N \n"); 
 
gets(jest_tak); 
 
if ((jest_tak[0]=='T')||(jest_tak[0]=='t')) 
 

 
printf("Wpisz nazw

ę

 firmy dostawcy TV kablowej: \n"); 

 
gets(ptr->dostawca.cable); 
 

background image

 

167 

ptr->c_d_p='c'; 
 

 
else 
 

 
printf("Czy korzystasz z TV sat T/N \n"); 
 
gets(jest_tak); 
 
if((jest_tak[0]=='T')||(jest_tak[0]=='t')) 
 

 
printf("Wpisz nazwe firmy diostwcy TV sat \n"); 
 
gets(ptr->dostawca.sat); 
 
ptr->c_d_p='d'; 
 

 
else 
 
ptr->c_d_p='p'; 
 

 
printf("Wpisz swoje nazwisko: \n"); 
 
gets(ptr->name); 
 
printf("i sw˘j wiek: \n"); 
 
scanf("%d",&ptr->wiek); 
 
printf("Ile godzin tygodniowo ogl

ą

dasz TV : \n"); 

 
scanf("%d",&ptr->hour_per_week); 
 

 
  
 
void DataDisplay(struct ankieta *ptr) 
 

 
printf("\nOto dane, kt˘re wprowadziłe

ś

: \n"); 

background image

 

168 

 
printf("Nazwisko: %s\n",ptr->name); 
 
printf("Wiek: %d \n",ptr->wiek); 
 
printf("Godzin tygodniowo: %d\n",ptr->hour_per_week); 
 
if(ptr->c_d_p=='c') 
 
printf("Twoja firma TV kablowej :%s\n",ptr->dostawca.cable); 
 
else 
 
if(ptr->c_d_p=='d') 
 
printf("Twoja firma TV Sat: %s \n",ptr->dostawca.sat); 
 
else 
 
printf("Niekorzystasz ani z kabla ani z TV sat\n"); 
 
printf("Dzi

ę

kujemy -- Koniec aniekty! \n"); 

 

 
  
 
  
 
  
 
Definiowanie pól bitowych przy pomocy słowa kluczowego struct 
 
Typ char to najmniejszy typ danych w j

ę

zyku C. Dane te zajmuja 

8 bitów. 
 
Jednak posługuj

ą

c si

ę

 słowem kluczowym struct mo

ż

na 

zadeklarowa

ć

 obiekt jeszcze mniejszy - pole bitowe /bit 

field/. 
 
Pole bitowe umo

ż

liwia łatwy dost

ę

p do pojedynczych bitów. 

Pojedynczy bit mo

ż

e przyjmowa

ć

 jedna z warto

ś

ci 0 lub 1. 

 
  
 
Format deklaracji: 
 
struct nazwa { 
 
data_typ_1 nazwa1: dlugosc1; 
 

background image

 

169 

data_typ_2 nazwa2: dlugosc2; 
 
..................................................... 
 
data_typ_N nazwanN: dlugoscN; 
 
} lista_zmiennych; 
 
struct - słowo kluczowe 
 
nazwa - nazwa typu zmiennych 
 
data_typ_i - typ danych kolejnego pola bitowego (musi by

ć

 

jednym z typów : int, unsigned, signed) 
 
nazwai - nazwy poszczególnych pól bitowych 
 
długosci – długo

ś

ci poszczególnych pól bitowych, które nie 

mog

ą

 przekraczac długo

ś

ci typu danych int 

 
lista_zmiennych - wyliczenie zmiennych danego typu 
 
  
 
struct bf { 
 
int jumper1: 1; 
 
int jumper2: 2; 
 
int jumper3: 3; 
 
} jumpers; 
 
jumper1 jumper2 jumper3 trzy pola bitowe o długo

ś

ciach 

odpowiednio: 1, 2, 3 bity 
 
zmienna o nazwie jumpers jest struktur

ą

 zawieraj

ą

ca trzy pola 

bitowe. 
 
  
 
jumper1 jumepr2 jumper3 
 
 
  
 
//p_95 
 
#include <stdio.h>#include <conio.h>#include <string.h>struct 
bit_field 

background image

 

170 

 

 
int cable: 1; 
 
int sat: 1; 
 
}; 
 
struct ankieta 
 

 
char name[20]; 
 
struct bit_field c_d; 
 
int wiek; 
 
int hour_per_week; 
 
union 
 

 
char cable[16]; 
 
char sat[16]; 
 
} dostawca; 
 
}; 
 
void DataEnter(struct ankieta *s); 
 
void DataDisplay(struct ankieta *s); 
 
void main(void) 
 

 
struct ankieta tv; 
 
clrscr(); 
 
DataEnter(&tv); 
 
DataDisplay(&tv); 
 
getch(); 
 

background image

 

171 


 
void DataEnter(struct ankieta *ptr) 
 

 
char jest_tak[4]; 
 
printf("Czy korzystasz w domu z telewizji kablowej T/N \n"); 
 
gets(jest_tak); 
 
if ((jest_tak[0]=='T')||(jest_tak[0]=='t')) 
 

 
printf("Wpisz nazw

ę

 firmy dostawcy TV kablowej: \n"); 

 
gets(ptr->dostawca.cable); 
 
ptr->c_d.cable=1; 
 
ptr->c_d.sat=0; 
 

 
else 
 

 
printf("Czy korzystasz z TV sat T/N \n"); 
 
gets(jest_tak); 
 
if((jest_tak[0]=='T')||(jest_tak[0]=='t')) 
 

 
printf("Wpisz nazwe firmy diostwcy TV sat \n"); 
 
gets(ptr->dostawca.sat); 
 
ptr->c_d.cable=0; 
 
ptr->c_d.sat=1; 
 

 
else 
 

background image

 

172 

 
ptr->c_d.cable=0; 
 
ptr->c_d.sat=0; 
 

 

 
printf("Wpisz swoje nazwisko: \n"); 
 
gets(ptr->name); 
 
printf("i swój wiek: \n"); 
 
scanf("%d",&ptr->wiek); 
 
printf("Ile godzin tygodniowo ogl

Ą

dasz TV : \n"); 

 
scanf("%d",&ptr->hour_per_week); 
 

 
  
 
void DataDisplay(struct ankieta *ptr) 
 

 
printf("\nOto dane, które wprowadziłe

ś

: \n"); 

 
printf("Nazwisko: %s\n",ptr->name); 
 
printf("Wiek: %d \n",ptr->wiek); 
 
printf("Godzin tygodniowo: %d\n",ptr->hour_per_week); 
 
if(ptr->c_d.cable && !ptr->c_d.sat) 
 
printf("Twoja firma TV kablowej :%s\n",ptr->dostawca.cable); 
 
else 
 
if(!ptr->c_d.cable && ptr->c_d.sat) 
 
printf("Twoja firma TV Sat: %s \n",ptr->dostawca.sat); 
 
else 
 
printf("Nie korzystasz ani z kabla ani z TV sat\n"); 
 

background image

 

173 

printf("Dzi©kujemy -- Koniec aniekty! \n"); 
 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Operacje na plikach dyskowych 
 
Plik  
 
Poj

ę

cie pliku odnosi si

ę

 do urz

ą

dzenia peryferyjnego 

(terminal, drukarka, plik na ta

ś

mie, plik na dysku) z którym 

ma nast

ą

pi

ć

 wymiana informacji. 

 
Przed rozpocz

ę

ciem procesu wymiany informacji plik nale

ż

otworzy

ć

, za

ś

 po zako

ń

czeniu tego procesu nale

ż

y go zamkn

ąć

 
Strumie

ń

 

 
Przepływ danych z programu do pliku lub odwrotnie nazywamy 
strumieniem danych. 
 
Strumie

ń

 stanowi seri

ę

 bajtów.  

background image

 

174 

 
Strumie

ń

 nie jest zwi

ą

zany z 

ż

adnym urz

ą

dzeniem. 

 
Aby przeprowadzi

ć

 operacj

ę

 wej

ś

cia/wyj

ś

cia nale

ż

y skojarzy

ć

 

plik ze strumieniem. 
 
Istniej

ą

 dwa formaty strumieni : 

 
1/ Strumie

ń

 tekstowy - zawiera sekwencje znaków; stosowany do 

przesyłania danych tekstowych; 
 
2/ Strumie

ń

 binarny - stanowi seri

ę

 bajtów (np. plik exe); 

Stosowany do danych nietektowych; 
 
Buforowanie wej

ś

cia/wyj

ś

cia 

 
Buforem nazywamy obszar pami

ę

ci słu

żą

cy do tymczasowego 

przechowywania danych przed przesłaniem ich do miejsca 
przeznaczenia. 
 
Strumienie wej

ś

cia/wyj

ś

cia s

ą

 buforowane w sposób domy

ś

lny. 

 
Buforowane wej

ś

cie/wyj

ś

cie na zywane jest obsług

ą

 We/Wy 

wysokiego poziomu, za

ś

 nie buforowane wej

ś

cie/wyj

ś

cie obsług

ą

 

We/Wy niskiego poziomu. 
 
  
 
  
 
  
 
  
 
Podstawy operacji We/Wy 
 
Wska

ź

niki typu FILE 

 
Struktura FILE słu

ż

y do zarz

ą

dzania plikami, zdefiniowana w 

pliku nagłówkowym stdio.h. 
 
Wska

ź

nik typu FILE jest wska

ź

nikiem plikowym i jest 

wykorzystywany przez strumie

ń

 do sterowania operacjami We/Wy . 

 
FILE *fptr; 
 
W obr

ę

bie struktury FILE znajduje si

ę

 wska

ź

nik pozycji w 

pliku, który wskazuje bie

żą

c

ą

 pozycje podczas operacji 

zapisu/odczytu danych. 
 
Otwieranie pliku 

background image

 

175 

 
Funkcja fopen() pozwala na otwarcie pliku i skojarzenie go ze 
strumieniem danych. Wymaga ona podania dwóch argumentów: trybu 
otwarcia i nazwy przedmiotowego pliku. 
 
#include <stdio.h> 
 
FILE *fopen(const char *filename, const char *mode); 
 
filename - nazwa pliku do otwarcia /wska

ź

nik do stałego 

ła

ń

cucha znaków/ 

 
mode - tryb otwarcia pliku /wska

ź

nik do stałego ła

ń

cucha 

znaków/ 
 
Funkcja zwraca wska

ź

nik typu FILE.  

 
Je

ż

eli wystapi bł

ą

d otwarcia , funkcja zwraca wska

ź

nik pusty. 

 
Tryby otwarcia pliku – mode 
 
r - otwiera istniej

ą

cy plik tekstowy tylko do odczytu 

 
w - tworzy nowy plik tekstowy do zapisu 
 
a - otwiera istniej

ą

cy plik tekstowy w trybie dopisywania do 

ko

ń

ca pliku 

 
r+ - otwiera istniej

ą

cy plik tekstowy do odczytu i/lub zapisu 

 
w+ - tworzy plik tekstowy do zapisu i/lub odczytu 
 
a+ - otwiera lub tworzy plik tekstowy do dopisywania na ko

ń

cu 

 
rb - otwiera istniej

ą

cy plik binarny do odczytu 

 
wb - tworzy nowy plik binarny do zapisu 
 
ab - otwiera istneij

ą

cy plik binarny w trybie dopisywania do 

ko

ń

ca pliku 

 
r+b - otwiera istniej

ą

cy plik binarny dla odczytu i/lub zapisu 

 
w+b - tworzy plik binarny do zapisu i/lub zapisu 
 
a+b - otwiera lub tworzy plik binarny do dopisywania na ko

ń

cu 

 
próba otwarcia pliku test.txt 
 
FILE *fprt; 
 

background image

 

176 

if ((fptr = fopen(”test.txt”,”r”))==NULL) 
 

 
printf(”Nie mog

ę

 otworzy

ć

 pliku test.txt \n”); 

 
exit(1); 
 

 
......... 
 
  
 
Zamykanie pliku 
 
Po wykonaniu operacji na otwartym pliku dyskowym (r,w,a), 
nale

ż

y odł

ą

czy

ć

 plik od strumienia danych – zamkn

ąć

 go à 

fclose(). 
 
#include <stdio.h> 
 
int fclose(FILE *pointer); 
 
pointer - wska

ź

nik skojarzony ze strumieniem do otwartego 

pliku. 
 
Je

ż

eli operacja zamkni

ę

cia powiedzie si

ę

 funkcja zwraca 0, w 

przeciwnym razie zwraca kod EOF, lub kod bł

ę

du je

ż

eli 

dyskietka z plikiem została wyj

ę

ta z nap

ę

du b

ą

d

ż

 brak jest 

miejsca na dysku 
 
Otwarcie i zamkni

ę

cie pliku dyskowego.  

 
//p_96 
 
  
 
/* Otwarcie i zamkni

ę

cie pliku */#include <stdio.h> enum 

{SUCCESS, FAIL};main(void){ FILE *fptr; char filename[]= 
"haiku.txt"; int reval = SUCCESS; clrscr(); 
 
if ((fptr = fopen(filename, "r")) == NULL){ 
 
printf("Nie mog

ę

 otworzy

ć

 %s.\n", filename); 

 
reval = FAIL; 
 
} else { 
 
printf("Warto

ść

 fptr: 0x%p\n", fptr); 

background image

 

177 

 
fclose(fptr); 
 
getch(); 
 

 
 
return reval; 
 

 
------------------------- 
 
#include <stdio.h>enum {SUCCESS, FAIL};int CharRead(FILE 
*fin);main(void){ FILE *fptr; char filename[]= "haiku.txt"; 
int reval = SUCCESS; clrscr(); if ((fptr = fopen(filename, 
"r")) == NULL){ printf("Nie mog

ę

 otworzy

ć

 %s.\n", filename); 

 
reval = FAIL; 
 
} else { 
 
printf("\nIlo

ść

 znaków -> %d.\n", 

 
CharRead(fptr)); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
int CharRead(FILE *fin) 
 

 
int c, num; 
 
 
num = 0; 
 
while ((c=fgetc(fin)) != EOF) 
 

 
putchar(c); 

background image

 

178 

 
++num; 
 
}  
 
 
return num; 
 

 
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Odczyt i zapis plików dyskowych 
 
Sposoby przeprowadzania operacji wej

ś

cia/wyj

ś

cia : 

 
1/ czyta

ć

 i pisa

ć

 znak po znaku 

 
2/ czyta

ć

 i pisa

ć

 wiersz po wierszu 

 
3/ czyta

ć

 i pisa

ć

 blok po bloku 

 
Odczyt i zapis po znaku 
 
Funkcje fgetc() i fputc() mo

ż

na zastosowac do odczytu i zapisu 

znak po znaku. 
 
  
 
#include <stdio.h> 
 
int fgetc(FILE *stream); 
 
stream - wska

ź

nik do pliku, który jest skojarzony ze 

strumieniem danych 
 
Funkcja fgetc() wczytuje kolejny znak ze strumienia stream.  
 

background image

 

179 

Po przekształceniu wczytanego znaku na kod numeryczny int 
funkcja zwraca t

ę

 warto

ść

 
  
 
#include <stdio.h> 
 
int fputc(int c, FILE *stream); 
 
int c - numeryczny kod znaku c; 
 
  
 
Odczyt i zapis metod

ą

 znak po znaku 

 
//p_97 
 
/* Czytanie i pisanie znak po znaku */ 
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL}; 
 
void CharReadWrite(FILE *fin, FILE *fout); 
 
main(void) 
 

 
FILE *fptr1, *fptr2; 
 
char filename1[]= "outhaiku.txt"; 
 
char filename2[]= "haiku.txt"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr1 = fopen(filename1, "w")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s.\n", filename1); 

 
reval = FAIL; 
 
} else if ((fptr2 = fopen(filename2, "r")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s.\n", filename2); 

 
reval = FAIL; 
 

background image

 

180 

} else { 
 
CharReadWrite(fptr2, fptr1); 
 
fclose(fptr1); 
 
fclose(fptr2); 
 

 
getch(); 
 
return reval; 
 

 
/* definicja funkcji */ 
 
void CharReadWrite(FILE *fin, FILE *fout) 
 

 
int c; 
 
 
while ((c=fgetc(fin)) != EOF){ 
 
putchar(c); 
 
fputc(c, fout); 
 

 

 
 
 
----------------------- 
 
  
 
  
 
#include <stdio.h> 
 
#include <string.h> 
 
enum {SUCCESS, FAIL, MAX_LEN = 80}; 
 
void LineWrite(FILE *fout, char *str); 
 

background image

 

181 

main(void) 
 

 
FILE *fptr; 
 
char str[MAX_LEN+1]; 
 
char filename[32]; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
printf("Podaj nazw

ę

 pliku:\n"); 

 
gets(filename); 
 
 
printf("Wprowad

ź

 ła

ń

cuch znak˘w :\n"); 

 
gets(str); 
 
if ((fptr = fopen(filename, "w")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s dla zapisu.\n", filename); 

 
reval = FAIL; 
 
} else { 
 
LineWrite(fptr, str); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
/* definicja funkcji */ 
 
void LineWrite(FILE *fout, char *str) 
 
{  
 
fputs(str, fout); 
 

background image

 

182 

printf("OK!\n"); 
 

 
  
 
Odczyt i zapis wiersz po wierszu 
 
Mo

ż

na przeprowadzi

ć

 zarówno zapis jak i odczyt wiersz po 

wierszu. 
 
Słu

żą

 do tego celu funkcje fgets() i fputs(). 

 
#include <stdio.h> 
 
char *fgets((char *s, int n, FILE *stream); 
 
s - wska

ź

nik do tablicy znakowej u

ż

ywanej do zapami

ę

tania 

znaków wczytanych z otwartego pliku wskazanego przez wska

ź

nik 

stream. 
 
stream - wska

ź

nik do pliku 

 
n – maksymalna ilo

ść

 elementów tablicy znakowej /l. znaków w 

wierszu/ 
 
Je

ż

eli operacja wczytania wiersza zako

ń

czy si

ę

 powodzeniem , 

funkcja zwraca wska

ź

nik char *s. Je

ż

eli funkcja napotka znak 

ko

ń

cz apliku EOF funkcja zwraca pusty wska

ź

nik i pozostawia 

tablic

ę

 znakowa w stanie nienaruszonym. Je

ż

eli wyst

ą

pi bł

ą

d, 

funkcja zwraca pusty wska

ź

nik, ale zawarto

ść

 tablicy jest tym 

razem nieokre

ś

lona. 

 
Funkcja fgets() mo

ż

e wczyta

ć

 n-1 znaków i mo

ż

e doł

ą

czy

ć

 znak 

ko

ń

ca ła

ń

cucha tekstowego ‘\0’ po wczytaniu ostatniego znaku, 

dopóki nie napotka znaku przej

ś

cia do nowego wiersza lub znaku 

ko

ń

ca pliku /EOF/. 

 
Po napotkaniu znaku przej

ś

cia do nowego wiersza funkcja wł

ą

czy 

go do wyj

ś

ciowej tablicy znakowej. 

 
#include <stdio.h> 
 
int fputs(const char *s, FILE *stream); 
 
s - wskazuje tablic

ę

 znakow

ą

, wktórej znajduje si

ę

 tekst 

przeznaczony do zapisu w pliku dyskowym skojarzonym ze 
wska

ź

nikiem plikowym stream. 

 
  
 

background image

 

183 

Odczyt i zapis metoda wiersz po wierszu 
 
//p_98 
 
  
 
/* Czytanie i zapis wierszami */ 
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL, MAX_LEN = 81}; 
 
void LineReadWrite(FILE *fin, FILE *fout); 
 
main(void) 
 

 
FILE *fptr1, *fptr2; 
 
char filename1[]= "outhaiku.txt"; 
 
char filename2[]= "haiku.txt"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr1 = fopen(filename1, "w")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s dla zapisu.\n", filename1); 

 
reval = FAIL; 
 
} else if ((fptr2 = fopen(filename2, "r")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s dla odczytu.\n", filename2); 

 
reval = FAIL; 
 
} else { 
 
LineReadWrite(fptr2, fptr1); 
 
fclose(fptr1); 
 
fclose(fptr2); 
 

 
getch(); 

background image

 

184 

 
return reval; 
 

 
/* definicja funkcji */ 
 
void LineReadWrite(FILE *fin, FILE *fout) 
 

 
char buff[MAX_LEN]; 
 
 
while (!feof(fin)){ 
 
fgets(buff, MAX_LEN, fin); 
 
printf("%s", buff); 
 
fputs(buff, fout); 
 

 

 
 
-------------------- 
 
  
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL}; 
 
void CharWrite(FILE *fout, char *str); 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "test_21.txt"; 
 
char str[]= "Plik dyskowy I/O "; 
 
int reval = SUCCESS; 
 
clrscr(); 
 

background image

 

185 

if ((fptr = fopen(filename, "w")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s.\n", filename); 

 
reval = FAIL; 
 
} else { 
 
CharWrite(fptr, str); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
/* definicja funkcji */ 
 
void CharWrite(FILE *fout, char *str) 
 

 
int i, c; 
 
 
i = 0; 
 
while ((c=str[i]) != '\0'){ 
 
putchar(c); 
 
fputc(c, fout); 
 
i++; 
 

 

 
  
 
  
 
Odczyt i zapis blok po bloku 
 
Do zapisu lub odczytu bloku danych do/z pliku wykorzystywane 
s

ą

 funkcje fread() , fwrite(). 

background image

 

186 

 
#include <stdio.h> 
 
size_t fread(void *ptr, size_t size, size_t n, FILE *stream); 
 
ptr - oznacza wska

ź

nik do tablicy, w której sa przechowywane 

dane wczytane 
 
size - rozmiar ka

ż

dego elementu tablicy 

 
n - liczba elementów do odczytu 
 
stream - wska

ź

nik skojarzony z plikiem otwartym do odczytu 

 
size_t - typ numeryczny całkowity zdefiniowany w pliku 
nagłówkowym stdio.h 
 
Funkcja fread() zwraca liczb

ę

 elementów, które wczytała. 

 
Ilo

ść

 elementów wczytanych przez funkcje powinna by

ć

 równa jej 

trzeciemu argumentowi /chyba 

ż

e zdarzy si

ę

 bł

ą

d lub funkcja 

napotka na znak EOFà w takim przypadku zwróci rzeczywist

ą

 

ilo

ść

 wczytanych elementów/. 

 
#include <stdio.h> 
 
size_t fwrite(const void *ptr, size_t size, size_t n, FILE 
*stream); 
 
ptr – wska

ź

nik do tablicy, wktórej s

ą

 przechowywane dane, 

które nale

ż

y zapisa

ć

 do otwartego pliku wskazanego przez 

wska

ź

nik stream.  

 
Parametr size okre

ś

la wielko

ść

 elementów tablicy. 

 
n - okre

ś

la ilo

ść

 elementów tablicy, które nale

ż

y zapisa

ć

 do 

pliku. 
 
Funkcja zwraca liczb

ę

 rzeczywi

ś

cie zapisanych do pliku 

elementów. 
 
Je

ż

eli nie wystapiły 

ż

adne bł

ę

dy, liczba zwrócona przez 

funkcj

ę

 fwrite() powinna by

ć

 równa jej trzeciemu elementowi. 

Je

ż

eli wyst

ą

pił bł

ą

d to warto

ść

 zwrócona mo

ż

e by

ć

 mniejsza. 

 
Bardzo istotne jest sprawdzenie czy tablica jest wystarczaj

ą

co 

du

ż

a , by pomie

ś

ci

ć

 dane dla funkcji fread() i fwrite(). Dla 

sprawdzenia kiedy nastapi znak ko

ń

ca pliku słuzy funkcja 

feof(). 
 

background image

 

187 

Je

ż

eli w programie stwierdzimy napotkanie znaku ko

ń

ca pliku 

(EOF) w obr

ę

bie pliku binarnego poprzez sprawdzenie warto

ś

ci 

zwróconej przez funkcje fread(), mo

ż

emy zako

ń

czy

ć

 prac

ę

 w 

nieprawidłowym miejscu (nie osi

ą

gn

ą

wszy rzeczywistego ko

ń

ca 

pliku). Zastosowanie funkcji feof() pozwoli unikn

ąć

 bł

ę

dów 

wykrywaj

ą

c rzeczywisty koniec pliku. 

 
#include <stdio.h> 
 
int feof(FILE *stream) 
 
stream - wska

ź

nik plikowy skojarzony z otwartym plikiem. 

 
Funkcja ta zwraca 0 je

ż

eli koniec pliku nie został osi

ą

gni

ę

ty 

, w przeciwnym razie zwraca niezerow

ą

 warto

ść

 całkowit

ą

 
  
 
  
 
  
 
  
 
  
 
Zapis i odczyt bloku znaków 
 
  
 
//p_99 
 
  
 
/* Odczyt i zapis blokami */ 
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL, MAX_LEN = 80}; 
 
void BlockReadWrite(FILE *fin, FILE *fout); 
 
int ErrorMsg(char *str); 
 
main(void) 
 

 
FILE *fptr1, *fptr2; 
 
char filename1[]= "outhaiku.txt"; 

background image

 

188 

 
char filename2[]= "haiku.txt"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr1 = fopen(filename1, "w")) == NULL){ 
 
reval = ErrorMsg(filename1); 
 
} else if ((fptr2 = fopen(filename2, "r")) == NULL){ 
 
reval = ErrorMsg(filename2); 
 
} else { 
 
BlockReadWrite(fptr2, fptr1); 
 
fclose(fptr1); 
 
fclose(fptr2); 
 

 
getch(); 
 
return reval; 
 

 
/* definicja funckji */ 
 
void BlockReadWrite(FILE *fin, FILE *fout) 
 

 
int num; 
 
char buff[MAX_LEN + 1]; 
 
 
while (!feof(fin)){ 
 
num = fread(buff, sizeof(char), MAX_LEN, fin); 
 
buff[num * sizeof(char)] = '\0'; 
 
printf("%s", buff); 
 
fwrite(buff, sizeof(char), num, fout); 

background image

 

189 

 

 

 
/* definicja funkcji */ 
 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
-------------------- 
 
  
 
#include <stdio.h> 
 
#include <string.h> 
 
enum {SUCCESS, FAIL}; 
 
void BlkWrite(FILE *fout, char *str); 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "test_21.txt"; 
 
char str[]= "Plik dyskowy I/O "; 
 
int reval = SUCCESS; 
 
 
if ((fptr = fopen(filename, "w")) == NULL){ 
 
printf("Bł

ą

d otwarcia %s.\n", filename); 

 
reval = FAIL; 
 
} else { 
 
BlkWrite(fptr, str); 

background image

 

190 

 
fclose(fptr); 
 

 
 
return reval; 
 

 
/* definicja funkcji */ 
 
void BlkWrite(FILE *fout, char *str) 
 

 
int num; 
 
 
num = strlen(str);  
 
fwrite(str, sizeof(char), num, fout);  
 
printf("%s\n", str);  
 

 
  
 
  
 
  
 
  
 
  
 
Dostep sekwencyjny i bezpo

ś

redni do pliku. 

 
Zapis/Odczyt pliku od pocz

ą

tku bajt po bajcie, z mo

ż

liwo

ś

cia 

dopisania danych na ko

ń

cu pliku nazywamy dospepem sekwencyjnym 

do pliku, 
 
Poszukiwanie informacji w pliku o taki dost

ę

pie odbywa si

ę

 

poprzez przegl

ą

ganie informacji od pierwszego bajtu zawartego 

w pliku. 
 
W przypadku pliku o dost

ę

pie swobodnym elementy danych mog

ą

 

by

ć

 odczytywane w dowolnej kolejno

ś

ci /bez konieczno

ś

ci 

odczytywania wszystkich poprzednich danych/. 
 

background image

 

191 

Jednym z elementów struktury FILE jest znacznik pozycji pliku, 
który mo

ż

na ustawi

ć

 na poprzedniej pozycji przed operacj

ą

 

zapisu lub odczytu. 
 
Funkcja fseek() - słu

ż

y do przesuwania znacznika pozycji we 

wła

ś

ciwe miejsce w obr

ę

bie pliku. 

 
#include <stdio.h> 
 
int fseek(FILE *stream, long offset, int relation); 
 
stream - wska

ź

nik plikowy skojarzony z otwartym plikiem 

 
offset - oznacza przesuni

ę

cie w bajtach od punktu okre

ś

lonego 

przez trzeci argument 
 
relation - punkt odniesienia, od którego rozpoczyna si

ę

 

odliczania 
 
SEEK_SET - licz

ą

c od pocz

ą

tku pliku 

 
SEEK_CUR - licz

ą

c od bie

żą

cej pozycji znacznika w pliku 

 
SEEK_END - licz

ą

c od ko

ń

ca pliku 

 
je

ż

eli operacja powiedzie si

ę

 funkcja fseek() zwraca 0, w 

przeciwnym przypadku warto

ść

 ró

ż

n

ą

 od zera. 

 
Je

ż

eli 

 
relation = SEEK_SET offset > 0 
 
relation = SEEK_END offset < 0 
 
relation = SEEK_CUR  
 
Aby odczyta

ć

 bie

żą

c

ą

 pozycj

ę

 znacznika w pliku - funkcja 

ftell() 
 
#include <stdio.h> 
 
long ftell(FILE *stream); 
 
stream - wska

ź

nik plikowy skojarzony z otwartym plikiem 

 
Funkcja zwraca bie

żą

c

ą

 warto

ść

 /typu long/ pozycji znacznika 

licz

ą

c do bie

żą

cej pozycji od pocz

ą

tku pliku w bajtach. Je

ż

eli 

wystapi bł

ą

d zwraca  

 
-1L. 
 

background image

 

192 

  
 
Swobodny dost

ę

p do pliku. 

 
  
 
  
 
  
 
  
 
  
 
//p_100 
 
/* Dost

ę

p swobodny do pliku */ 

 
#include <stdio.h> 
 
enum {SUCCESS, FAIL, MAX_LEN = 80}; 
 
void PtrSeek(FILE *fptr); 
 
long PtrTell(FILE *fptr); 
 
void DataRead(FILE *fptr); 
 
int ErrorMsg(char *str); 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "haiku.txt";  
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "r")) == NULL){ 
 
reval = ErrorMsg(filename); 
 
} else { 
 
PtrSeek(fptr); 
 
fclose(fptr); 

background image

 

193 

 

 
getch(); 
 
return reval; 
 

 
void PtrSeek(FILE *fptr) 
 

 
long offset1, offset2, offset3; 
 
 
offset1 = PtrTell(fptr); 
 
DataRead(fptr); 
 
offset2 = PtrTell(fptr); 
 
/* skok do 3 wiersza haiku */ 
 
fseek(fptr, 26L, SEEK_CUR); 
 
offset3 = PtrTell(fptr); 
 
DataRead(fptr); 
 
printf("\nodczyt z haiku:\n"); 
 
/* ponowny odczyt 3 wiersza haiku */ 
 
fseek(fptr, offset3, SEEK_SET); 
 
DataRead(fptr); 
 
/* odczyt 2 wiersza haiku */ 
 
fseek(fptr, offset2, SEEK_SET); 
 
DataRead(fptr); 
 
/* odczyt 1 wiersza haiku */ 
 
fseek(fptr, offset1, SEEK_SET); 
 
DataRead(fptr); 
 
 

background image

 

194 


 
long PtrTell(FILE *fptr) 
 
{  
 
long reval; 
 
 
reval = ftell(fptr); 
 
printf(" fptr jest w %ld\n", reval); 
 
return reval; 
 

 
void DataRead(FILE *fptr) 
 

 
char buff[MAX_LEN]; 
 
fgets(buff, MAX_LEN, fptr); 
 
printf("---%s", buff); 
 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia \n", str); 

 
return FAIL; 
 

 
---------------------- 
 
  
 
#include <stdio.h> 
 
 
enum {SUCCESS, FAIL, MAX_LEN = 80}; 
 
void PtrSeek(FILE *fptr); 
 
long PtrTell(FILE *fptr); 

background image

 

195 

 
void DataRead(FILE *fptr); 
 
int ErrorMsg(char *str); 
 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "LaoTzu.txt";  
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "r")) == NULL){ 
 
reval = ErrorMsg(filename); 
 
} else { 
 
PtrSeek(fptr); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
void PtrSeek(FILE *fptr) 
 

 
long offset1, offset2, offset3; 
 
 
offset1 = PtrTell(fptr); 
 
DataRead(fptr); 
 
offset2 = PtrTell(fptr); 
 
DataRead(fptr); 
 

background image

 

196 

offset3 = PtrTell(fptr); 
 
DataRead(fptr); 
 
printf("\nPonowny odczyt paragrafu:\n"); 
 
/* 3-ej sentencji */ 
 
fseek(fptr, offset3, SEEK_SET); 
 
DataRead(fptr); 
 
/* 2-ej sentencji */ 
 
fseek(fptr, offset2, SEEK_SET); 
 
DataRead(fptr); 
 
/* 1-szej sentencji */ 
 
fseek(fptr, offset1, SEEK_SET); 
 
DataRead(fptr);  
 

 
long PtrTell(FILE *fptr) 
 
{  
 
long reval; 
 
 
reval = ftell(fptr); 
 
printf(" fptr jest w %ld\n", reval); 
 
return reval; 
 

 
void DataRead(FILE *fptr) 
 

 
char buff[MAX_LEN]; 
 
 
fgets(buff, MAX_LEN, fptr); 
 
printf("%s", buff); 

background image

 

197 

 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
  
 
Funkcja rewind() - cofni

ę

cie znacznika pozycji na pocz

ą

tek 

pliku 
 
#include <stdio.h> 
 
void rewind(FILE *stream); 
 
stream - wska

ź

nik plikowy skojarzony z otwartym plikiem 

 
  
 
  
 
Zatem równowa

ż

ne s

ą

 
rewind(ftpr); i fseek(ftpr, 0L, SEEK_SET); 
 
  
 
  
 
Odczyt i zapis danych w trybie binarnym. 
 
Otwarcie instniej

ą

cego pliku binarnego w trybie tylko do 

odczytu. 
 
fprt = fopen(”test.bin”, ”rb”); 
 
  
 
Odczyt i zapis danych binarnych 
 
//p_101 
 
/* Zapis i odczyt danych binarnych */ 
 

background image

 

198 

#include <stdio.h> 
 
enum {SUCCESS, FAIL, MAX_NUM = 3}; 
 
void DataWrite(FILE *fout); 
 
void DataRead(FILE *fin); 
 
int ErrorMsg(char *str); 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "double.bin"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "wb+")) == NULL) 
 

 
reval = ErrorMsg(filename); 
 
} else 
 

 
DataWrite(fptr); 
 
rewind(fptr); 
 
DataRead(fptr); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
void DataWrite(FILE *fout) 
 

background image

 

199 

 
int i; 
 
double buff[MAX_NUM] = { 
 
123.45, 
 
567.89, 
 
100.11}; 
 
 
printf("Wielko

ść

 buff: %d-bajty\n", sizeof(buff)); 

 
for (i=0; i<MAX_NUM; i++){ 
 
printf("%5.2f\n", buff[i]); 
 
fwrite(&buff[i], sizeof(double), 1, fout); 
 

 

 
void DataRead(FILE *fin) 
 

 
int i; 
 
double x; 
 
 
printf("\nCzytanie z pliku binarnego :\n"); 
 
for (i=0; i<MAX_NUM; i++){ 
 
fread(&x, sizeof(double), (size_t)1, fin); 
 
printf("%5.2f\n", x); 
 

 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 

background image

 

200 

return FAIL; 
 

 
--------------------- 
 
  
 
#include <stdio.h> 
 
 
enum {SUCCESS, FAIL, MAX_LEN = 80}; 
 
void PtrSeek(FILE *fptr); 
 
long PtrTell(FILE *fptr); 
 
void DataRead(FILE *fptr); 
 
int ErrorMsg(char *str); 
 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "LaoTzu.txt";  
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "r")) == NULL){ 
 
reval = ErrorMsg(filename); 
 
} else { 
 
PtrSeek(fptr); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

background image

 

201 

 
void PtrSeek(FILE *fptr) 
 

 
long offset1, offset2, offset3; 
 
 
offset1 = PtrTell(fptr); 
 
DataRead(fptr); 
 
offset2 = PtrTell(fptr); 
 
DataRead(fptr); 
 
offset3 = PtrTell(fptr); 
 
DataRead(fptr); 
 
printf("\nCzytanie paragrafu :\n"); 
 
/* 3 sentencja */ 
 
fseek(fptr, offset3, SEEK_SET); 
 
DataRead(fptr); 
 
/* 2 sentencja */ 
 
fseek(fptr, offset2, SEEK_SET); 
 
DataRead(fptr); 
 
/* 1 sentencja */ 
 
rewind(fptr); /* przewini

ę

cie pozycjonera */ 

 
DataRead(fptr); 
 

 
long PtrTell(FILE *fptr) 
 
{  
 
long reval; 
 
 
reval = ftell(fptr); 
 

background image

 

202 

printf(" fptr jest w %ld\n", reval); 
 
return reval; 
 

 
void DataRead(FILE *fptr) 
 

 
char buff[MAX_LEN]; 
 
 
fgets(buff, MAX_LEN, fptr); 
 
printf("%s", buff); 
 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
  
 
  
 
Funkcje fscanf() i fprintf() 
 
Funkcje printf() i scanf() słu

żą

 do zapisu i odczytu 

sformatowanych danych do/z strumieni do plików standardowego 
urz

ą

dzenia We/Wy (stdout,stdin). 

 
Dla plików dyskowych s

ą

 dwa odpowiedniki tych funkcji : 

fprintf() i fscanf(), które dodatkowo pozwalaj

ą

 wybrac 

strumie

ń

 danych wej

ś

cia wyj

ś

cia stream. 

 
#include <stdio.h> 
 
int fscanf(FILE *stream, const char *format, ...); 
 
stream - wska

ź

nik plikowy skojarzony z otwartym plikiem, a 

zastosowanie pozostałych elementów jest takie jak w finkcji 
scanf() 
 

background image

 

203 

Funkcja zwraca liczb

ę

 wczytanych argumentów lub EOF jako wynik 

negatywny. 
 
  
 
#include <stdio.h> 
 
int fprintf(FILE *stream, const char *format, ... ); 
 
stream - wskaxnik plikowy skojarzony z otwartym plikiem, 
zastosowanie pozostałych argumentów jest takie jak w funkcji 
printf(). 
 
Funkcja zwraca liczb

ę

 sformatowanych wyra

ż

e

ń

 lub warto

ść

 

ujemn

ą

 w przypadku negatywnym. 

 
Zastosowanie funkcji fprintf() i fscanf(). 
 
//p_102 
 
/* fscanf() i fprintf() */ 
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL,  
 
MAX_NUM = 3,  
 
STR_LEN = 23}; 
 
void DataWrite(FILE *fout); 
 
void DataRead(FILE *fin); 
 
int ErrorMsg(char *str); 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "strnum.mix"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "w+")) == NULL){ 
 
reval = ErrorMsg(filename); 

background image

 

204 

 
} else { 
 
DataWrite(fptr); 
 
rewind(fptr); 
 
DataRead(fptr); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
void DataWrite(FILE *fout) 
 

 
int i; 
 
char cities[MAX_NUM][STR_LEN] = { 
 
"St.Louis->Houston:", 
 
"Houston->Dallas:", 
 
"Dallas->Philadelphia:"}; 
 
int miles[MAX_NUM] = { 
 
845, 
 
243, 
 
1459}; 
 
 
printf("Zapis danych:\n"); 
 
for (i=0; i<MAX_NUM; i++){ 
 
printf("%-23s %d\n", cities[i], miles[i]); 
 
fprintf(fout, "%s %d", cities[i], miles[i]); 
 

background image

 

205 

 

 
void DataRead(FILE *fin) 
 

 
int i; 
 
int miles; 
 
char cities[STR_LEN]; 
 
 
printf("\nCzytanie danych:\n"); 
 
for (i=0; i<MAX_NUM; i++){ 
 
fscanf(fin, "%s%d", cities, &miles); 
 
printf("%-23s %d\n", cities, miles); 
 

 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
------------------ 
 
  
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL}; 
 
void DataWrite(FILE *fout); 
 
void DataRead(FILE *fin); 
 
int ErrorMsg(char *str); 
 
main(void) 

background image

 

206 

 

 
FILE *fptr; 
 
char filename[]= "data.bin"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = fopen(filename, "wb+")) == NULL){ 
 
reval = ErrorMsg(filename); 
 
} else { 
 
DataWrite(fptr); 
 
rewind(fptr); 
 
DataRead(fptr); 
 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
void DataWrite(FILE *fout) 
 

 
double dnum; 
 
int inum; 
 
 
 
dnum = 123.45; 
 
inum = 10000; 
 
 
printf("%5.2f\n", dnum); 
 
fwrite(&dnum, sizeof(double), 1, fout); 

background image

 

207 

 
printf("%d\n", inum); 
 
fwrite(&inum, sizeof(int), 1, fout); 
 

 
void DataRead(FILE *fin) 
 

 
double x; 
 
int y; 
 
 
printf("\nCzytanie z pliku binarnego:\n"); 
 
fread(&x, sizeof(double), (size_t)1, fin); 
 
printf("%5.2f\n", x); 
 
fread(&y, sizeof(int), (size_t)1, fin); 
 
printf("%d\n", y); 
 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
  
 
  
 
  
 
Funkcja freopen() 
 
Standardowy przepływ strumieni danych mo

ż

na zmieni

ć

 np. tak 

aby strumienie stdin i stdout skojarzy

ć

 z plikami dyskowymi. 

U

ż

ywana do tego celu funkcja freopen(). 

 
#include <stdio.h> 

background image

 

208 

 
FILE *freopen(const char *filename, const char *mode, FILE 
*stream); 
 
const char *filename - wska

ź

nik do stałego ła

ń

cucha znaków, 

nazwy plików 
 
Chodzi tu o ten plik, który nale

ż

y skojarzy

ć

 ze standardowym 

strumieniem (trzeci argument funkcji) 
 
FILE *stream - wska

ź

nik do standardowego strumienia, który 

nale

ż

y skojarzy

ć

 z plikiem. 

 
mode - wska

ź

nik typu *char wskazuj

ą

cy ła

ń

cuch znaków 

okre

ś

laj

ą

cy tryb otwarcia danego pliku dyskowego; argument ten 

mo

ż

e przybiera

ć

 tu te same warto

ś

ci, co w przypadku funkcji 

fopen(); 
 
Funkcja freopen() zwraca pusty wska

ź

nik w przypadku 

wyst

ą

pienia bł

ę

du, w przeciwnym przypadku zwraca standardowy 

strumie

ń

 /wska

ź

nik typu FILE */. Ten standardowy strumie

ń

 

zostaje skojarzony z plikiem zadanym przez pierwszy argument 
funkcji filename. 
 
  
 
  
 
  
 
Skierowanie standardowego strumienia stdout do pliku dyskowego 
 
//p_103 
 
/* Zmiana kierunku przepˆywu standardowego srtumienia danych 
*/ 
 
#include <stdio.h> 
 
enum {SUCCESS, FAIL,  
 
STR_NUM = 4}; 
 
 
void StrPrint(char **str);  
 
int ErrorMsg(char *str); 
 
main(void) 
 
{  

background image

 

209 

 
char *str[STR_NUM] = { 
 
"Be bent, and you will remain straight.", 
 
"Be vacant, and you will remain full.", 
 
"Be worn, and you will remain new.", 
 
"--- by Lao Tzu"}; 
 
char filename[]= "LaoTzu.txt"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
StrPrint(str); 
 
if (freopen(filename, "w", stdout) == NULL) 
 

 
reval = ErrorMsg(filename); 
 
} else 
 

 
StrPrint(str); 
 
fclose(stdout); 
 

 
getch(); 
 
return reval; 
 

 
void StrPrint(char **str) 
 

 
int i; 
 
 
for (i=0; i<STR_NUM; i++) 
 
printf("%s\n", str[i]); 

background image

 

210 

 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
------------------ 
 
  
 
#include <stdio.h> 
 
 
enum {SUCCESS, FAIL,  
 
MAX_NUM = 3,  
 
STR_LEN = 23}; 
 
 
void DataRead(FILE *fin); 
 
int ErrorMsg(char *str); 
 
 
main(void) 
 

 
FILE *fptr; 
 
char filename[]= "strnum.mix"; 
 
int reval = SUCCESS; 
 
clrscr(); 
 
if ((fptr = freopen(filename, "r", stdin)) == NULL){ 
 
reval = ErrorMsg(filename); 
 
} else { 
 
DataRead(fptr); 

background image

 

211 

 
fclose(fptr); 
 

 
getch(); 
 
return reval; 
 

 
void DataRead(FILE *fin) 
 

 
int i; 
 
int miles; 
 
char cities[STR_LEN]; 
 
 
printf("Czytanie danych :\n"); 
 
for (i=0; i<MAX_NUM; i++){ 
 
scanf("%s%d", cities, &miles); 
 
printf("%-23s %d\n", cities, miles); 
 

 

 
int ErrorMsg(char *str) 
 

 
printf("Bł

ą

d otwarcia %s.\n", str); 

 
return FAIL; 
 

 
  
 
  
 
  
 
  

background image

 

212 

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
Preprocesor 
 
 
Preprocesor to specjalny program pozwalaj

ą

cy na definiowanie i 

kojarzenie nazw symboli ze stałymi. Preprocesor jest 
uruchamiany przed kompilatorem. Przed uruchomieniem 
kompilatora preprocesor przetwarza makropolecenia. 
makrodefinicj

ę

 mo

ż

na umie

ś

cic w dowolnym miejscu programu, 

jednak makronazwa musi zosta

ć

 zdefiniowana przed jej pierwszym 

u

ż

yciem w programie. 

 
Preprocesor pozwala równie

ż

 na doł

ą

czanie do kodu 

ź

ródłowego 

programu innych plików 

ź

ródłowych (stdlib.h, 

strung.h,stdio.h). 
 
Preprocesor ma własn

ą

 składni

ę

 
Rozkazy jego rozpoczynaja si

ę

 od znaku # i ko

ń

cz

ą

 znakiem 

przej

ś

cia do nowego wiersza (nie 

ś

rednika jak w j

ę

zyku C); 

 
Preprocesor C pracuje w trybie wiersz-po-wierszu. 
 
Najcz

ęś

ciej u

ż

ywane dyrektywy preprocesora C : 

 
#define - zdefiniuj 
 
#undef - anuluj definicj

ę

 

 

background image

 

213 

#if - je

ż

eli 

 
#elif - w przeciwnym razie, je

ś

li... 

 
#else - w przeciwnym razie 
 
#ifdef - je

ś

li zdefiniowane jest... 

 
#ifndef - je

ś

li nie jest zdefiniowane... 

 
#endif - koniec bloku warunkowego 
 
Makrorozkazy /te, które maja by

ć

 zast

ą

pione stałymi/ s

ą

 

zazwyczaj pisane du

ż

ymi literami. 

 
  
 
  
 
  
 
  
 
Dyrektywy #define #undef 
 
  
 
#define macro_name macro_body 
 
macro_name - identyfikator 
 
macro_body - ła

ń

cuch zło

ż

ony z elementów danych zastepuj

ą

cy 

identyfikator przy ka

ż

dym jego wyst

ą

pieniu w programie 

 
np. 
 
#define MY_NAME ‘Artur’ 
 
#define SUMA (12+3) 
 
Dla anulowania dyrektywy #define słuzy dyrektywa #undef 
 
#undef macro_name 
 
np. 
 
#undef MY_NAME ‘Artur’ 
 
Definiowanie makropolece

ń

 na podobie

ń

stwo funkcji przy pomocy 

dyrektywy #define 
 

background image

 

214 

W makronazwie definiowanej przy pomocy dyrektywy #define , 
mo

ż

na podobnie jak w przypadku funkcji definiowa

ć

 jeden lub 

wi

ę

cej argumentów.  

 
  
 
#define MULTIPLY (val1,val2) ((val1)*(val2)) 
 
rezult = MULTIPLY(2,3) + 10; 
 
Zastosowanie dyrektywy #define 
 
//p_104 
 
  
 
  
 
  
 
  
 
  
 
Zagnie

ż

d

ż

anie makrodefinicji 

 
Uprzednio zdefiniowane makro mo

ż

e by

ć

 zastosowane w nast

ę

pnej 

definicji 
 
#define JEDEN 1 
 
#define DWA (JEDEN + JEDEN) 
 
#define TRZY (JEDEN + DWA) 
 
wynik = DWA + TRZY; 
 
#define SUMA 12 + 8 
 
wynik = SUMA * 10; à 92 
 
#define SUMA (12 + 8) 
 
wynik = SUMA * 10; à 200 
 
  
 
  
 
Kompilacja warunkowa 
 

background image

 

215 

Dyrektywy #infdef i #endif 
wyznaczaj

ą

 pocz

ą

tek i koniec fragmentu kodu 

ź

ródłowego 

decyduj

ą

 czy w/w fragment kodu zostanie skompilowany 

 
#ifdef macro_name 
 
instr1; 
 
instr2; 
 
instr3; 
 
... 
 
#endif 
 
nacro_name - dowolny ła

ń

cuch zdefiniowany dyrektyw

ą

 define 

 
Instrukcje zostan

ą

 skompilowane i wejd

ą

 w skład kodu, je

ż

eli w 

chwili przetwarzania identyfikator macro_name jest 
zdefiniowany. 
 
  
 
Dyrektywa #ifndef 
 
Dyrektywa ta pozwala na warunkow

ą

 kompilacj

ę

 feagmentu kodu 

ź

ródłowego, je

ż

eli okre

ś

lona makronazwa nie jest zdefiniowana. 

 
  
 
#ifndef 
 
instr1; 
 
instr2; 
 
instr3; 
 
... 
 
#endif 
 
Zastosowanie dyrektyw : #ifdef, #ifndef, #endif 
 
//p_105 
 
  
 
  
 

background image

 

216 

Dyrektywy #if, #elif, #else 
 
Dyrektywa #if okre

ś

la warunki ewentualnej kompilacji i 

ą

czenia do kodu wykonywalnego pewnych instrukcji pod 

warunkiem, 

ż

e wyra

ż

enie warunkowe zwróci warto

ść

 niezerow

ą

 

(warunek spełniony). Wyra

ż

enie warunkowe mo

ż

e by

ć

 np. 

wyra

ż

eniem arytmetycznym. 

 
#if wyra

ż

enie 

 
instr1; 
 
instr2; 
 
instr3; 
 
... 
 
#endif 
 
  
 
Przy wyborze jednej z dwu mozliwo

ś

ci : 

 
#if 
 
instr1; 
 
instr2; 
 
instr3; 
 
... 
 
#else 
 
ins1; 
 
ins2; 
 
ins3; 
 
... 
 
#endif 
 
  
 
#ifdef DEBUG 
 
instrukcja1; 

background image

 

217 

 
#else 
 
instrukcja2; 
 
#endif 
 
  
 
#if 1 
 
instr1; à zawsze b

ę

dzie kompilowana  

 
#endif 
 
dyrektywa #elif oznacza to samo co else...if 
 
  
 
Zastosowanie dyrektyw #if #elif #else 
 
  
 
//p_106 
 
  
 
  
 
Zagnie

ż

d

ż

anie bloków kompilacji warunkowej 

 
/standard ANSI C max 8 poziomów/ 
 
#if makro1 
 
#if makro2 
 
#if makro3 
 
instr1; 
 
#else 
 
instr2; 
 
#endif 
 
#else  
 
instr3; 
 

background image

 

218 

#endif 
 
#else 
 
instr4; 
 
#endif 
 
  
 
  
 
  
 
  
 
  
 
Zagnie

ż

d

ż

anie dyrektywy #if 

 
//p_107