background image

sem. II i III

Dr inż. M. Czyżak

Katedra Elektrotechniki Teoretycznej i 

Informatyki

background image

Literatura:
1. A.R. Neubauer, Języki C i C++, Twój pierwszy program, Help, 
W-wa, 1995.
2. C. Sexton, Język C  to proste, RM, W-wa, 2001.
3. G. Perry, Język C w przykładach, Que, W-wa, 2000.
4. Brian W. Kernighan, Dennis M. Ritchie, Język ANSI C, WNT, 
Warszawa, 1994.
5. Andrzej Zalewski, Programowanie w językach C i C++ z 
wykorzystaniem pakietu Borland C++, Nakom, Poznań, 1999
.

background image

Język ANSI C - historia

1972 – definicja języka C– Dennis M. Ritchie

Pierwowzór – beztypowy język B  ( Ken Thompson (1970)) 
będący adaptacją języka BCPL( Basic Combined Programming
Language, Martin Richards(1967) ) dla PDP-7. 

1974- opis języka C – D.M. Ritchie, B.W. Kernighan, The C 
programming language, Prentice-Hall. Standard   K&R.

1988- unowocześniony standard języka C- język ANSI C. Opis

standardu : American National Standard for Information Systems-
Programming Language C, X3.159-1989). Później standard ISO 
9899:1990.

background image

Język ANSI C - wstęp

Zastosowanie:  początkowo  systemy operacyjne, 
oprogramowanie  narzędziowe  ( kompilatory, edytory)  i 
oprogramowanie sieciowe, później oprogramowanie użytkowe. 
Kompilatory dostępne w praktycznie każdym systemie 
operacyjnym. Język C jest podstawowym językiem tworzenia 
oprogramowania dla procesorów sygnałowych i sterujących 
różnego typu urządzeniami (przykład- kompilator Keil C dla 
8051).   

background image

Język ANSI C - wstęp

Cechy języka C  cz I:

Typy:

- typy podstawowe : typy znakowe, całkowite i rzeczywiste

- typy pochodne : wskaźnikowe, tablice, struktury, unie i

inne.

Wyrażenia : budowane z operatorów i ich argumentów

Wskaźniki : operacje na adresach niezależnie od maszyny

background image

Język ANSI C - wstęp

Cechy języka C  cz. II:

Konstrukcje sterujące:

- grupowanie instrukcji (instrukcja złożona) 

- podejmowanie decyzji ( if, if-else, switch)

- realizacja powtarzania ze sprawdzaniem warunku na

początku ( for, while), na końcu ( do-while)

- przerwanie (break) i kontynuacja pętli (continue)

background image

Język ANSI C - wstęp

Cechy języka C  cz III:

Ogólna budowa programu

- program składa z pewnych jednostek programowych  

( fragmentów kodu ) zwanych funkcjami z dobrze 

określonymi mechanizmami komunikacji z otoczeniem;

- program w C posiada tzw. płaską strukturę tzn. funkcje

są niezależne i nie można definiować jednych funkcji w 

drugich.

background image

Język ANSI C - wstęp

Cechy języka C  cz IV:

Funkcje:

- mogą zwracać wartości typów podstawowych, struktury,

unie i wskaźniki;

- zmienne w funkcjach mogą być zmiennymi lokalnymi 

(automatyczne i statyczne) lub zewnętrznymi;

- mogą być wywoływane rekurencyjnie;

- mogą być rozmieszczone w jednym lub większej liczbie 

plików.

background image

Język ANSI C - wstęp

Przykład 1. Prosty program w języku C- wersja 1 

#include <stdio.h>

main()

{

printf("Pierwszy program w języku C");

}

background image

Język ANSI C - wstęp

Przykład 2. Prosty program w języku C- wersja 2 

#include <stdio.h>

#include <conio.h>

main()

{

printf(”Pierwszy program w języku C”);

getch();

}

background image

Język ANSI C - wstęp

Przykład 3. Prosty program w języku C- wersja 3 

/* program ten jest uzupełniony o wybrane elementy*/

#include <stdio.h>

#include <conio.h>

main()

{

clrscr();

printf("Pierwszy program w języku C");

printf("\n napisany przez J. Kowalskiego");

getch();

return 0;

}

background image

Język ANSI C - przykład

Przykład 4. Prosty program z użyciem zmiennych

#include <stdio.h>

#include <conio.h>

main()

{   int a;

int b;

int c;

a=1;

b=2;  

c=a+b;

printf("\n Suma a+b =%d",c);

getch();

return 0;

}

background image

Język ANSI C – pojęcie zmiennej

Zmienna w języku C

Zmienna w języku C z punktu widzenia programisty oznacza 

pewien obszar pamięci komputera, który może być używany przez 
programistę w określony sposób. Np. dla zmiennej a, rozmiar  tego 
obszaru określa typ int ( skrót od integer-całkowity). Typ ten oznacza, że 
w zmiennych tego typu można przechowywać wartości całkowite ( dla 
kompilatora Borland Builder C++ typ int zajmuje 32 bity i można 
przechowywać wartości z  zakresu                       .    Liczby całkowite są 
przechowywane w kodzie U2.

]

1

2

 ,

2

[

31

31

background image

Język ANSI C – operatory

Operatory w języku C 

Operatory to znaki lub kombinacje znaków symbolizujące pewne 

operacje w programie np. =, +, -.   

Operatory służą wraz i innymi elementami do tworzenia tzw. wyrażeń. 

Wyrażenie jest pewną kombinacją operatorów i innych elementów takich 
jak zmienne i stałe.
Przykładami wyrażeń mogą być:

-- jest to wyrażenie składające się z operatora

minus (-) i argumentu ( zmiennej )

-b+– wyrażenie to składa się z operatora plus(+) i

dwóch argumentów (zmienne b)

background image

Język ANSI C – operatory

Operator minus(-) w pierwszym wyrażeniu jest operatorem

jednoargumentowym, a operator plus(+) w drugim wyrażeniu jest 
operatorem dwuargumentowym.

Ogólnie  w języku C operator jednoargumentowy może być użyty w 

sposób następujący:

op argument  lub argument op,

a operator dwuargumentowy

argument1 op argument 2

background image

Język ANSI C – operatory 

Operatory w C można podzielić na następujące grupy:

-operatory arytmetyczne ( np. +,-,*,/, %, ++, --)

-operatory relacyjne (<,<=, ==, >, >=, !=)

-operatory logiczne (&&, ||, !)

-operatory bitowe ( ~, &, |, ^)

-operator funkcyjny  () 

-operator indeksowania [ ]

- operatory adresowy ( &) i dereferencji (*)

background image

Język ANSI C – operatory 

-operator sizeof

-operator warunkowy(?)

-operatory przypisania ( np. =)

-operator rzutowania (typ)

-operator przecinkowy

-operatory bezpośredniego( . ) i pośredniego odwołania do pola 
struktury(->)

background image

Język ANSI C – typy całkowite

Zakresy i rozmiary typów całkowitych

Typ                      Rozmiar(bity)             Zakres liczbowy

unsigned char

8                                     0 do 255

char

8                                -128 do 127

short int

16                          -32768 do 32767

unsigned short int

16                                 0   do 65536

int

32               -2147483648  do  2147483647 

unsigned int

32                                  0  do 4294967295

long int

32                        zakres int 

unsigned long int

32                        zakres unsigned  int

( typ wyliczeniowy enum zostanie omówiony w dalszej części) 

unsigned oznacza typ bez znaku (kod NKB), pozostałe

są przechowywane w kodzie U2.

background image

Język ANSI C – operatory 

Operatory arytmetyki na liczbach całkowitych

(ang. integer arithmetic)

- operatory jednoargumentowe ‘+’ i ‘ –’
- operator dodawania ‘ 

- operator odejmowania ‘-

- operator mnożenia ‘*

- operator dzielenia całkowitego ‘/

- operator obliczania reszty z dzielenia całkowitego

Operatory te są stosowane, gdy argument lub argumenty operatora są 

typu całkowitego.

background image

Język ANSI C – operatory 

/*Przykład 5. Program ilustrujący użycie operatorów   arytmetyki całkowitej

dla liczb ze znakiem*>

#include <stdio.h>
#include <conio.h>
main()
{  int a,b,c;

printf("Podaj a:");
scanf("%d", &a);
printf("\nPodaj b:”);
scanf("%d", &b);
c=a+b;
printf("\n Suma %d + %d =%d", a,b,c);
c=a-b;
printf("\n Roznica %d - %d =%d", a,b,c);
c=a*b;
printf("\n Iloczyn %d * %d =%d", a,b,c);
c=a/b;
printf("\n Iloraz calkowity  %d  przez %d =%d", a,b,c);
c=a%b;
printf("\n Reszta z dzielenia całkowitego %d przez  %d =%d", a,b,c);
getch();
return 0;  } 

background image

Język ANSI C – typy całkowite

Uwaga: ani argumenty ani też rezultaty poszczególnych

działań nie mogą  przekraczać zakresów liczbowych dla 

poszczególnych typów podanych w tabeli. Przykładowo, mnożenie liczb 
65000*40000 da liczbę ujemną. 

Reprezentacja tego iloczynu jest 32-bitowa, stąd najwyższy jej bit 
wchodzi na pozycję znaku, co powoduje, że otrzymany ciąg bitów jest  
traktowany jako liczba ujemna w kodzie U2.

background image

Język ANSI C – typy całkowite

/*Przykład 6. Program ilustrujący użycie operatorów   arytmetyki całkowitej

dla liczb bez znaku*/

#include <stdio.h>
#include <conio.h>
main()
{  unsigned int a,b,c;

printf("Podaj a:");
scanf("%u", &a);
printf("\nPodaj b:");
scanf("%u", &b);
c=a+b;
printf("\n Suma %u + %u =%u", a,b,c);
c=a-b;
printf("\n Roznica %u - %u =%u", a,b,c);
c=a*b;
printf("\n Iloczyn %u * %u =%u", a,b,c);
c=a/b;
printf("\n Iloraz calkowity  %u  przez %u =%u", a,b,c);
c=a%b;
printf("\n Reszta z dzielenia całkowitego %u przez  %u =%u", a,b,c);
getch();
return 0;} 

background image

Język ANSI C – typy całkowite

Przykład 7. Program ilustrujący użycie operatorów   arytmetyki całkowitej

do obliczania wyrażenia 

#include <stdio.h>
#include <conio.h>
#include <math.h>
main()
{  int k,l, licznik, mianownik, wynik;

printf("Podaj k:");
scanf(”%d”, &k);
printf(”\n Podaj l:”);
scanf("%d", &l);
licznik=k*k*k+ k%5 +abs(l);
mianownik=k+ k/(k+l);
wynik=licznik/mianownik;
printf("\n Wartosc wyrazenia=%d", wynik);
getch();
return 0;

l

k

k

k

l

k

k

y

+

+

+

+

=

5

3

background image

Język ANSI C – operatory cz. V

Wartości logiczne w języku C

-Wartość logiczna prawda jest reprezentowana przez każdą 
liczbę różną od zera, np. 1,2, -5.

-Wartość logiczna fałsz jest reprezentowana przez 0.

background image

Język ANSI C – operatory cz. VI

Operatory relacji w języku C

Operatory te to:

‘ < ‘    - mniejsze 
‘ < =‘  - mniejszy lub równe
‘ >‘     - większe
‘ >= ‘  - większe lub równe
‘==‘    - równe  
‘!=‘     - różne

background image

Język ANSI C – operatory cz. IV

Wyrażenie relacyjne

Wyrażenie relacyjne to wyrażenie składające się z operandów 

połączonych pewnym operatorem relacji

op1  operator_relacyjny op2,

np.  a>b, a!=b, a==b.

Wartością wyrażenia relacyjnego jest 1, jeżeli wyrażenie jest prawdziwe 

albo też 0,  gdy wyrażenie jest fałszywe.

background image

Język ANSI C -operatory

Przykład. Prosty program ilustrujący zastosowanie operatorów relacyjnych
#include <stdio.h>
#include <conio.h.>
int main(int argc, char * argv{})
{  int a,b,c;

printf(” Podaj a=:”);
scanf (”%d”, &a);
printf(” Podaj b=:”);
scanf (”%d”, &b);
c=a<b;
printf (”\n Wartosc wyrazenia %d < %d=%d”,a,b,c);
c=a<=b;
printf (”\n Wartosc wyrazenia %d <= %d=%d”,a,b,c);
c=a==b;
prinf (”\n Wartosc wyrazenia %d ==%d=%d”,a,b,c);
c=a>b;
printf (”\n Wartosc wyrazenia %d > %d=%d”,a,b,c);
c=a>=b;
printf (”\n Wartosc wyrazenia %d > =%d=%d”,a,b,c);
c=a!=b;
printf (”\n Wartosc wyrazenia %d != %d=%d”,a,b,c);
getch(); return 0; }

background image

Przykład.  Program uzupełniony o możliwość wielokrotnego wykonania ( nieskończona 
pętla while)

#include <stdio.h>
#include <conio.h.>
int main(int argc, char * argv{})
{  int a,b,c;

while (1) // początek pętli while  

{  

printf(” Podaj a=:”);
scanf (”%d”, &a);
printf(” Podaj b=:”);
scanf (”%d”, &b);
c=a<b;
printf (”\n Wartosc wyrazenia %d < %d=%d”,a,b,c);
c=a<=b;
printf (”\n Wartosc wyrazenia %d <= %d=%d”,a,b,c);
c=a==b;
prinf (”\n Wartosc wyrazenia %d ==%d=%d”,a,b,c);
c=a>b;
printf (”\n Wartosc wyrazenia %d > %d=%d”,a,b,c);
c=a>=b;
printf (”\n Wartosc wyrazenia %d > =%d=%d”,a,b,c);
c=a!=b;
printf (”\n Wartosc wyrazenia %d != %d=%d”,a,b,c);
getch(); 

}                // koniec pętli do while 

return 0; }

background image

Przykład.  Program uzupełniony o możliwość wielokrotnego wykonania (  pętla while  z określoną 
liczbą wykonań ) 
#include <stdio.h>
#include <conio.h.>
int main(int argc, char * argv{})
{  int a,b,c, n, licznik=0;

printf(” Podaj liczbe wykonan petli”); 
scanf(”%d”,&n);

while (licznik <n) {
printf(” Podaj a=:”);
scanf (”%d”, &a);
printf(” Podaj b=:”);
scanf (”%d”, &b);
c=a<b;
printf (”\n Wartosc wyrazenia %d < %d=%d”,a,b,c);
c=a<=b;
printf (”\n Wartosc wyrazenia %d <= %d=%d”,a,b,c);
c=a==b;
prinf (”\n Wartosc wyrazenia %d ==%d=%d”,a,b,c);
c=a>b;
printf (”\n Wartosc wyrazenia %d > %d=%d”,a,b,c);
c=a>=b;
printf (”\n Wartosc wyrazenia %d > =%d=%d”,a,b,c);
c=a!=b;
printf (”\n Wartosc wyrazenia %d != %d=%d”,a,b,c); licznik=licznik+1;
getch(); }

return 0; }

background image

Język ANSI C – operatory cz. VII

Operatory logiczne w języku C

Operatory te to:

‘ ! ‘    - operator negacji
‘&&‘  - operator koniunkcji( iloczynu logicznego)
‘||‘     - operator alternatywy (sumy logicznej)

background image

Język ANSI C – operatory 

Tabela wartości dla operatorów logicznych

x

y

x&&y

x||y

!x

0 (fałsz)

0 (fałsz)

0

0

1

0 (fałsz)

1 (prawda)

0

1

1

1 (prawda)

0 (fałsz)

0

1

0

1 (prawda)

1 (prawda)

1

1

0

background image

Przykład.  Program ilustrujący najprostsze użycie operatorów logicznych. 
#include <stdio.h>
#include <conio.h.>
int main(int argc, char * argv{})
{  int a,b,c, n, licznik=0;

printf(” Podaj liczbe wykonan petli”); 
scanf(”%d”,&n);

while (licznik <n) {
printf(” Podaj a=:”);
scanf (”%d”, &a);
printf(” Podaj b=:”);
scanf (”%d”, &b);
c=a&&b;
printf (”\n Wartosc wyrazenia %d &&%d=%d”,a,b,c);
c=a||b;
printf (”\n Wartosc wyrazenia %d ||%d=%d”,a,b,c);
c=!a;
prinf (”\n Wartosc wyrazenia  !%d=%d”,a,c);
licznik=licznik+1;
getch(); }

return 0; }

background image

Przykład.  Wyrażenia logiczne. Dla obliczenia wartości w poniższych wyrażeniach 
przyjęto x=1, y=4, z=1. 

Wyrażenie

Wartość wyrażenia

x<=1 && y==3

0

x<=1||y==3

1

!(x>1)

1

!x>1

0

!(x<=1||y==3)

0

x>=1&&y==3||z<14

1

background image

Priorytety operatorów cz. I

O kolejności stosowania operatorów w wyrażeniu decyduje ich 

priorytet ( pierwszeństwo). Priorytet operatora decyduje o tym czy 
będzie on użyty przed innymi operatorami czy też po nich. Przykładowo, 
w wyrażeniu

a+b*c

stosowany  jest najpierw operator * , a dopiero później operator +.  
Podobnie w wyrażeniu 

a>b && c<d || e>f

stosowane  są najpierw operatory relacyjne,  później operator && 
następnie operator ||.

Język ANSI C -operatory

background image

Język ANSI C 

Hierarchia operatorów ( dotychczas stosowanych)

Poziom 1 (najwyższy) ‘ ’ , ‘+’ (jednoargumentowy), ‘!
Poziom 2                     ‘ *’, ‘/’, ‘%’  
Poziom 3                     ‘+’, ‘-
Poziom 4                     ‘<‘, ‘<=‘,  ‘>’,’>=‘, 
Poziom 5                      ‘==‘,  ‘!=
Poziom 6                     ‘&&’
Poziom 7                    ‘ ||’
Poziom 8                    ‘=‘

background image

Język ANSI C – identyfikator

Identyfikatory

Pisząc program musimy wybrać nazwy dla zmiennych, funkcji i 

innych obiektów.

-Identyfikator(nazwa) jest sekwencją liter i cyfr o dowolnej 

długości (niektóre kompilatory wprowadzają tu pewne ograniczenia).

-Pierwszy znak identyfikatora musi być literą, przy czym znak 

podkreślenia '_' jest traktowany jako litera. 

-Litery duże i małe są rozróżniane. 

background image

Język ANSI C – identyfikatory

-Służą one do zapisu konstrukcji, jakie są dopuszczalne w  C.

-Identyfikator nie może być słowem kluczowym(niektóre 

identyfikatory zostały zastrzeżone przez twórców języka).

Budowa identyfikatora

Identyfikator w C musi  spełniać następujące wymagania:

a) zaczynać od litery (A do Z, a do z) lub też od znaku

podkreślenia _  ;

b) składać z liter (A do Z, a do z), cyfr lub też znaków

podkreślenia _  ; 

c) nie może być słowem kluczowym (słowo kluczowe to takie

słowo jak  for czy while ).

background image

Język ANSI C – identyfikatory

Przykład. Legalne (dopuszczalne) identyfikatory

ilosc
ilosc_calkowita
_suma
kolumna3
ILOSC

Z wyjątkiem identyfikatorów zewnętrznych (nazw zewnętrznych),
pierwsze 31 znaków każdego identyfikatora to tzw. znaki znaczące
Jeżeli dwa identyfikatory różnią się od 32 znaku, mogą być uznane za 
ten sam identyfikator. Ze względu na to , że rozróżniane są litery małe i 
wielkie identyfikatory  ilosc i ILOSC są różnymi identyfikatorami.

background image

Język ANSI C – identyfikatory

Przykład. Identyfikatory nielegalne (niepoprawne).

ilosc$

(niedopuszczalny znak $)

2_suma

(rozpoczyna się cyfrą)

long

(słowo kluczowe)

druga suma

(w identyfikatorze nie może być

spacji)

ILOSC-CALKOWITA (niedopuszczalny znak -)

background image

Język ANSI C – komentarze 

Komentarze

- Komentarze są ciągami znaków ujętych w znaki /*    */.

- Komentarze są ignorowane przez kompilator.

Przykład.

/*         Komentarz w języku C */

- Komentarze takie mogą obejmować wiele wierszy.

- W komentarzach można używać polskie znaki. 

- Jeśli stosuje się kompilator C++, można też stosować komentarz 
jednowierszowy rozpoczynający się od znaków  //.

background image

Język ANSI C 

W języku ANSI C istnieją następujące słowa kluczowe:

auto

double

int

struct

break

else

long

switch

case

enum

register

typedef

char

extern

return

union

const

float

short

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

static

while

background image

Język ANSI C – typ znakowy

Typ znakowy

-W językach programowania istnieje konieczność 

reprezentowania, oprócz liczb, także znaków, np. liter.

-Znaki  są reprezentowane wewnętrznie w postaci pewnych 

całkowitych nieujemnych  liczb zwanych kodami znaków.

-Sposób przyporządkowania poszczególnym znakom 

odpowiednich liczb zwany jest kodem. Przykłady kodów to np. 
ASCII, EBDIC,  Unicode, 8859-2. 

background image

Język ANSI C – typ znakowy

Kod ASCII 

- Kod ASCII (ang. American Standard Code for Information

Interchange) jest standardowym sposobem kodowania znaków. 

Standardowy oznacza, że jest powszechnie przyjęty przez wytwórców 
różnych urządzeń, aby mogły się ze sobą komunikować. 

- Kodowanie oznacza, że każdemu znakowi odpowiada w tym kodzie 
pewna liczba będąca jej tzw. kodem ASCII.

background image

Język ANSI C – typ znakowy

Kod ASCII 

- W kodzie ASCII znaki o kodach z zakresu [0,127] należą do 

tzw. standardowego zestawu znaków. Kodom z tego zakresu 
odpowiadają te same znaki we wszystkich urządzeniach 
wykorzystujących kod ASCII.

Ogólna budowa kodu ASCII

- Kody z zakresu [0,31] reprezentują tzw. znaki sterujące
np. kod 8 znak BS (ang. backspace), kod 10 znak LF
(ang. Line Feed- nowa linia), kod 13 znak CR (ang. Carriage
Return- powrót karetki, terminologia pochodzi z maszyn do 
pisania). Cyfry są reprezentowane przez kody z przedziału 
[48,57], duże litery z [65,90], a małe litery [97,122].
( kody pozostałych znaków w dostarczonym materiale).   

background image

Język ANSI C – typ znakowy

Typ znakowy

- W  języku C istnieje specjalny typ char o zakresie  [-128,127] 

przeznaczony do operacji  na znakach. Zmienne i stałe tego typu 
zajmują 1 bajt. Zmienne są definiowane w sposób następujący:

char ch;

- W  języku C istnieje szereg funkcji istnieje umożliwiających 

wykonywanie operacji  na znakach takich jak  wprowadzanie znaków z 
klawiatury, wyprowadzanie znaków na ekran i klasyfikacja znaków.

background image

Język ANSI C – typ znakowy

Wejście znakowe(1)

- Znaki mogą być wczytywane z klawiatury przy zastosowaniu 

funkcji pochodzących ze standardowej biblioteki języka C lub też
funkcji dostarczanych przez producentów kompilatorów.

1. Funkcja scanf. 

Przy wczytywaniu znaków konieczne jest zastosowanie deskryptora 

format %c.

printf(” Podaj znak :”);
scanf (”%c”,&ch);

2. Funkcja getchar().

printf(” Podaj znak :”);
ch=getchar();

background image

Język ANSI C – typ znakowy

Wejście znakowe (2)

- Funkcja getch(); 

printf(” Podaj znak :”);
ch=getch();

Wczytywanie znaku przy użyciu scanf i  getchar wymaga Enter po 

wprowadzeniu znaku.

background image

Język ANSI C – typ znakowy

Wyjście znakowe

- Wyprowadzenie znaku na ekran może być zrealizowane w sposób 

następujący

printf(” Znak=%c”, ch);

lub

putchar(ch);

lub

putch (ch);

background image

Język ANSI C – typ znakowy

Przykład. Drukowanie wybranych znaków i ich kodów ASCII.
#include <stdio.h>
#include <conio.h>
main()

{   int  i ;

i=32;

clrscr(); 

while (i<256)
{  

printf(”\n \n Znak =%c  kod  dec=%3d  hex =%x oct=%o”, i , 

i, i, i );

getch();
i++;

}

return 0; 

}

background image

Język ANSI C – typ znakowy

Stałe znakowe

Stała znakowa – ciąg złożony z jednego lub wiekszej liczby 

znaków ujęty w pojedyncze apostrofy np. ‘x’.

Stałe jednoznakowe są typu char, a wieloznakowe typu int. 

Stałe znakowe mogą być używane w operacjach arytmetycznych. 
W  operacjach stosowany jest kod ASCII liczby np..

int cyfra;

cyfra= ‘5’-’0’; 

Faktycznie jest to odejmowanie 53-48, czyli w zmiennej cyfra 

będzie wartość 5. 

background image

Język ANSI C – typ znakowy

Stałe znakowe

Stałe znakowe mogą być zapisywane również przy zastosowaniu 

kodów heksalnych i oktalnych, np. stałą znakową

‘A’ można zapisać także jako ‘\x41’ albo też ‘\101’ . 

Mechanizm ten ma szczególne znaczenie jeżeli chce się 

drukować znaki, które nie występują na klawiaturze. 

background image

Język ANSI C – typ znakowy

Stałe znakowe

Przykładowo, napis ” Róża bez kolców” można 

wydrukować w sposób następujący:

printf("\n R\242\276a bez kolc\242w"); //wersja oktalna

printf("\n R\xa2\xbe a bez kolc\xa2w");// wersja heksalna

W powyższych instrukcjach zastosowano kody oktalne i heksalne
liter ó i ż.   242 i  a2 są kodami ó, a  276 i be litery ż. 

background image

Język ANSI C – typ znakowy

Sekwencje ucieczki ( ang. escape sequences)

Znaki, które nie mają reprezentacji graficznej na 

ekranie monitora lub też mają specjalne znaczenia w 
łańcuchach znaków, mogą być wygenerowane przy użyciu  
tzw. sekwencji ucieczki złożonych z ukośnika \ i 
odpowiedniego znaku.

background image

Język ANSI C – typ znakowy

Tabela sekwencji ucieczki cz. I

Nazwa sekwencji

Symbol

Zapis znakowy

Wartość liczbowa

Nowy wiersz

NL(LF)

\n

10 (dec)

Tabulacja 

pozioma

HT

\t

9(dec)

Tabulacja 

pionowa

VT

\v

11(dec)

Kasowanie znaku 

(backspace)

BS

\b

8(dec)

Powrót karetki

CR

\r

13(dec)

background image

Język ANSI C – typ znakowy

Tabela sekwencji ucieczki cz. II

Nazwa sekwencji

Symbol

Zapis znakowy

Wartość liczbowa

Nowa strona         

( form feed)

FF

\f

12 (dec)

Dzwonek

(alert)

BEL

\a

7(dec)

Lewy ukośnik

\

\\

92(dec)

Znak zapytania

?

\?

63(dec)

Pojedynczy 

apostrof

\’

39(dec)

Podwójny 

apostrof

\”

34(dec)

Znak zerowy

NUL

\0

0

background image

Język ANSI C – typy rzeczywiste

Zakresy i rozmiary typów rzeczywistych

Typ              Rozmiar(bity)      Zakres liczbowy   Liczba cyfr znaczących

float

32                                                            6-7

double

64                                                          15-16

long double

80                                                          19-20

308

308

10

4

.

3

  

do

 

10

7

.

0

38

38

10

4

.

3

 

do

 

10

4

.

3

4932

4932

10

1

.

0

 

do

 

10

4

.

3

background image

Język ANSI C – typy rzeczywiste

Przykład. Program ilustrujący wczytywanie  i drukowanie   zmiennych rzeczywistych   typu 
float, double i long double.
#include <stdio.h>
#include <conio.h>
main()
{  float x; double y; long double z;

printf(”Podaj x:”);
scanf(”%f”, &x); // %f jest deskryptorem formatu stosowanym przy wczytywaniu 

// i drukowaniu zmiennych typu float

printf(”\n Podaj y:”);
scanf(”%lf”, &y);// %lf deskryptor formatu dla zmiennych typu double
printf(”\nPodaj z:”);
scanf(”%Lf”, &z);// %Lf deskryptor formatu dla zmiennych typu long double

printf(”\n x=%f”, x);
printf(”\n y=%f”, y);
printf(”\n z=%Lf”, z);

getch();

return 0;  } 

background image

Język ANSI C – typy rzeczywiste

/*Przykład. Program ilustrujący użycie operatorów   arytmetyki rzeczywistej*/
#include <stdio.h>
#include <conio.h>
main()
{  double a,b,c;

printf(”Podaj a:”);
scanf(”%lf”, &a);
printf(”Podaj b:”);
scanf(”%lf”, &b);
c=a+b;
printf(”\n Suma %f + %f =%f”, a,b,c);
c=a-b;
printf(”\n Roznica %f - %f =%10.2f”, a,b,c);
c=a*b;
printf(”\n Iloczyn %f * %f =%.4f”, a,b,c);
c=a/b;
printf(”\n Iloraz   %e  przez %e =%f”, a,b,c);
getch();
return 0;} 

background image

Język ANSI C – typy rzeczywiste

Formatowanie wydruku liczb rzeczywistych

Formatowanie wydruku to kształtowanie zewnętrznej postaci liczb (na ekranie monitora lub 

na drukarce).  Zakres takiego kształtowania zależy od formatu liczby rzeczywistej czyli sposobu 
jej przechowywania w pamięci komputera. Powszechnie przyjmuje się tzw. formaty standardowe 
zgodne  z pewną normą. Normą tą jest tzw. standard IEEE 754. Standard ten określa cztery 
podstawowe formaty binarne liczb rzeczywistych: 

- zwykły o o pojedynczej precyzji (SINGLE)
- rozszerzony o pojedynczej precyzji (SINGLE EXTENDED)
- zwykły o podwójnej precyzji (DOUBLE)
- rozszerzony podwójnej precyzji (DOUBLE EXTENDED)

s

...........................

...............

E- wykładnik w e-bitowym 
kodzie z obciążeniem +N

f- ułamek ( m-bitowy kod  
modułu mantysy bez bitu 
ukrytego)

background image

Język ANSI C – typy rzeczywiste

W standardzie IEEE 754 wymaga się, aby reprezentacje liczb były znormalizowane( nie dotyczy 
to liczb bardzo bliskich 0). Moduł mantysy         ma być liczbą z przedziału 

i obowiązuje konwencja ukrytej jedynki, co oznacza, że najstarszy bit mantysy jest równy 1, 

jednak nie jest pamiętany.  Każdy moduł ma postać 1.bbb.....b.  Wartość liczby znormalizowanej 
można wyrazić następującą zależnością:

M

2

1

<

≤ M

( )

E

s

f

F

2

)

1

(

1

+

=

background image

Język ANSI C – typy rzeczywiste

Wybrane formaty IEEE 754

Parametr

Symbol

SINGLE

DOUBLE

DOUBLE 

EXTENDED

Rozmiar  formatu

n

32

64

>=79

Rozmiar  mantysy

m

23(+1)

52(+1)

>=64

Rozmiar  wykładnika

e

8

11

>=15

Obciążenie wykladnika

N

127

1023

>=16383

Zakres wykładnika

E

[-126,127] [-1022,1023]

[-(N-1),N]

Dokładność

ulp

Zakres formatu

R

7

23

10

2

15

52

10

2

1

2

+

m

38

128

10

2

308

1024

10

2

4932

16384

10

2

background image

Język ANSI C – typy rzeczywiste

Maksymalna ilość  znaczących cyfr dziesiętnych, które można uzyskać w wydruku wynika z 

wielkości liczb dziesiętnych, która z kolei wynika z przeliczenia maksymalnych wartości 
mantysy na postać dziesiętną. Dla typu SINGLE ( w języku C odpowiada mu typ float)   mantysa 
może reprezentować liczbę dziesiętną o wartości

co umożliwia uzyskanie 6-7 cyfr dziesiętnych. Podobnie

dla typu double mamy

co daje 15-16 cyfr dziesiętnych.

7

23

10

2

15

52

10

2

background image

Język ANSI C – typy rzeczywiste

Dla typu long double mamy

czyli 19-20 cyfr dziesiętnych.

Podstawowe formaty wydruku liczb rzeczywistych w języku C to 

- format stałoprzecinkowy

m.dd..ddd

- format zmiennoprzecinkowy  ( notacja inżynierska)

m.d....d e   xx     lub   m.d....d e    xxxx

( zamiast e może też być stosowane E). 

19

64

10

2

±

±

background image

Język ANSI C – typy rzeczywiste

Wybrane zasady tworzenia opisu formatu w łańcuchu formatującym

(pełny opis w B.W. Kernighan, D.M. Ritchie, Język ANSI C, Dodatek B,

Pkt. B1.2 Formatowanie wyjście)

Przykład.

double x=12.348;

printf(”\n x=%10.2lf”, x);

Opis formatu rozpoczyna się znakiem %, liczba 10 oznacza minimalną szerokość pola wydruku, 
liczba 2 ilość drukowanych miejsc po kropce dziesiętnej, a lf oznacza wydruk wartości typu 
double.

W ogólnym przypadku pomiędzy znakiem % a znakiem przekształcenia mogą wystąpić

- modyfikatory( umieszczane w dowolnej kolejności), które wpływają na postać wydruku:

background image

Język ANSI C – typy rzeczywiste

Modyfikatory te to:

-znak  minus (-) powodujący dosunięcie wydruku do lewego krańca pola

- znak plus (+)  wypisanie liczby zawsze ze znakiem

odstęp poprzedzenie wyniku znakiem odstępu, jeżeli pierwszym drukowanym znakiem nie jest 
plus lub minus

-znak zero (0) uzupełnienie liczby wiodącymi zerami do pełnego rozmiaru pola

Następnym znakiem jest liczba określająca minimalny rozmiar pola. Przekształcony 

argument zostanie wydrukowany w polu o ilości znaków nie mniejszej niż ta liczba. Jeżeli 
argument wymaga szerszego pola, to pole wydruku jest rozszerzane. Jeżeli argument jest krótszy,  
dopełniany jest spacjami z lewej strony (ew. w zależności od modyfikatora z prawej lub zerami).    

Kolejnym znakiem jest kropka, której następuje liczba oznaczająca precyzję czyli ilość cyfr po
kropce dziesiętnej w specyfikacjach f, e i E.

background image

Język ANSI C – typy rzeczywiste

Uwagi dodatkowe o formatach f, e i E

Dla formatu f domyślną precyzją jest 6, przy precyzji zero opuszcza się kropkę dziesiętną.  Dla 
formatu m.dddddde      xx  lub formatu  m.ddddddE    xx  domyślną precyzją jest 6 i przy precyzji 
zero również opuszcza się kropkę dziesiętną.

Przykład. Formaty z zastosowaniem modyfikatorów.

x=25.3485;

printf(”\n x=% 020.4f”,x);// uzupełnienie zerami

printf(”\n x=% +20.4f”,x);// drukowanie znaku liczby

printf(”\n x=% -20.4f”,x);//dosunięcie do lewego krańca pola

Otrzymane wydruki: 

x= 000000000000025.3485

x=                         +25.3485

x= 25.3485

± ±

±

background image

Język ANSI C – typy rzeczywiste

Standard ANSI/ISO C definiuje zawartość i postać standardowej biblioteki języka ANSI 
C. Standard określa zestaw funkcji, w który muszą być wyposażone kompilatory zgodne 
ze standardem. Kompilatory mogą też zawierać funkcje, które nie są określone w 
standardzie. Każda funkcja zdefiniowana w standardowej bibliotece języka C ma 
odpowiadający jej nagłówek, nagłówki te są zawarte w plikach nagłówkowych 
włączanych dyrektywą #include.

Standard C89 zawiera następujące 22 standardowe funkcje arytmetyczne:

acos

cos

fmod

modf

tan

asin

cosh

frexp

pow

tanh

atan

exp

ldexp

sin

atan2

fabs

log

sinh

ceil

floor

log10

sqrt

Arytmetyczne funkcje standardowe ANSI C

background image

Język ANSI C – typy rzeczywiste

acos

double acos (double arg);

long double acosl (long double arg);

Funkcje te obliczają arcus cosinus arg. Argument musi należeć do przedziału [-1,1]. 

Jeżeli argument nie należy do tego przedziału, pojawi się błąd dziedziny (ang. domain
error).

asin
double asin (double arg);
long double asinl (long double arg);

Funkcje te obliczają arcus sinus arg . Argument musi należeć do przedziału [-1,1]. 

Jeżeli argument nie należy do tego przedziału, pojawi się błąd dziedziny (ang. domain
error).

background image

Język ANSI C – typy rzeczywiste

atan

double atan (double arg);

long double atanl (long double arg);

Funkcje  atan and atanl dla argumentu rzeczywistego obliczają wartość arcusa

tangensa (wynik w zakresie  -pi/2 do pi/2). 

double atan2 (double y, double x);
long double atan2l (long double y, long double x);

Funkcje  atan2 and atan2l dla argumentu rzeczywistego obliczają wartość arcusa

tangensa y/x  (wynik w zakresie  -pi/2 do pi/2). 

background image

Język ANSI C – typy rzeczywiste

double ceil (double num);

long double ceill (long double num);

Funkcje  zwracają (obliczają) najmniejszą liczbę całkowitą typu double nie mniejszą niż 
num. 

Np. Dla num 1.05 funkcja zwraca wartość 2.0, a dla -1.05, zwraca -1.0.

double cos (double arg);
double cosl (long double arg);
Funkcja ta zwraca cosinus arg. Kąt jest podawany w radianach. Zwracana wartość w 
zakresie [-1,1].

double cosh (double arg);
long double coshl (long double arg);
Funkcja ta zwraca cosinus hiperboliczny arg

background image

Język ANSI C – typy rzeczywiste

double exp (double num);

long double expl (long double num);

Funkcja oblicza  .

W pewnych sytuacjach argumenty przekazane do tych funkcji powodują nadmiar 
arytmetyczny lub wynik nie może zostać obliczony. Gdy powstaje nadmiar 
arytmetyczny, funkcja exp zwraca  HUGE_VAL a  expl zwraca _LHUGE_VAL. 
Rezultaty o bardzo dużej wartości powodują ustawienie zmiennej globalnej  errno 
na 

ERANGE

Result out of range.

Przy niedomiarze arytmetycznym funkcje te  zwracają 0.0,  errno nie jest zmieniana. 
Traktowanie błędu dla tych funkcji może być zmienione poprzez funkcje _matherr and 
_matherrl.

x

e

background image

Język ANSI C – typy rzeczywiste

/* _matherr example  biblioteka standardowa C++ Builder 6.0*/
// przykład dla zaawansowanych – przechwytywanie i korekcja błędu  
// dziedziny
#include <math.h>
#include <string.h>
#include <stdio.h>

int _matherr (struct _exception *a)
{

if (a->type == DOMAIN)

if (!strcmp(a->name,"sqrt")) {

a->retval = sqrt (-(a->arg1));

return 1;
}

return 0;

}
int main(void)
{

double x = -2.0, y;
y = sqrt(x);
printf("_Matherr corrected value: %lf\n",y);
return 0;

}

background image

Język ANSI C – typy rzeczywiste

double fabs (double num);
long double fabsl (long double num);
Funkcje obliczają wartość bezwzględną argumentu num

double floor (double num);

long double floorl (long double num);

Funkcje te zwracają (obliczają) największą liczbę całkowitą  nie większą niż num.

Np. dla 1.05 funkcja zwraca wartość 1.0, a dla -1.05, zwraca -2.0.

double fmod (double a, double b);
long double fmodl (long double a, long double b);
Funkcje obliczają resztę z dzielenia a/b.

background image

Język ANSI C – typy rzeczywiste

double frexp (double num, int *pexp);
long double frexpl (long double num, int *pexp);
Funkcje te rozkładają liczbę num na mantysę z przedziału [0.5,1.0] oraz wykładnik  
całkowity exp, takie że num=mantysa         .

Przykład.

int exp, mantysa;

double num=0.5;

mantysa=frexp(num,&exp);

double ldexp (double num, int  exp);
long double ldexpl (long double num, int exp);

Funkcje  obliczają wartość wyrażenia num           .

exp

2

exp

2

exp

2

background image

Język ANSI C – typy rzeczywiste

double log (double num);

long double logl (long double num);

Funkcje  obliczają logarytm naturalny z  num. Jeżeli num<0, występuje błąd dziedziny, 

dla num=0 błąd zakresu. 

double log10 (double num);
long double log10l (long double num);

Funkcje  obliczają logarytm dziesiętny z  num. Jeżeli num<0, występuje błąd 

dziedziny, dla num=0 błąd zakresu.

background image

Język ANSI C – typy rzeczywiste

double modf (double num, int *pi);
long double modfl (long double num, int *pi);

Funkcje te rozkładają liczbę num na część całkowitą i część ułamkową.
Funkcja zwraca część ułamkową, a część całkowitą wstawia do zmiennej wskazywanej 
przez wskaźnik pi.
Przykład.

int cz_calkowita,cz_ulamkowa;
double num=0.5;

cz_ulamkowa=modf(num,&cz_calkowita);

double pow(double base, double exp);
long double powl (long double base, long double exp );

Funkcje obliczają wartość base podniesioną do potęgi exp. Reguły obliczania takie jak 
dla funkcji exp. 
Jeżeli argument odpowiadający base przekazany do pow lub powl jest rzeczywisty i
mniejszy od 0, a  argument odpowiadający exp nie jest całkowity lub jeśli argument 
odpowiadający base jest równy 0 a argument odpowiadający exp jest mniejszy od 0, lub 
stosuje się wywołanie pow(0,0), zmienna globalna  errno jest ustawiana na wartość  
EDOM Domain error.                   .

background image

Język ANSI C – typy rzeczywiste

double sin (double arg);
long double sinl (long double arg);
Funkcje te zwracają sinus arg. Kąt jest podawany w radianach. Zwracana wartość w 
zakresie [-1,1].

double sinh (double arg);
long double sinhl (long double arg);
Funkcje te zwracają sinus hiperboliczny arg

double sqrt (double arg);
long double sqrtl (long double arg);
Funkcja ta zwraca dodatni pierwiastek kwadratowy z arg. Jeżeli arg
mniejszy od 0, zmienna globalna  errno jest ustawiana na wartość  EDOM Domain error.

background image

Język ANSI C – typy rzeczywiste

double tan (double arg);
long double tanl (long double arg);
Funkcje te zwracają tangens arg. Wartość arg jest podawana w radianach.

double tanh (double arg);
long double tanhl (long double arg);
Funkcje te zwracają tangens hiperboliczny arg.

background image

Język ANSI C – typy rzeczywiste

⎣ ⎦

x

x

x

ctgz

x

e

tgx

x

y

π

+

+

+

+

+

=

3

2

)

1

(

log

3

sin

log

5

Przykład. Napisać program obliczający dane wyrażenie dla zmiennych  x i z typu double

wprowadzanych z klawiatury. Przy wprowadzaniu danych sprawdzać czy dane 

reprezentują liczby, czy należą do dziedziny oraz czy nie nastąpi przekroczenie zakresu 

typu double.  

background image

Język ANSI C – typy rzeczywiste

#include <stdio.h>
#include <conio.h>
#include <math.h>
int main(int argc, char* argv[])
{   double x,z,p1,p2,p3,p4,p5,p6,q1,q2,q3,licznik,mianownik,wynik;

int k;
printf("\n Podaj x:");
scanf("%lf",&x);
printf("\n Podaj z:");
scanf("%lf",&z);
p1=fabs(sin(x));
p2=log10(p1);
p3=fabs(tan(x));
p3=sqrt(p3);
p4=fabs(pow(x,5));
p5=exp(p4);
p6=floor(pow(3,x));
q1=log10(x-1)/log10(2);
q2=pow(1/tan(z),1/3.0);
q3=pow(M_PI,x);

Przykład. Obliczanie wyrażenia ( wersja bez sprawdzania danych)

background image

Język ANSI C – typy rzeczywiste

// cz.2 programu obliczającego wyrażenie

licznik=p2+p3+p5+p6;

mianownik=q1+q2+q3;
if (mianownik)  {

wynik=licznik/mianownik;
printf("\n Wartosc wyrazenia wynosi=%f",wynik);
getch(); }

else {

printf("\n Dzielenie przez zero");
getch();  }

return 0;
}

background image

Język ANSI C – typy rzeczywiste

Dziedzina: 

a) ze względu na funkcję logarytm w liczniku x musi być różny od wielokrotności pi.       

b) ze względu na funkcję logarytm w mianowniku, musi być x>1.

Ograniczenie na  x wynika też z wartości przybieranych przez człon

Musi być spełniona zależność

Graniczną wartość x możemy określić jako

5

x

e

308

10

5

x

e

71

.

3

10

ln

308

5

=

x

background image

Język ANSI C – typy rzeczywiste

// Fragment programu związany ze sprawdzaniem danych wejściowych
#include <stdio.h>
#include <conio.h>
#include <math.h>
int main(int argc, char* argv[])
{   double x,z,p1,p2,p3,p4,p5,p6,q1,q2,q3,licznik,mianownik,wynik;

int k;
do 

{

printf("\n Podaj x:");
k= scanf("%lf”,&x);
fflush(stdin);
if (k==0) printf(”\n Niewlasciwy format liczby”);
else

if (x<=1 || x==M_PI||x>3.7) printf(”\n x nie należy do dziedziny”);

}

while (k==0 || x<=1|| x==M_PI ||x>3.7 );
do {

printf("\n Podaj z:");
k=scanf("%lf",&z);

} while(!k||fmod(z,M_PI)==0);

background image

Język ANSI C – typy rzeczywiste

Z obliczaniem wyrażeń w języku C wiążą się trzy zagadnienia:

a) problem kolejności obliczania podwyrażeń

b) konwersja typów w wyrażeniach

c) rzutowanie (zmiana typu wyrażenia)

Ad a. 

Język C nie określa kolejności w jakiej są obliczane podwyrażenia danego 

wyrażenia. Kompilator ma więc swobodę w zmianie kolejności obliczania tak aby 
uzyskać zoptymalizowany kod. Przykładowo w wyrażeniu

x=f1() +f2(); 

nie można określić czy funkcja f1 będzie wywołana jako pierwsza.

background image

Język ANSI C – typy rzeczywiste

Ad.b.

Jeżeli w wyrażeniu występują zmienne i stałe różnych typów, są one wszystkie 

przekształcane do jednego wspólnego typu. Kompilator przekształca wszystkie 
operandy do największego typu występującego w wyrażeniu. W pierwszym rzędzie 
wartości typu char short int przekształcane są do typu int.

Przekształcenia typów przebiegają zgodnie z powyższymi regułami:

- jeżeli operand jest typu long double, to drugi operand jest przekształcany do typu 

long double

-jeżeli operand jest typu  double, to drugi operand jest przekształcany do typu  double

-jeżeli operand jest typu  unsigned long, to drugi operand jest przekształcany do typu 
unsigned long,

-jeżeli operand jest typu  float, to drugi operand jest przekształcany do typu float

-jeżeli operand jest typu  long int, to drugi operand jest przekształcany do typu  long
int

background image

Język ANSI C – typy rzeczywiste

Ad. b (ciąg dalszy-przekształcenia typów)

-jeżeli operand jest typu  unsigned int , to drugi operand jest przekształcany do typu 

unsigned int

Istnieje jednak pewien specjalny przypadek: jeżeli jeden operand jest typu long 

drugi typu unsigned int, i wartości typu unsigned int nie można przedstawić przy 
użyciu typu long, wtedy oba operandy są przekształcane do typu unsigned int.

background image

Język ANSI C – typy rzeczywiste

Ad. b (ciąg dalszy-przekształcenia typów)

Po zastosowaniu powyższych reguł każda para operandów ma ten sam typ oraz wynik 

operacji jest tego samego typu, co typ obu operandów.

Przykład. 

char ch=3; int i=5; float f=1.5; double d=2.5,wynik;

wynik=(ch / i)   +       (f   *   d)      -

(f  +   i);

int            double                              float

int               double                     float

double

double

background image

Język ANSI C – typy rzeczywiste

Ad.c. (rzutowanie)

Typ wyrażenia można narzucić lub zmienić przy pomocy tzw. rzutowania. Ogólna 

postać rzutowania to: 

(typ) wyrażenie,

lub 

typ ( wyrażenie)

Rzutowanie jest operatorem o priorytecie takim jak pozostałe operatory 
jednoargumentowe.

background image

Język ANSI C – typy rzeczywiste

Przykład. Napisać fragment programu określający procentową ilość udanych prób w 
stosunku do ogólnej ilości prób.
// Przykład. Zmiana typu poprzez rzutowanie
#include <stdio.h>
#include <conio.h>
#include <math.h>
int main(int argc, char* argv[])
{

int ilosc_prob, ilosc_udanych_prob;

double udzial_procentowy;
printf("\n Podaj ilosc prob :");
scanf("%d",&ilosc_prob);
printf("\n Podaj ilosc udanych prob:");
scanf("%d",&ilosc_udanych_prob);

udzial_procentowy= 

double (ilosc_udanych_prob

)/ilosc_prob*100;

printf("\n Udzial procentowy  udanych prob=%6.2f%", udzial_procentowy);
getch();
return 0;

}

background image

Język ANSI C – instrukcje

Instrukcja złożona (grupująca)

Instrukcja złożona składa się z nawiasu klamrowego otwierającego, dowolnych 

instrukcji (mogą być również kolejne instrukcje złożone) i nawiasu klamrowego 
zamykającego:

Przykład. Instrukcja złożona.

printf("Instrukcja 1" ); 
printf("Instrukcja 2\n"); 

Wszystkie instrukcje w języku C z wyjątkiem instrukcji złożonej kończą się średnikiem
Instrukcja złożona jest stosowana wtedy, gdy istnieje konieczność zgrupowania kilku 

instrukcji, tak aby były traktowane jako jedna instrukcja.

background image

Język ANSI C – instrukcje

Instrukcja while

Instrukcja while jest instrukcją iteracyjną, umożliwiającą powtarzanie pewnego ciągu 
operacji. Instrukcja while ma następującą postać:

while (wyrażenie)

akcja

W  instrukcji while najpierw określa się czy wyrażenie jest prawdziwe czy też 

fałszywe. C wymaga by wyrażenie było zawarte w nawiasach.. Jeżeli wyrażenie jest 

prawdziwe, wykonywana jest akcja i następuje powrót do obliczania wyrażenia

wyrażenie jest ponownie testowane  i jeżeli jest prawdziwe znowu wykonywana jest 

akcja i następuje kolejny powrót do obliczania wyrażenia. Jeżeli jednak przy którymś 

obliczaniu wyrażenia, stwierdzone zostanie, że wyrażenie jest fałszywe, następuje 

natychmiastowe przejście do instrukcji znajdującej się po instrukcji while.

background image

Język ANSI C – instrukcje

Akcja może się składać z jednej instrukcji lub też szeregu instrukcji zawartych 

w nawiasach {

}. Użycie tych nawiasów jest konieczne jeśli akcja 

obejmuje więcej niż jedną instrukcję.

Przykład. Instrukcja while.

int x=0;

while (x != 2)

x = x + 1;

printf (“\n x =  %d”, x);

background image

Język ANSI C – instrukcje

Fragment ten wydrukuje

x = 2

Zmienna x jest inicjalizowana wartością 0 przy definicji.  Ponieważ != jest operatorem 

relacyjnym „różne” (nierówne), wyrażenie 

x != 2 

ma wartość prawda i wykonywane jest instrukcja 

x = x + 1,

która dodaje 1 do x, i wynik umieszcza w x. Następuje powrót do obliczania wyrażenia 

po while. Wyrażenie x != 2 jest prawdziwe (gdyż równa się 1), więc znowu dodawane 

jest 1 do i następuje powrót do obliczania wyrażenia po while. Wyrażenie x != 2 jest 

teraz fałszywe (bo równa się 2) więc zostanie wykonana instrukcja

printf (“\n x =  %d”, x);   która pisze    x = 2

background image

Język ANSI C – instrukcje

Instrukcja do while

Instrukcja do while jest podobna do instrukcji while, z tą różnicą, że wyrażenie 

kontrolujące pętlę jest na końcu pętli. Cała pętla wykonywana jest przynajmniej raz. 

do

akcja

while (wyrażenie);

Przy wykonywaniu pętli do while wykonywana jest najpierw akcja, a następnie 

wykonywane jest sprawdzenie, czy wyrażenie jest prawdziwe czy też nie. Jeżeli jest 

prawdziwe, następuje powrót  do początku pętli. Jeżeli w którymś momencie wyrażenie 

staje się  fałszywe, wykonywana jest pierwsza instrukcja występująca po pętli. Część 

pętli oznaczona jako akcja może być jedną instrukcją lub też grupą instrukcji zamkniętą 

w nawiasy {    }.

background image

Język ANSI C – instrukcje

Instrukcja do while jest użyteczna wtedy, gdy test w sposób naturalny znajduje się 

na końcu pętli. Przykładem takiej sytuacji może być weryfikacja wartości wprowadzanej 

przez użytkownika z klawiatury. Po  wprowadzeniu wartości,  jest ona sprawdzana. 

Jeżeli wartość jest niedopuszczalna przy danym formacie, użytkownik zachęcany jest do 

wprowadzenia innej wartości.

Przykład. Użycie instrukcji do while do wprowadzenia liczby dodatniej.

int wartosc, k;

do {

printf (“\nPodaj liczbe calkowita:”);

k = scanf (“%d”, &wartosc);

fflush(stdin); //Czyszczenie strumienia wejściowego

}  while (!k  || wartosc <=0);

background image

Język ANSI C – instrukcje

Instrukcja warunkowa  if

Instrukcja warunkowa if umożliwia uzależnienie wykonania pewnej instrukcji  od 

spełnienia pewnego warunku. Warunek ten jest reprezentowany przez wyrażenie 

umieszczone po słowie if. Wyrażenie to przybiera wartość prawda lub wartość fałsz 

(wszystkie wartości różne od 0 są w języku C traktowane jako prawda, wartość  0 jako 

fałsz). Instrukcja ta ma następującą postać

if (wyrażenie)

akcja;

background image

Język ANSI C – instrukcje

Wyrażenie musi być zawarte w nawiasach. Aby wykonać if najpierw oblicza się 

wyrażenie i określa się czy jest prawdziwe czy też fałszywe. Jeżeli wyrażenie jest 

prawdziwe,  zostaje wykonana akcja i sterowanie przechodzi do instrukcji programu 

umieszczonej po akcji

Jeżeli wyrażenie jest fałszywe, akcja zostaje pominięta i następuje przejście do 

instrukcji umieszczonej po akcji. Część if określona jako akcja składa się z pojedynczej  

instrukcji lub instrukcji  złożonej (pewnej liczby instrukcji umieszczonych w nawiasach 

{}).

background image

Język ANSI C – instrukcje

Przykład. Instrukcja if

int kod;

printf(”\n Podaj kod:”);

scanf(”%d”,&kod);

if (kod= =1)

printf ("\n warunek jest  spełniony");

Jeżeli z klawiatury podano wartość 1, fragment programu drukuje napis

warunek jest  spełniony

Nie należy mylić znaku = z parą znaków  = =. Można wprawdzie  napisać if (x=1)

jednak  wyrażenie po if jest tutaj równe 1 niezależnie od wartości x,  więc instrukcja if

nie będzie pełnić swojej roli.

background image

Język ANSI C – instrukcje

Instrukcja if else

Instrukcja ta ma następującą postać:

if (wyrażenie)

akcja1

else

akcja2

Podobnie jak dla instrukcji if, najpierw obliczane jest  wyrażenie po if. Jeżeli wyrażenie 

ma wartość logiczną prawda, wykonywana jest akcja1,

natomiast jeżeli wyrażenie ma wartość fałsz, jest wykonywana akcja2.

background image

Język ANSI C – instrukcje

Przykład. Instrukcja if else

int kod;

printf(”\n Podaj kod”);

scanf(” %d”,&kod);

if (kod==3245) 

printf(”\n Podano prawidłowy kod”);

else 

printf(”\n Kod nie jest poprawny”);

background image

Język ANSI C – instrukcje

Przykład. Instrukcja if else ze złożonymi instrukcjami po if i po else.

int kod;
printf(”\n Podaj kod”);
scanf(” %d”,&kod);
if (kod!=2)

printf(”\n Instrukcje te wykonują się gdy ”);
printf(”\n zmienna kod ma wartość rozna od 2”);

}

else 

{

printf(”\n Instrukcje te się wykonuja”);
printf(”\n gdy zmienna kod ma wartosc 2 ”);

}

background image

Język ANSI C – instrukcje

Przykład. Określić napisy drukowane przez poniższy fragment programu dla zmiennej 

kod=1 i 2.
int kod;
printf(”\n Podaj kod”);
scanf(” %d”,&kod);
if (kod==2) 

{

printf(”\n Matematyk”);
if (kod==2)

printf(”  artysta”);

else

printf(” programista”);

}

else 
printf(”\n Specjalista programista”);

background image

Język ANSI C – instrukcje

Instrukcje if  zagnieżdżone

W instrukcji takiej po if  lub po else występuje kolejna instrukcja warunkowa if lub if

else

Instrukcja taka ma budowę następującą:

if (wyrażenie1)

akcja1;

else if (wyrażenie2)

akcja2;

else if (wyrażenie3)

.

.

.

else if (wyrażenie n)

akcja n;

background image

Język ANSI C – instrukcje

Działanie instrukcji if zagnieżdżone

Instrukcja taka funkcjonuje w sposób następujący:

jeżeli prawdziwy jest warunek pierwszy (wyrażenie1) to wykonywana jest akcja1 

następuje przejście do instrukcji umieszczonej po akcji n-tej. 

Ogólnie, jeżeli jest prawdziwe wyrażenie i-te, to jest wykonywana i-ta akcja 

następuje przejście do instrukcji po wyrażeniu n-tym. 

Jest wykonywana tylko jedna akcja (grupa akcji w nawiasie klamrowym), pozostałe 

akcje są odrzucane.

background image

Język ANSI C – instrukcje

Przykład. Instrukcja if zagnieżdżone.

int kod;

printf(”\n Podaj kod”);

scanf(” %d”,&kod);

if (kod= =1)

printf("Akcja ta jest wykonywana gdy kod jest równy 1");/*instrukcja 1*/

else if (kod= =2)

printf("Akcja ta jest wykonywana gdy kod jest równy 2");/*instrukcja 2*/

else if (kod<=3)

printf("Akcja ta jest wykonywana gdy kod jest mniejszy równy 3");/*instrukcja 3*/

Gdy zmienna kod ma wartość  1, wykonywana jest instrukcja 1, pomimo że 

wyrażenie kod<=3 jest prawdziwe, jednak sterowanie do niego w tym przypadku nie 

dochodzi.

background image

Język ANSI C – instrukcje

Instrukcja if else z akcją domyślną

if (wyrażenie1)

akcja1;

else if (wyrażenie2)

akcja2;

else if (wyrażenie3)

.
.
.

else if (wyrażenie n)

akcja n;

else

akcja;

Akcja jest tutaj działaniem domyślnym, które jest wykonywane, gdy 

żadna z akcji od 1 do n nie zostanie wykonana.

background image

Język ANSI C – instrukcje

Przykład. Instrukcja if else z akcją domyślną. 
int kod;
printf(”\n Podaj kod”);
scanf(” %d”,&kod);
if (kod= =1)

printf(”Akcja ta jest wykonywana, gdy kod jest rowny 1");

else if (kod= =2)

printf("Akcja ta jest wykonywana, gdy kod jest rowny 2");

else if (kod<=3)

printf("Akcja ta jest wykonywana gdy kod jest mniejszy lub

rowny 3");

else

printf("Akcja ta jest wykonywana, gdy "

"żadna z akcji 1, 2, 3 nie wykona się");

background image

Język ANSI C – operator ? (wyrażenie warunkowe)

Operator ? pozwala na zastąpienie niektórych instrukcji if-else. Operator ten ma  postać:

wyrażenie1 wyrażenie2 :wyrażenie3

Operator ten działa w sposób następujący: najpierw jest obliczane wyrażenie1, jeśli ma 

ono wartość logiczną prawda, wtedy jest obliczane wyrażenie2 i staje się ono wartością 

całego wyrażenia, jeśli zaś wyrażenie1   ma wartość logiczną fałsz, obliczane jest 

wyrażenie3 i ono staje się wartością całego wyrażenia.

Przykład.

int x, y;   

x=5;

y=x>10? 50  : 100;

background image

Język ANSI C – operator ? (wyrażenie warunkowe)

Przykład.

z=a>b? a: b; // max(a,b)

Powyższa instrukcja wyznacza większą z wartości a i b. 

Wyrażenie warunkowe może być stosowane wszędzie tam, gdzie w języku C może 

wystąpić wyrażenie. Priorytet operatora ? jest względnie niski ( tuż nad operatorem 

przypisania) stąd nie jest konieczne stosowanie nawiasów, aby wymusić odpowiednią 

kolejność wykonywania operacji. 

background image

Język ANSI C – operator przecinkowy

Użycie operator przecinkowego  jest stosowany przedstawić w sposób następujący:

wyr1wyr2,…,wyrN

Wyrażenia oddzielone przecinkami oblicza się od lewej do przy czym typem i wartością 
całego wyrażenia są typ i wartość wyrażenia wyrN.

Przykład.

int x, y;

x= (y=15;y+1);

Wartość x jest równa 16.

background image

Język ANSI C – operatory inkrementacji i dekrementacji

.

Dla operatorów  tych stosowane są  następujące symbole

++ - dla operatora inkrementacji (zwiększania),

oraz

-- - dla  operatora  dekrementacji ( zmniejszania).

Operatory te zwiększają wartość swego argumentu o 1 (operator ++), lub też 

zmniejszają o 1 ( operator --). Operatory te mogą być używane w następujących 

formach:

++ operand  -

++ - operator  preinkrementacji,

operand++ -

++ - operator postinkrementacji,

-- operand  -

-- operator predekrementacji,

operand -- -

-- operator postdekrementacji,

background image

Język ANSI C – operatory inkrementacji i dekrementacji

Operand w powyższych wyrażeniach z operatorami ++ lub -- może być typu 

arytmetycznego lub wskaźnikowego, musi być jednak tzw. Lwartością (ang. Lvalue), tzn. 

musi reprezentować pewną lokację pamięci.

Użycie powyższych operatorów powoduje dwa efekty:

- wartość operandu jest modyfikowana ( zwiększana lub zmniejszana

o 1),  

- wyrażeniu z operandem jest przypisywana pewna wartość.

background image

Język ANSI C – operatory inkrementacji i dekrementacji

Działanie operatora postinkrementacji (operand ++).

- wartość operandu jest zwiększana o 1,

- wartość wyrażenia operand ++ jest równa początkowej 

wartości operandu.

Przykład. 

x=3;

y=x++;

y=x++;

x jest zwiększany o1             wartość wyrażenia jest równa 

(x=4)                                  początkowej wartości x ( y=3)

background image

Język ANSI C – operatory inkrementacji i dekrementacji

Działanie operatora preinkrementacji (++operand).

- wartość operandu jest zwiększana o 1,

- wartość wyrażenia ++operand  jest równa zwiększonej o 1

wartości operandu.

Przykład. 

x=3;

y=++x;

y=++x;

x jest zwiększany o1             wartość wyrażenia jest równa 

(x=4)                                  zwiększonej wartości x ( y=4)

background image

Język ANSI C – operatory inkrementacji i dekrementacji

Działanie operatora postdekrementacji (operand - -).

- wartość operandu jest zmniejszana o 1,

- wartość wyrażenia operand -- jest równa początkowej 

wartości operandu.

Przykład. 

x=3;

y=x--;

y=x--;

x jest zmniejszany o1             wartość wyrażenia jest równa 

(x=2)                                  początkowej wartości x ( y=3)

background image

Język ANSI C – operatory inkrementacji i dekrementacji

Działanie operatora predekrementacji (- - operand).

- wartość operandu jest zmniejszana o 1,

- wartość wyrażenia operand -- jest zmniejszonej o 1 

wartości operandu.

Przykład. 

x=3;

y=--x;

y=--x;

x jest zmniejszany o1             wartość wyrażenia jest równa 

(x=2)                                  zmniejszonej wartości x ( y=2)

background image

Język ANSI C – instrukcje

Przykład. Użycie operatorów preinkrementacji i postinkrementacji.
#include <stdio.h>
#include <conio.h>

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

int x,y;

x= (y=15,y=y+1,y=y+1,++y);

printf("\n x=%d",x);

x= (y=15,y=y+1,y=y+1,y++);

printf("\n x=%d",x);

getch();

return 0;

}

background image

Język ANSI C – instrukcje

Instrukcja for

Instrukcja for, zwana też pętlą for, jest instrukcją iteracyjną podobnie jak instrukcje while

do while. Stosowana jest ona do wielokrotnego powtarzania pewnego segmentu kodu. 

Pętla for w języku C jest podobna do pętli for w innych językach programowania, 

posiada jednak znacznie większe możliwości. 

Pętla for ma następującą postać:

for (wyr1; wyr2; wyr3)

akcja

background image

Język ANSI C – instrukcje

Wyrażenie wyr1 jest stosowane do inicjalizacji pętli, wyrażenie wyr2 jest używane do 

testowania warunku kontynuacji pętli, wyrażenie wyr3 służy do uaktualniania pętli. Akcja

stanowi treść (ciało) pętli. Działanie:

Krok1.  Obliczenie wyrażenia wyr1 (jest ono obliczane jeden raz i tylko jeden raz 

na początku działania pętli). 

Krok 2a. Obliczenie wyr2 i sprawdzenie czy wyrażenie wyr2 jest prawdziwe czy 

też fałszywe.

Krok 2b. Jeżeli wyr2 jest fałszywe, zakończenie pętli i przejście do instrukcji 

umieszczonej bezpośrednio po pętli.  Jeżeli wyr2 jest prawdziwe, 

wykonanie akcji.

Krok 3. Obliczenie wyrażenia wyr3, następnie przejście do Kroku 2.

background image

Język ANSI C – instrukcje

Ciało pętli (akcja) może być pojedynczą instrukcją albo też instrukcją złożoną 

(grupującą), jeśli jest konieczne wykonanie w pętli więcej niż jednej instrukcji 

Przykład. Użycie pętli for.

int sum=0;

int i;

for (i=1; i<=4;i=i+1)

sum=sum+i;

W powyższym przykładzie  w pętli for najpierw jest wykonywana instrukcja i=1 

następnie sprawdzany jest warunek i<=4, dla i=1 jest on prawdziwy, więc wykonywana 

jest instrukcja sum=sum+i; i następuje przejście do instrukcji i=i+1, i przyjmuje wartość 

2, i wykonywane jest sprawdzenie i<=4, warunek jest prawdziwy, więc ponownie 

wykonywana jest instrukcja sum=sum+i. Gdy przybierze wartość 5, warunek i<=4 nie 

spełniony i pętla kończy się.

background image

Język ANSI C – instrukcje

Przykład. Użycie pętli for ( typowy zapis)

#include <stdio.h>
#include <conio.h>
int main(int argc, char* argv[])
{

int i,sum;

for( i=0,sum=0; i<=4;i++)

sum=sum+i;

printf("\n sum=%d",sum);
getch();

return 0;
}
W wyrażeniu wyr1 użyto operator przecinkowy.

background image

Język ANSI C – instrukcje

#include <stdio.h>
#include <conio.h>
int main(int argc, char* argv[])
{

int x, y;

for( x=0,y=0; x+y<10 ;x++)

{

y=getch();  // wczytywanie y jako znaku
putchar(y); // drukowanie wczytanego znaku
y=y -'0';      // wyznaczanie cyfry reprezentowanej przez wczytany znak 

}

printf("\n x=%d y=%d", x,y);
getch();
return 0;
}

background image

Język ANSI C – instrukcje

Odmiany pętli for

1. Pętla nieskończona

for (  ;  ;  ) 

printf (” Pętla ta będzie działać w nieskończoność”);

Brak  wyr2 uważany jest za wyrażenie prawdziwe. 

2. Pętla bez treści(ciała)

for (i=0;i<100000;i++) ; // pętla taka może realizować opóźnienie w  programie

Ogólnie w pętli for  może nie być któregoś z wyrażeń albo też wszystkich, jednak 

zawsze muszą być dwa średniki.

Przykład. Pętla bez wyrażenia wyr3.

for( i=0,sum=0; i<=4;)

{

sum=sum+i;
i++;

}                      

background image

Język ANSI C – instrukcje

Instrukcja break 

Instrukcja break  powoduje natychmiastowe przerwanie wykonywania pętli, w 

której została umieszczona. 

Przykład . Użycie instrukcji break w pętli.

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

{

printf("\n i=%d ",i);
if (i==3) break;

printf("\n Koncowa instrukcja petli");

}

printf("\n Poza petla");

W przykładzie powyższym, gdy zmienna osiągnie wartość 3, warunek po if ma wartość 
logiczną prawda, co powoduje  wykonanie jest instrukcja break, która daje 
natychmiastowe przerwanie wykonywania pętli. 

background image

Język ANSI C – instrukcje

Instrukcja continue

Instrukcja continue jest podobna do instrukcji break w tym sensie, że również 

przerywa działanie pętli, jednak pętla nie ulega zakończeniu, lecz następuje przeskok do 

wykonania wyrażeń sterujących pętlą. Dla pętli for mamy

for (wyr1;wyr2;wyr3)

{

blok instrukcji (1)

if (warunek) continue;

blok instrukcji (2)

}

Jeżeli warunek po if jest prawdziwy, to wykonanie continue powoduje 

natychmiastowe przejście, bez wykonania bloku instrukcji2 do obliczenia wyrażenia 

wyr3 i następnie do obliczenia wyrażenia wyr2. Jeżeli wyrażenie wyr2   ma wartość 

prawda,  wykonanie pętli jest kontynuowane. 

.

background image

Język ANSI C – instrukcje

Dla pętli while i pętli do while następuje natychmiastowe przejście do obliczenia 

wyrażenia sterującego pętlą, czyli dla pętli while na początek pętli, a dla pętli do while
na koniec pętli. 

Przykład . Program oblicza średnią liczb dodatnich podawanych na wejscie, liczby 
ujemne są odrzucane przy użyciu instrukcji continue.
#include <stdio.h>
#include <conio.h>
main()
{

double x, suma=0;

int ilosc=0;
while ( printf ("\n Podaj liczbe :"), scanf("%lf" ,&x)!=0)

{

if (x<0.0) continue;

suma=suma+x;

ilosc++;

}

if (ilosc>0)

printf("\n Srednia=%f", suma/ilosc);

else

printf("\n Nie podano zadnych liczb dodatnich");

getch();

t

0

background image

Język ANSI C – instrukcje

Instrukcja switch

switch( wyrazenie_calkowite)
{
case etykieta_1: instrukcja 1;
case etykieta_2: instrukcja 1;
.
.
.
case etykieta_n: instrukcja_n;

default: instrukcje;

}

Wyrażenie po słowie switch, zwane wyrażeniem wyboru lub selektorem, musi 

przyjmować wartości całkowite. Etykiety są całkowitymi wartościami stałymi lub 

wyrażeniami stałymi. Jeśli podczas wykonywania instrukcji switch jedna z etykiet ma 

wartość równą wartości selektora (oznaczonego jako wyrazenie_calkowite), to 

wykonanie instrukcji switch rozpoczyna się od wykonania instrukcji znajdującej się przy 

tej etykiecie.

background image

Język ANSI C – instrukcje

Jeżeli w instrukcji switch występuje słowo default (ang. domyślny), instrukcje 

umieszczone po słowie default są wykonywane, gdy żadna z etykiet nie ma wartości 

równej selektorowi. Etykieta default jest opcjonalna, i jeżeli nie występuje, to następuje 

przejście do pierwszej instrukcji po instrukcji switch.

Jeżeli chce się uzyskać wykonanie tylko jednej konkretnej instrukcji, należy po 

każdym wariancie umieścić słowo break wraz ze średnikiem. Spowoduje to 

natychmiastowe przerwanie wykonywania instrukcji switch po zrealizowaniu instrukcji 

związane z danym wariantem. 

background image

Język ANSI C – instrukcje

Przykład. W przykładzie wczytywana jest liczba całkowita i jeżeli jest to liczba 0,1,2 lub 
3, drukowany jest komunikat informujący o wartości liczby. Jeżeli jest podaną liczbą jest 
inna liczba, drukowany jest komunikat Inna liczba.
#include <stdio.h>
#include <conio.h>
main()

int liczba; 

printf("\n Podaj liczbe:"); 

scanf("%d", &liczba);
switch( liczba)

{

case 0: printf("\n Liczba 0");
break;
case 1: printf("\n Liczba 1");
break;
case 2:case 3: printf("\n Liczba 2 lub 3");

break;

default : printf("\n Inna liczba");
}
getch();
return 0; }

background image

Język ANSI C – instrukcje

Instrukcja goto (cz.1)

Instrukcja  goto to tzw. instrukcja skoku powodująca bezwarunkowe sterowania 

do pewnego punktu w programie opatrzonego etykietą. 

Etykieta jest identyfikatorem i zakończona jest dwukropkiem. Etykietę można 

umieścić przed każdą instrukcją w funkcji,  w której występuje instrukcja goto.

Przykład. 

int j=1;

E1: j++;

if (j<=100) goto E1;

printf(”\n j=%d”, j);

background image

Język ANSI C – instrukcje

Instrukcja goto (cz.2)

Stosowanie instrukcji goto nie jest zalecane, gdyż zwykle jej wielokrotne użycie  

powoduje, iż program staje się mniej czytelny jak również trudniejszy do modyfikacji. 

Istnieją jednak sytuacje, gdzie instrukcja goto jest wygodnym rozwiązaniem.

Przykład. 

int i,j,k;

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

for (j=0;j<100;j++)

for (k=0;k<50;k++)

if (i+j+k>10000) goto E2;

E2: printf (”\n Instrukcja poza petlami”);

background image

Język ANSI C – tablice

Tablice w języku C są pewnymi strukturami danych stanowiącymi zbiory 

zmiennych tego samego typu, do których odwołujemy się przy użyciu wspólnej nazwy. 

Tablice jednowymiarowe mają strukturę w pewnym sensie zbliżoną do struktur 

matematycznych takich jak wektory, a tablice dwuwymiarowe do macierzy.

W języku C tablice umieszczane są w ciągłych obszarach pamięci. Najniższy adres 

odpowiada pierwszemu elementowi tablicy, a najwyższy ostatniemu.

Definicja tablicy jednowymiarowej ma następującą postać:

typ nazwa_tablicy [rozmiar];

typ określa typ każdego elementu tablicy, rozmiar musi być określony w standardzie 

C89 przy użyciu wyrażenia stałego. Tak więc rozmiar tablicy jest ustalany w trakcie 

kompilacji. 

Dostęp do elementów tablicy uzyskuje się poprzez tzw. indeksowanie.

background image

Język ANSI C – tablice

Indeksowanie realizuje się umieszczając indeks ( numer elementu tablicy ) w nawiasach 
kwadratowych za nazwą tablicy. W języku C elementy indeksowane są od zera. 

Przykład. 

int a[20];

a[0]=1; // wpisanie do pierwszego elementu tablicy wartości 1,

// po lewej stronie zastosowano operator indeksowania i indeks 0

a[3]=2;

a[5]=2*a[0]-5*a[3]+10; // do elementu a[5] wstawiana jest wartość 2.

Elementy tablicy mogą być traktowane w ten sam sposób jak zmienne danego 

typu.

background image

Język ANSI C – tablice 

Poza zastosowaniem instrukcji podstawienia, elementom tablicy można nadać 

wartości przy użyciu tzw. inicjalizacji lub  instrukcji wejścia.

Przykład. Inicjalizacja tablicy.

int a[5]={ 1, 3, -1, 4, 5};

Ilość elementów inicjalizujących może być równa lub mniejsza od ilości elementów 

tablicy.

Jeżeli nie stosuje się inicjalizacji przy definicji tablicy, jej elementy mogą mieć wartości 

przypadkowe, gdy tablica jest definiowana wewnątrz funkcji. Tablice definiowane poza 

funkcjami bez inicjalizacji  (tablice zewnętrzne) są zerowane.

background image

Język ANSI C – tablice

Przykład. Wczytywanie i drukowanie tablicy 

#include <stdio.h>

#include <conio.h>

int main()

{  double x[10]; int i;

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

{  printf(”\n Podaj element x[%d]=”,i);

scanf(”%lf”,&x[i]);

fflush(stdin);  }

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

printf(”\n  x[%d]=%f”,i, x[i]);

getch();

return 0; }  

background image

Język ANSI C – tablice

Przykład. Wczytywanie i drukowanie tablicy ze sprawdzaniem formatu
#include <stdio.h>
#include <conio.h>
int main()
{  double x[10]; int i;

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

do

printf(”\n Podaj element x[%d]=”,i);
k=scanf(”%lf”,&x[i]);
fflush(stdin);

} while (k==0);

}

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

printf(”\n  x[%d]=%f”,i, x[i]);

getch();

return 0;

background image

Język ANSI C – tablice

Przykład. Sumowanie różnych kategorii elementów tablicy.

int a[10]={ 1, 3, -1, 4, 5,6,9,2,15,12};

int i, suma=0, suma_p=0, suma_ind=0, ind1=2, ind2=6;

for (i=0;i<10;i++)      suma = suma + a[i];

for (i=0;i<10;i++)     if (a[i] %2==0)  suma_p = suma_p+a[i]; 

for (i=ind1;i<=ind2 ;i++)      suma_ind = suma_ind + a[i];

background image

Język ANSI C – tablice

Przykład. Wyszukiwanie w tablicy elementu minimalnego i maksymalnego

int a[10]={ 1, 3, -1, 4, 5,6,9,2,15,12};
int i, amin,  amax;

amin=a[0];

for (i=1;i<10;i++)   

if ( a[i] < amin) amin = a[i];

amax=a[0];

for (i=1;i<10;i++)   

if ( a[i] > amax) amax= a[i];

printf(”\n element minimalny =%d ”,amin);
printf(”\n element maksymalny =%d ”,amax);

background image

Język ANSI C – tablice

Przykład. Wyszukiwanie w tablicy zadanej wartości i zapis wartości indeksów elementów 
równych tej wartości  

#include <stdio.h>
#include <conio.h>
int main(int argc, char* argv[])
{  int a[10]={ 1, 2, -1, 4, 5,6,9,2,15,12};

int i, k=0,element, poz[10];
printf("\n  Podaj poszukiwany element :");
scanf("%d",&element);

for (i=0;i<10;i++)
if ( a[i] ==element ) poz[k++]=i;
if (k)
{ printf("\n Pozycje tablicy na ktorych wystepuje element=%d", element);

for (i=0;i<k;i++)
printf("   %d    ", poz[i]);

}

else printf("\n Zadany element nie wystepuje w tablicy");
getch();
return 0; }

background image

Język ANSI C – tablice

Sortowanie jest procesem ustawiania zbioru obiektów w określonym porządku.

Sortowanie stosuje się w celu ułatwienia późniejszego wyszukiwania elementów 

sortowanego zbioru.   

Problem sortowania można sformułować następująco:

Dane są obiekty   

Sortowanie (niemalejąco) polega na przestawianiu tych obiektów aż do chwili 
osiągnięcia uporządkowania 

takiego, że dla danej funkcji porządkującej f zachodzi związek:

n

a

a

a

,...,

,

2

1

3

2

1

,...,

,

k

k

k

a

a

a

)

(

...

)

(

)

(

3

2

1

k

k

k

a

f

a

f

a

f

background image

Język ANSI C – tablice

Zwykle nie oblicza się wartości funkcji porządkującej, lecz przechowuje się je w jawnej 
postaci jako składowe każdego obiektu. Wartość tej funkcji nazywana jest kluczem 
obiektu
.  Dla tablic kluczem obiektu jest wartość elementu.

Metody sortowania obiektów w miejscu można podzielić na trzy zasadnicze grupy:

- sortowanie przez zamianę (ang. exchange sort),

- sortowanie przez wybieranie (selekcję, ang. selection sort),

- sortowanie przez wstawianie (ang. insertion sort),

Przykłady  metod:

- sortowanie przez prostą zamianę ( sortowanie bąbelkowe) 

- sortowanie przez proste wybieranie,

- sortowanie przez proste wstawianie,

background image

Język ANSI C – tablice

Sortowanie przez prostą zamianę( sortowanie bąbelkowe)

Metoda ta polega na porównywaniu w kolejnych przebiegach kluczy kolejnych 

sąsiadujących elementów (dla tablic wartości elementów tablicy) i ewentualnej zamianie 

miejscami tych elementów, jeżeli nie spełniają zadanej relacji. Po zakończeniu danego 

przebiegu następuje sprawdzenie czy nastąpiły w nim zamiany. Jeśli tak, realizowany 

jest kolejny przebieg, jeśli nie, to sortowanie zostało zakończone.

background image

Język ANSI C – tablice

Sortowanie przez prostą zamianę( sortowanie bąbelkowe)

Przykład. Posortować niemalejąco tablicę 5-elementową zawierającą elementy 
8,6,10,2,1. Pokazane zostaną poniżej stany tablicy w kolejnych przebiegach.

I. przebieg         II. przebieg      III. przebieg IV. przebieg   V. przebieg

8,6,10,2,1        6,8,2,1,10

6,2,1,8,10       2,1,6,8,10      1,2,6,8,10

6,8,10,2,1       6,8,2,1,10

2,6,1,8,10       1,2,6,8,10      1,2,6,8,10

6,8,10,2,1        6,2,8,1,10

2,1,6,8,10       1,2,6,8,10      1,2,6,8,10

6,8,2,10,1        6,2,1,8,10

2,1,6,8,10       1,2,6,8,10      1,2,6,8,10

6,8,2,1,10        6,2,1,8,10

2,1,6,8,10       1,2,6,8,10      1,2,6,8,10 

background image

// Sortowanie przez prostą zamianę (bąbelkowe)
#define n  5 // sortowanie niemalejąco
#include <stdio.h>
#include <conio.h>

int main(int argc, char **argv)

{ int i, nr=1,p, zam;

int a[5]={8,6,10,2,1};
do

{  zam=0;

printf("\n przebieg nr=%d",nr++);
for (i=0;i<n -1;i++)

if (a[i+1]<a[i]) {

p=a[i];
a[i]=a[i+1];
a[i+1]=p;
zam=1; }

}

while (zam);   

printf("\n Stan wektora po sortowaniu");
for (i=0;i<n;i++)   printf(" % d  ",a[i]);getch(); }

Język ANSI C – tablice

background image

Język ANSI C – tablice

Sortowanie przez proste wybieranie

Metodę tę można opisać następująco:( sortowanie niemalejąco)

- wybrać element  o najmniejszym kluczu ( dla tablic element o  

najmniejszej wartości)

- wymienić go z pierwszym elementem.

Operacje te powtarza się z pozostałymi n-1 obiektami, następnie z n-2 obiektami, aż 
pozostanie jeden obiekt - największy. 

background image

Język ANSI C – tablice

// Sortowanie przez proste wybieranie
#define n  8
#include <stdio.h>
#include <conio.h>

int main(int argc, char **argv)

{ int i,i1,j,k,p,amin;    int a[8]={9,5,-2,7,-4,15,-20,100};

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

{  amin=a[i];

k=i;
for (j=i+1;j<n;j++)

if (a[j]<amin)

{  amin=a[j];

k=j;  }

if (k!=i)

{ p=a[i];

a[i]=a[k];
a[k]=p;

}

}         printf("\n Stan wektora po sortowaniu");

for (i=0;i<n;i++)   printf(" % d  ",a[i]);    getch();}

background image

Język ANSI C – tablice

Sortowanie przez proste wstawianie

Metoda ta jest stosowana przez grających w karty. Zaczynamy od „ pustej” lewej 

ręki, po czym bierzemy  ze stołu kolejne karty i wstawiamy w odpowiednie miejsca w 

zbiorze kart trzymanych w lewej ręce.  Dla danej karty znajdujemy właściwe miejsce,  

porównując ją kolejno z kartami w lewej ręce.

9

5

2

7

1

5

9

2

5

9

2

5

7

9

1

2

5

7

9

background image

Język ANSI C – tablice

#define  n  5 // Sortowanie przez wstawianie 
#include <stdio.h>
#include <conio.h>

int main(int argc, char **argv)
int i,j,x;     int a[5]={9,5,2,7,1};

j=0;

while (j<n)

{

x=a[j];
i=j-1;
while (i>=0 && a[i]>x)
{

a[i+1]=a[i];
i=i-1;

}

a[i+1]=x;
j=j+1;
}

printf("\n Stan wektora po sortowaniu");

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

printf("  % d   ",a[i]);getch(); }

background image

Język ANSI C – funkcje

W języku ANSI C program składa się z jednego lub większej liczby segmentów 

kodu zwanych funkcjami, z których jedna musi nazywać się main().

Wykonanie programu zaczyna się od funkcji main() i program powinien kończyć się 

wraz z zakończeniem działania funkcji main()( program również może się zakończyć, 

gdy pojawi się sytuacja nienormalna-wyjątek, np. dzielenie przez zero, albo też gdy 

zostanie zakończony w sposób jawny- ctrl-break, powodem zakończenia może być też 

wywołanie funkcji exit(). 

background image

Język ANSI C – funkcje

Powody  stosowania funkcji w programach

1. Program jest zbyt duży by pisać go jako jedną funkcję main().

2. Podział zadania programistycznego na mniejsze, które mogą być opracowywane 

niezależnie( np. w różnym czasie lub równocześnie przez różnych programistów).

3. Modularyzacja programu- podział programu na jednostki realizujące wyodrębnione 

logicznie zadania.

4. Ułatwienia w uruchamianiu dużych programów ( można niezależnie uruchamiać i 

testować poszczególne funkcje).

5. Korzystanie z bibliotek lub funkcji stworzonych przez innych programistów.

6. Unikanie powtarzania w programie tego samego kodu, gdy pewne zadania trzeba 

wykonywać wielokrotnie.

background image

Język ANSI C – funkcje

Funkcje a struktura programu w jezyku C (cz. I)

-Program w języku C  może być programem jednoplikowym lub wieloplikowym

W programie jednoplikowym wszystkie funkcje znajdują się w jednym pliku lub są do 

niego dołączane przy zastosowaniu dyrektywy #include. W programie wieloplikowym

pliki są łączone w sposób zależny od środowiska ( np. w C++ Builder opcja Project -

>Add to Project).

- Funkcje nie muszą występować w pliku w określonym porządku      ( pewne 

sposoby uporządkowania mogą wymagać dodatkowych deklaracji), jednak 

umieszczenie main() jako pierwszej funkcji w pliku ułatwia analizę programu).

background image

Język ANSI C – funkcje

Funkcje a struktura programu w języku C (cz. II)

- Każda funkcja może wywoływać dowolną inną funkcję.

- Nie jest dopuszczalne zagnieżdżanie funkcji, tzn. nie można jednej funkcji 

definiować wewnątrz innej funkcji.

- W programie występuje tylko jedna funkcja main() i musi ona wystąpić niezależnie 

od liczby plików źródłowych.

background image

Język ANSI C – funkcje

Przykład. Prosty program stosujący funkcję do obliczania kwadratu pewnej wartości. 

#include <stdio.h>

#include <conio.h>

int kwadrat (int num)   { 

int pom; // zmienna lokalna funkcji

pom=num*num;

return pom; }   // zmienna pom nie jest konieczna, może być 

// return num*num; 

main() {

int liczba, wartosc;   

printf(”\n Podaj wartosc :”);

scanf(”%d”,&wartosc);  

liczba=kwadrat(wartosc);/* zmienna wartosc jest tzw. argumentem funkcji,

po  prawej stronie znaku podstawienia umieszczono tzw. wywołanie funkcji czyli 

uruchomienie jej kodu. Zmienna wartość zawiera liczbę, która ma być podniesiona 
do kwadratu */    

background image

Język ANSI C – funkcje

printf (”\n Kwadrat liczby %d  wynosi :%d”, wartosc, liczba);

getch();

return 0;

background image

Język ANSI C – funkcje

#include <stdio.h>

#include <conio.h>

int kwadrat (int);   // deklaracja funkcji

main() {

int liczba, wartosc;   

printf(”\n Podaj wartosc :”);

scanf(”%d”,&wartosc);  

liczba=kwadrat(wartosc);

printf (”\n Kwadrat liczby %d  wynosi :%d”, wartosc, liczba);

getch();

return 0;  } 
int kwadrat (int num)

int pom; 
pom=num*num;
return pom;

}

background image

Język ANSI C – funkcje

Zadanie. Napisać i wywołać w main() dla dwóch par argumentów następujące funkcje:

a) funkcję obliczającą sumę swoich argumentów typu int 

b) funkcję obliczającą różnicę swoich argumentów typu int 

c) funkcję obliczającą  iloczyn swoich argumentów typu int

background image

Język ANSI C – funkcje

Przykład. Napisać i zastosować w programie funkcję silnia.
#include <stdio.h>
#include <conio.h>
int silnia  (int n ) 

int i, sil=1;

if (n>0)

for (i=1;i<=n;i++)

sil=sil*i; 

return sil;

}   

main() {

int l1=5, l2=6;

sil1=silnia (l1);
sil2=silnia (l2);
printf(”\n % d ! wynosi %d”, l1,sil1);
printf(”\n % d ! wynosi %d”, l2,sil2);
getch();
return 0;

}

background image

Język ANSI C – funkcje

Przykład. Napisać i zastosować w programie funkcję wczytajd wczytującą zmienną 
typu double.
#include <stdio.h>
#include <conio.h>
double  wczytajd  (void ) 

{ int k;

double x;
do {

printf(”\n Podaj zmienna :”);
k=scanf(”%lf”,&x);
if (k==0) printf(”\n Niepoprawny format liczby !”);
fflush(stdin);

} while (k==0); // można też   while (!k);

return x;  }   

main() {

double x1,x2;

x1=wczytajd ();
x2=wczytajd();
printf(”\n x1 wynosi %f”, x1);
printf(”\n x2 wynosi %f”, x2);
getch();
return 0;  }

background image

Język ANSI C – funkcje

Ogólna budowa funkcji

Definicja funkcji

Typ_zwracanej_wartości nazwa_funkcji (deklaracja parametrów formalnych, jeśli 
występują)

{

deklaracje 

instrukcje

}

Definicje poszczególnych funkcji mogą się pojawić w jednym pliku lub większej liczbie   

plików źródłowych, przy czym żadna funkcja nie może być rozdzielona między plikami  
(definicja funkcji musi być umieszczona w jednym pliku).

background image

Język ANSI C – funkcje

Deklaracja funkcji ( cz. I)

Deklaracja funkcji stanowi informację dla innych funkcji stosujących daną funkcję o  

typie zwracanej wartości, liczbie i typach parametrów funkcji.

Deklaracja ma postać skróconego nagłówka funkcji zakończonego średnikiem.

Przykład. Deklaracje funkcji

int kwadrat (int, int);  

int echo_line (void);

void print_hist ( int size);

void print_prompt( void);

Nazwy po typach parametrów są opcjonalne i są ignorowane przez kompilator.  

Nazwy parametrów stosować można dla celów dokumentacji, pozwalają one 
zorientowąć  się co do roli poszczególnych parametrów bez sięgania do definicji 

funkcji.  

background image

Język ANSI C – funkcje

Definicja a deklaracja funkcji

Definicja   funkcji występować jednokrotnie.

1. Deklaracja funkcji może występować  wewnątrz funkcji , która  

wywołuje daną funkcję  f    lub też na zewnątrz wszystkich funkcji.

2.  Deklaracja funkcji wewnątrz funkcji służy tylko funkcji g.   

3.   Deklaracja funkcji f  na zewnątrz wszystkich funkcji służy  wszystkim 

tym funkcjom, których definicje umieszczono po deklaracji  funkcji .   

background image

Język ANSI C – funkcje

Instrukcja return (cz. I)

Instrukcja return ( ang. powróć, zwróć) pełni dwie zasadnicze funkcje:

1. Zwraca sterowanie programem do miejsca wywołania funkcji

( do funkcji wywołującej).

2. Umożliwia przekazanie wartości obliczonej przez funkcję do funkcji 

wywołującej.

background image

Język ANSI C – funkcje

Instrukcja return cz. II

Funkcja, która zwraca wartość, powinna mieć przynajmniej jedną instrukcję return w 

formie

return (wyrażenie);

lub 

return wyrażenie;

gdzie wyrażenie jest jakimkolwiek legalnym wyrażeniem języka C.

Obie formy mają to samo znaczenie. 

Do funkcji wywołującej zwracana (przekazywana) jest wartość

wyrażenia.

Funkcja przy wywołaniu może zwrócić co najwyżej jedną wartość. 

background image

Język ANSI C – funkcje

Instrukcja return cz. III

Przykład. Instrukcja return.

a)     return ( 25*5 + fun2(x);

b)     return (25*5+ fun2(x));

c)

double modul ( double x)

{

return x>0 ? x : -x;

}

Niezależnie od tego czy wyrażenie po return jest skomplikowane, czy też nie, zwracana 

jest jedna wartość.

background image

Język ANSI C – funkcje

Instrukcja return IV

Funkcja może posiadać kilka instrukcji return, jednak w czasie danego 

wywołania funkcji może zostać wykonana tylko jedna instrukcja return.

Nie powinno się stosować w funkcji kilku instrukcji return, gdyż funkcja staje się 

mniej zrozumiała oraz  trudniejsza do testowania i modyfikacji.

Instrukcja return nie jest konieczna w funkcji, która nie zwraca żadnej wartości,

ale jeśli jest używana to w postaci 

return;

Jeśli nie ma instrukcji return, wykonywane są kolejne instrukcje w treści funkcji, 

aż do momentu dojścia do nawiasu zamykającego funkcję. 

background image

Język ANSI C – wskaźniki

Wskaźniki cz. I

Wskaźniki to typ obiektów, przechowujących adresy innych obiektów np. zmiennych. 

Adres to konkretna lokalizacja pewnego obiektu w pamięci.

Jeżeli pewien obiekt typu wskaźnikowego (np. zmienna) przechowuje adres innego 

obiektu, to mówimy, że wskazuje na ten obiekt. 

background image

Język ANSI C – wskaźniki

1000

1008

1004

20

1008

0

1012

160

1016

1

Adres pamięci

Zawartość

Zmienna umieszczona pod adresem 1000 wskazuje na zmienną umieszczoną pod 

adresem 1008.

background image

Język ANSI C – wskaźniki

Definicja prostej zmiennej wskaźnikowej

Jeżeli zmienna ma przechować adresy innych obiektów, należy ją odpowiednio 

zdefiniować.  Definicja zmiennej wskaźnikowej składa się z nazwy typu 

wskazywanych obiektów, gwiazdki oraz nazwy zmiennej

typ_wskazywanych_obiektów * nazwa_zmiennej ;

typ_wskazywanych_obiektów  zwany jest zwykle typem wskaźnika. 

Przykład. Definicja zmiennej wskazującej na obiekty typu int.

int * px;

background image

Język ANSI C – wskaźniki

Operatory wskaźnikowe

W języku C istnieją dwa operatory wskaźnikowe:

- operator adresowy &

- operator adresowania pośredniego * ( dereferencji)

Jednoargumentowy operator & przyłożony do operandu zwraca adres operandu w 

pamięci ( dokładniej - wyrażenie &operand reprezentuje adres operandu).

Jednoargumentowy operator * przyłożony do operandu wskaźnikowego, zwraca 

wartość znajdującą się pod adresem zawartym w obiekcie (zmiennej) występującym po 

operatorze. 

background image

Język ANSI C – funkcje

Przykład. Proste działania przy użyciu wskaźników.

int *px, *py;  // definicja zmiennej wskaźnikowej px 

int i=5, j,k=10;

px=&i;  // przypisanie adresu zmiennej wskaźnikowi px;

j=*px;   // podstawienie do przy użyciu wskaźnika 

*px= i+k; // podstawienie sumy i+do 

py=px;

*py=20; // podstawienie do wartości 20

printf(”\n i=%d”, *py); // drukowanie przy użyciu wskaźnika py

*py=*py+5;

printf(”\n i=%d”, *py); 

background image

Język ANSI C – funkcje

Przykład. Wczytywanie i drukowanie zmiennej przy użyciu wskaźnika

#include <stdio.h>

#include <conio.h>   

main() 

{

double *p;

double x;

p=&x;

printf(”\n Podaj x:”);

scanf(”%lf ”, p);

printf(”\n x=%f”,*p);

getch();

return 0;

}

background image

Język ANSI C – funkcje

Wskaźniki i tablice

Nazwa tablicy w C jest stałym wskaźnikiem do pierwszego elementu tablicy. Np. 

jeżeli stworzymy definicje

int a[5];

int *pa;

i zastosujemy instrukcję 

pa=a;

to wskaźnik pa będzie wskazywał na a[0], czyli pierwszy element tablicy a.

Stosując wskaźniki można wykonać te same operacje na tablicach, co przy użyciu 

indeksowania.

background image

Język ANSI C – funkcje

Przykład. Proste działania na tablicach przy użyciu wskaźników
#include <stdio.h>
#include <conio.h>
main() {

int a[10];
int *pa,i;
pa=a; // przypisanie wskaźnikowi pa adresu   a[0]
*pa=10; // zapis 1 do a[0]

pa++; // zwiększenie wskaźnika, wskazuje on teraz na a[1]
*pa=20; // zapis 2 do a[1];
pa=pa+1; // wskaźnik wskazuje na element a[2]

for (i=2; i<10; i++)

{

printf("\n Podaj a[%d]=",i);
scanf("%d",pa);
pa++;

}

pa=a; // ustawienie wskaźnika na początek tablicy

// alternatywnie pa= pa -10

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

printf("\n a[%d]=%d", i,*pa++);

getch();}

background image

Język ANSI C – funkcje

Komunikacja funkcji z otoczeniem

Każda funkcja w C może dysponować mechanizmami komunikacji z otoczeniem. 

Funkcja może pobierać wartości lub adresy od funkcji wywołującej, może zwracać 

wartość do funkcji wywołującej, jak również modyfikować argumenty, których adresy 

zostały do niej przekazane.

Istnieją dwa główne sposoby przekazywania argumentów:

przekazywanie  przez wartość

przekazywanie przez zmienną( przekazywanie przez referencję, przez 

wskaźnik) 

background image

Język ANSI C – funkcje

Przekazywanie przez wartość

Przy przekazywaniu przez wartość, wartości argumentów są kopiowane do 

parametrów formalnych, zmiany parametrów formalnych nie mają wpływu na wartości 

argumentów ( potocznie mówi się, że funkcja działa na kopiach argumentów). Przy 

takim sposobie przekazywania parametrów funkcja wywoływana nie może zmienić 

argumentów zastosowanych przy wywołaniu.

Argument może być wyrażeniem, którego wartość jest najpierw obliczana i 

następnie przekazywana do funkcji wywołującej.  

background image

Język ANSI C – funkcje

Przykład. Przekazywanie przez wartość.
#include <stdio.h>
#include <conio.h>
int sqr (int);   // deklaracja funkcji
main() {

int t=10, kw;   
kw=sqr(t); // argument wywołania – zmienna nie jest modyfikowana, pomimo że 

// parametr formalny odpowiadający  t,  jest modyfikowany. 

printf (”\n Kwadrat liczby %d  wynosi :%d”,t, kw);
getch();
return 0; 

int sqr (int k)

k=k*k;

return k;

}

// Przypisanie k=k*k modyfikuje tylko lokalną zmienną k.

background image

Język ANSI C – funkcje

Przekazywanie przez zmienną

Przy przekazywaniu przez zmienną, do funkcji przekazuje się wskaźnik do 

argumentu ( adres argumentu), a nie jego wartość. Funkcja wywoływana dysponując 

tym wskaźnikiem może zmienić argument znajdujący się poza funkcją. 

Mechanizm przekazywania przez zmienną umożliwia przekazanie na zewnątrz 

funkcji więcej niż jedną wartość.

background image

Język ANSI C – funkcje

Przykład. Funkcja zwracająca dwie wartości
#include <stdio.h>
#include <conio.h>   
int dodaj_mnoz ( int , int, int *);
main() {

int x=10, y=20, suma, iloczyn;

suma=dodaj_mnoz(x,y,&iloczyn);
printf(”\n Suma= %d  iloczyn=%d ”, suma, iloczyn);
getch();
return 0;

}

int dodaj_mnoz ( int a, int b, int pc*)

{   

int sum, ilo;
sum=a+b;
ilo=a*b;
*pc=ilo;
return sum;

}                         

background image

Język ANSI C – funkcje

Przykład. Funkcja zamieniająca swe argumenty.
#include <stdio.h>
#include <conio.h>   
void swap ( int *, int *);
main() {

int i=10, j=20;
printf(”\n Wartości i oraz j przed zamianą i=%d j=%d:”, i,j);
swap(&i, &j);
printf(”\n Wartości i oraz j po zamianie i=%d j=%d:”, i,j);
getch();
return 0;

}

void swap ( int *px, int *py)

{     temp=*px;// zapisz do temp wartość znajdującą się pod

// adresem px

*px=*py;   // umieść w komórce wskazywanej przez px

//  wartość znajdującą się pod adresem 
// wskazywanym przez py

*py=temp; // umieść w komórce wskazywanej przez py,  

// wartość z komórki temp 

}                         

background image

Język ANSI C – funkcje

Przekazywanie tablic jako argumentów

Gdy argumentem funkcji wywoływanej jest tablica, do funkcji przekazywany jest 

jej adres ( adres pierwszego elementu). W związku z tym funkcja operuje na 

przekazanej jej tablicy, a nie na kopii. Funkcja ma możliwość zmiany tej zawartości.  

background image

Język ANSI C – funkcje

Przykład. Funkcja oblicza sumę elementów tablicy i umieszcza tę sumę w pierwszym 
elemencie tablicy ,
#include <stdio.h>
#include <conio.h>
void  suma_tab( int [ ], int );
main() { 

int  sum, a[5]= { 0,1,2, -1,3};
suma_tab(a,5);
printf(”\n Suma elementów tablicy a=%d”, a[0]);
getch();
return 0; }

void  suma_tab( int b[ ], int n)

{ int i,suma;

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

suma=suma+b[i];
b[0]=suma;  

}

background image

Język ANSI C – funkcje

Przykład. Funkcje wczytujące i drukujące tablicę jednowymiarową.
#include <stdio.h>
#include <conio.h>
void  wczyt_tab( int [ ], int );
void  druk_tab( int [ ], int );
main() { 

int  a[5],b[10];
wczyt_tab(a,5);
wczyt_tab(b,10);
druk_tab(a,5);
druk_tab(b,10);
getch();
return 0; }

void  wczyt _tab( int x[ ], int n)

{ int i;

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

{ printf(”\n Podaj element %d=”,i);

scanf(”%d”,&x[i]);} 

}    

background image

Język ANSI C – funkcje

Przykład cd.  Funkcje wczytujące i drukujące tablicę jednowymiarową.

void  druk _tab( int x[ ], int n)

int i;
for (i=0;i<n; i++)

printf(”\n  Element %d=%d ”,i, x[i]);

}    

background image

Język ANSI C – funkcje

Przykład. Funkcja obliczająca w tablicy sumy liczb parzystych, nieparzystych, 
dodatnich i ujemnych. #include <stdio.h>
#include <conio.h>
void  wczyt_tab( int [ ], int );
int oblicz_sumy(int [ ], int n,int *pnp,int *pd, int *pu);
main() {

int  a[10], suma_p, suma_np, suma_d, suma_u;
wczyt_tab(a,10);
suma_p=oblicz_sumy(a,10,&suma_np, &suma_d, &suma_u);
printf("\n suma_p=%d suma_np=%d suma_d=%d suma_u=%d",\

suma_p, suma_np, suma_d, suma_u);

getch();
return 0;

void  wczyt_tab(int x[ ], int n)

{ int i;

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

{ printf("\n Podaj element %d=",i);

scanf("%d",&x[i]);}

}

background image

Język ANSI C – funkcje

Przykład cd. Funkcja obliczająca w tablicy sumy liczb parzystych, 
nieparzystych, dodatnich i ujemnych ( wersja 1)

int oblicz_sumy(int x[ ], int n, int *pnp, int *pd, int *pu)

{

int i, suma_p=0, suma_np=0, suma_d=0, suma_u=0;
for (i=0;i<n; i++)

{

if (x[i]%2==0) suma_p+=x[i];
else  suma_np+=x[i];
if (x[i]>0) suma_d+=x[i];

else    suma_u+=x[i];

*pnp=suma_np;
*pd=suma_d;

*pu=suma_u;

}

return suma_p;

}

background image

Język ANSI C – funkcje

Przykład cd. Funkcja obliczająca w tablicy ilości liczb parzystych, nieparzystych, 
dodatnich i ujemnych ( wersja 2- krótsza)

int oblicz_sumy(int x[ ], int n, int *pnp, int *pd, int *pu)

{ int i,suma_p=0;

*pnp=*pd=*pu=0;
for (i=0;i<n; i++)

{

if (x[i]%2==0) suma_p+=x[i];
else  *pnp+=x[i];
if (x[i]>0) *pd+=x[i];

else    *pu+=x[i];

}

return suma_p;

}

background image

Język ANSI C – tablice wielowymiarowe

W języku C poza tablicami jednowymiarowymi można stosować tablice 

wielowymiarowe. Tablice dwuwymiarowe odpowiadają macierzom. Możliwość 
definiowania tablic wielowymiarowych  w C wynika stąd, że elementy tablicy mogą być 
tablicami. 

Zapis 

int a[3][3]; 

definiuje tablicę o trzech wierszach i trzech kolumnach, lub też jedno-wymiarową tablicę 
o trzech elementach, z których każdy jest tablicą składającą się z trzech elementów.

Elementy tablicy zapisujemy jako  a[i] [j]. 

background image

Język ANSI C – tablice wielowymiarowe

Inicjalizacja tablic dwuwymiarowych

Przykład. Zainicjować tablicę b[3] [3].

int b[3][3]= { {2,1,1}, {3,4,2}, {2,3,4}};

W wyniku takiej inicjalizacji otrzymujemy następujące wartości elementów :

b[0][0] :2  b[0][1] : 1     b[0][2] :1
b[1][0] :3  b[1][1] : 4     b[1][2] :2
b[2][0] :2  b[2][1] : 3     b[2][2] :3

Tablicę [3][3] można też zainicjować w sposób następujący:

int b[3][3]= {2,1,1,3,4,2,2,3,3};

Tablice wielowymiarowe są zapamiętywane w C wierszami ( ostatni indeks z prawej 

strony zmienia się najszybciej ). Przykładowo dla tablicy b

mamy następujące rozmieszczenie tablicy w pamięci 

b[0][0], b[0][1], b[0][2], b[1][0], b[1][1], b[1][2], b[2][0], b[2][1], b[2][2].

background image

Język ANSI C – tablice wielowymiarowe i funkcje

Gdy tablica wielowymiarowa jest parametrem funkcji, konieczne jest podanie 

wszystkich wymiarów poza pierwszym.

Przykład. Napisać program wczytujący i drukujący dwie tablice o wymiarze 3x3.

#include <stdio.h>

#include <conio.h> 

void wczyt2D( int x[ ][3], int n)

{ int i,j,k;

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

for (j=0;j<3;j++) 

do {

printf (”\n Podaj element [%d][%d]=”,i, j);

k=scanf(”%d”, &x[i][j]);

fflush(stdin);

} while (k==0);

return; }                      

background image

Język ANSI C – tablice wielowymiarowe i funkcje

Przykład c.d.
void druk2D( int x[ ][3], int n)

{ int i,j,k;

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

{ for (j=0;j<3;j++) 

printf (”element [%d][%d]=%d”,i, j, x[i][j]);

printf(”\n”);

}

return;

}

int main()

{  int a[3][3], b[3][3];

wczyt2D(a,3);
wczyt2D(b,3);
druk2D(a,3);
druk2D(b,3);
getch();
return 0;

}

background image

Język ANSI C – funkcje

#include <stdio.h>

#include <conio.h> 
void kopiuj2D( int x[ ][3], int n);
int main()
{

int b[3][3]= { {2,1,1}, {3,4,2}, {2,3,4}};

int a[3][3];

kopiuj2D( a,b);

getch();

}
void kopiuj2D( int x[ ][3],y[ ][3], int n)

{ int i,j,k;

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

for (j=0;j<3;j++) 

x[i][y]=y[i][j];

}

background image

Język ANSI C – funkcje

Przykład. Przepisywanie tablicy  dwuwymiarowej do tablicy jednowymiarowej. 
#include <stdio.h>
#include <conio.h>

void kopiuj1D_2D( int b[ ][2],int n1, int d[ ])

{ int i,j,k=0;

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

for (j=0;j<2;j++)

d[k++]=b[i][j];

}

int main ()

{ int tab2D[2][2]={ {1,2},{2,3}};

int tab1D[4];
int i;

kopiuj1D_2D(tab2D, 2, tab1D);
for (i=0;i<4; i++)

printf("   %d ", tab1D[i]);

getch();

}

background image

Język ANSI C – funkcje

Przykład. Mnożenie macierzy. 
#include <stdio.h>
#include <conio.h>
#define  m   3 
void mnoz_mac( int a[ ][m],int b[][m], int c[ ][m], int n)

{ int i,j,k,s;

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

for (k=0;k<n;k++)

{ s=0;

for (j=0;j<n;j++)

s=s+a[i][j]* b[j][k];

c[i][k]=s;  }

}

int main ()
{ int u[m][m]={ {1,2,1},{1,1,1}, {2,1,1}};

int v[m][m]={ {2,1,0},{1,2,0}, {3,2,1}};
mnoz_mac( u,v, z,3);
for (i=0; i<n;i++)

{ for (j=0;j<3;j++) 

printf (”element [%d][%d]=%d”,i, j, x[i][j]);

printf(”\n”);

getch(); }

background image

Język ANSI C – dynamiczna alokacja pamięci cz. I

W języku ANSI C  istnieją zasadniczo dwa rodzaje zmiennych:

zmienne zwykłe definiowane w funkcji main() lub na zewnątrz wszystkich funkcji, 

lub w pewnym bloku. Każda zmienna tego rodzaju posiada swoją nazwę oraz 

określony typ.   

zmienne dynamiczne tworzone i usuwane w trakcie działania programu;  taki 

sposób przydzielania pamięci zwany jest alokacją w trakcie działania programu 

(ang. run-time allocation). Zmienne te nie posiadają nazw, znane są wyłącznie

adresy przydzielonej im pamięci ( wskaźniki do tej pamięci).

Do przydzielania pamięci zmiennym dynamicznym służą w ANSI C funkcje malloc 

calloc. Do usuwania zmiennych dynamicznych stosuje się funkcję free

background image

Język ANSI C – dynamiczna alokacja pamięci cz. I

Funkcje malloc i calloc (stdlib.h)

Każda z tych funkcji alokuje przydziela pamięć i zwraca adres tej pamięci (wskaźnik do 
tej pamięci). Rozmiar przydzielanej pamięci nie musi być znany podczas kompilacji.

Funkcja malloc

Nagłówek funkcji tej ma postać następującą:

void * malloc (int);

Funkcja malloc oczekuje, jako swojego argumentu liczby bajtów, które mają być 

przydzielone w danym wywołaniu funkcji. Jeżeli przydzielenie pamięci jest możliwe, 
funkcja zwraca wskaźnik do tej pamięci, jeśli nie, funkcja zwraca NULL (zerowy 
wskaźnik). 

Zwracany wskaźnik jest typu void*, czyli jest to wskaźnik do void.

Wskaźnik ten musi być przekształcony (przez rzutowanie) na wskaźnik do żądanego 
typu. Język C gwarantuje, że wskaźnik do void może być przekształcony na wskaźnik 
do każdego innego typu.

background image

Język ANSI C – dynamiczna alokacja pamięci

Przykład. Zastosowanie funkcji malloc do alokacji pamięci dla zmiennej dynamicznej 
typu int. 

#include <stdio.h>

#include <conio.h>

int main() {

int *ptr;

ptr=(int*) malloc( sizeof(int));

if (ptr==NULL){

printf(”\n Przydzielenie pamięci nie było możliwe”);

getch();return 1;}

printf(” Podaj wartosc :”);

scanf(”%d”, ptr);

printf(”\n Wartosc to :”, *ptr);

free(ptr);

getch(); 

return 0; }

background image

Język ANSI C – dynamiczna alokacja pamięci cz. I

Funkcja calloc

Nagłówek funkcji tej ma postać następującą:

void * calloc (int,int);

Funkcja calloc oczekuje dwóch argumentów typu int. Pierwszy 

argument oznacza liczbę bloków pamięci, które mają zostać 

przydzielone, a drugi rozmiar pojedynczego bloku. Funkcja zwraca

wskaźnik do pierwszego bloku. Wskaźnik ten jest typu void* i musi być 

rzutowany na wskaźnik do wymaganego typu. 

background image

Język ANSI C – funkcje

Przykład. Zastosowanie funkcji calloc do alokacji pamięci dla tablicy liczb typu int. 

#include <stdio.h>

#include <conio.h>

int main() {

int *ptr;

ptr=(int *) calloc(5, sizeof(int));

for (i=0;i<5;i++) {

printf(”\n Podaj element %d”, i);

scanf(”%d”, ptr++); }

ptr=ptr-5;

for (i=0;i<5;i++) {

printf(”\n Element [%d]=%d”, *ptr++);

ptr-=5;

free(ptr);

getch(); 

background image

Język ANSI C – dynamiczna alokacja pamięci cz. I

Przykład. Dynamiczna alokacja tablicy z użyciem funkcji zwracającej wskaźnik. 
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int * wczyt_tab(int n);

int main(int argc, char **argv)

{

int *pa,i,n=5;
pa=wczyt_tab(5);
for (i=0;i<n;i++)

printf("\n Element[%d]=%d",i, *pa++);

pa-=5;
free(pa);
getch();}

background image

Język ANSI C – funkcje

Przykład cz. II ( ciąg dalszy programu)
// definicja funkcji zwracającej wskaźnik do wczytanej tablicy
int * wczyt_tab(int n)

{

int i,*px;
px=(int*) malloc(n*sizeof(int));

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

{ printf("\n Podaj element[%d]=",i);

scanf("%d",px++);

}

px=px-n;

return px;
}

background image

Język ANSI C – funkcje

Przykład. Program wczytujący tablicę dwuwymiarową przy użyciu wskaźnika, do 
funkcji przekazywany jest wskaźnik do pierwszego elementu tablicy dwuwymiarowej.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
//Do funkcji przekazywany jest wskaźnik do pierwszego elementu tablicy 
//dwuwymiarowej oraz liczba wierszy i liczba kolumn.

void wczyt(int  *px, int w, int k)
{

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

for (j=0;j<k;j++)

{

printf("\n Podaj element [%d][%d]=",i,j);
scanf("%d",px++);

}

}

background image

Język ANSI C – funkcje

// Przykład c.d. zastosowanie funkcji wczyt do wczytania

// tablicy dwuwymiarowej 3x3. 

int main()
{

int x[3][3];
int *px;
int i,j;
clrscr();
px=&x[0][0];
wczyt(px,3,3);

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

for (j=0;j<3;j++)

printf("\n  element [%d][%d]=%d",i ,j, x[i][j]);

getch();

return 0; }

background image

Język ANSI C – funkcje

Przykład. Funkcja wczyt_D alokuje pamięć dla tablicy dwuwymiarowej o zadanej 
liczbie kolumn i zadanej liczbie wierszy, wczytuje tablicę i zwraca wskaźnik do 
jej pierwszego elementu.
int *wczyt_D(int w, int k)
{

int *px;
int i,j;
px=(int*)calloc(w*k,sizeof(int));

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

for (j=0;j<k;j++)

{

printf("\n Podaj element [%d][%d]=",i,j);
scanf("%d",px++);

}

px=px-w*k;
return px;

}

background image

Język ANSI C – funkcje

// Przykład c.d. zastosowanie funkcji wczyt_D do wczytania

// tablicy dwuwymiarowej 3x3.

int main()
{

int *py,i,j;

clrscr();
py=wczyt_D(3,3);

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

for (j=0;j<3;j++)

printf("\n  element [%d][%d]=%d",i,j,*py++);

py-=9;

free(py); 

getch();

return 0;}

background image

Język ANSI C – operatory bitowe

Język C pozwala programiście na bezpośrednie współdziałanie ze sprzętem ( 

hardware’m) poprzez użycie operatorów bitowych i wyrażeń bitowych. Operatory bitowe 

umożliwiają działanie na pojedynczych bitach. Operatory te działają wyłącznie z typami 

całkowitymi np. takimi jak char czy też int.   

Aby stosować operatory bitowe w danym systemie powinno się zgromadzić następujące 

informacje:

- liczba bitów, które tworzą bajt,

- liczba bajtów dla typów całkowitych,

- system kodowania znaków (np. ASCII)

- typ stosowanej reprezentacji liczb ujemnych( np. kod U2)

Poniżej założymy 8-bitowy bajt  i  16-bitową komórkę dla przechowywania

liczb całkowitych oraz kod U2.  

background image

Język ANSI C – operatory bitowe

Operatory bitowe to:

- ‘ ~ ‘   - bitowy operator uzupełnienia do 1,

-’&’     - bitowy operator koniunkcji (iloczynu logicznego),

-’ | ‘     - bitowy operator alternatywy (sumy logicznej),

- ’^’     - bitowy operator różnicy symetrycznej (XOR),

- ‘<<‘  - bitowy operator przesunięcia w lewo,

- ‘>>’  - bitowy operator przesunięcia w prawo. 

background image

Język ANSI C – operatory bitowe

Bitowy operator uzupełnienia do 1,  ‘ ~ ‘  (zwany tyldą), neguje poszczególne bity 

swojego argumentu (zamienia zera na jedynki a jedynki na zera). 

Przykład.

short int x,y;

x=6;

y=~x;

printf(„\n Wartosc y=%d”, y);

Wartość ~x wynosi 7. Wynika to ze stosowania kodu U2 reprezentowania liczb 
ujemnych.   Liczba 6 ma następującą reprezentację binarną

0000 0000 0000 0110

Po negacji otrzymujemy

1111 1111 1111 1001 czyli -7 w U2.

( Można to łatwo sprawdzić:

+7  0000  0000 0000 0111    ->   -7 w U1 1111 1111 1111 1000 , czyli po dodaniu

1, otrzymujemy  1111 1111 1111 1001)

background image

Język ANSI C – operatory bitowe

Rozszerzenie znakowe ( ang. sign extension) 

W operacjach wykonywanych na bitach występuje problem konwersji pomiędzy różnymi 
formatami liczb całkowitych (np. char i short int).

Przy konwersjach takich istnieje konieczność zachowania wartości konwertowanej 
liczby. Dla liczb ujemnych przy przechodzeniu z formatu krótszego na dłuższy, 
wszystkie bity starsze, które nie występowały w formacie krótszym zamieniane są na 1. 
Działanie takie nie powoduje zmiany wartości liczby ujemnej.

Przykład.   Dana jest liczba    -6    w  kodzie U2  umieszczona w komórce 8-bitowej

0000 0110        +6  w U2,

1111 1001         -6  w U1

1111  1010        -6 w U2

Po rozszerzeniu do 16 bitów mamy

1111 1111 1111 1010

Można sprawdzić, że kod ten reprezentuje -6 w U2.

+16  0000 0000 0000 0110,  - 6 w U1 1111 1111 1111 1001 , 

-6   w  U2 

1111 1111 1111 1010

background image

Bitowe operatory logiczne

-’&’     - bitowy operator koniunkcji (iloczynu logicznego),

-’ | ‘     - bitowy operator alternatywy (sumy logicznej),
- ’^’     - bitowy operator różnicy symetrycznej (XOR).

Operatory te działają niezależnie na parach bitów o tej samej wadze obydwu swoich 

argumentów. 

Wyniki działania poszczególnych operatorów pokazano w tabeli.

Dla dwóch danych bitów b1 i b2 otrzymujemy:

Język ANSI C – operatory bitowe

b1

b2

b1&b2

b1|b2

b1^b2

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

background image

Język ANSI C – operatory bitowe

Przykład. Dane są następujące definicje

short int lanbit1=12;

short int  lanbit2=-35

lanbit1         000 000 000 1100

lanbit2         1111 1111 1101 1101

Wykonać podane poniżej działania w programie i poprzez obliczenia na liczbach 

binarnych

1. ~lanbit1

-13

9.   lanbit1^lanbit2     

-47

2.  ~lanbit2           

34

10. ~(lanbit1^lanbit2) 

46

3.  lanbit1&lanbit2

12

4.  ~lanbit1&lanbit2    

-47

5.   ~(lanbit1&lanbit2) 

-13

6.   lanbit1| lanbit2       

-35

7. ~(lanbit1|lanbit2)      

34      

8.   (~lanbit1|lanbit2)            

background image

Język ANSI C – operatory bitowe

Przykład. Maskowanie w słowie 8-go bitu.

#include <stdio.h>

#include <conio.h>

int main() 

{ int c;

int maska=127;

while ((c=getchar())!=EOF)

putchar( c&maska);

getch();

}  

background image

Język ANSI C – operatory bitowe

Przykład. Wyznaczanie reprezentacji binarnej liczby 8-bitowej.

#include <stdio.h>

#include <conio.h>

int main()

{ char x=12;

int i,k=1, bit[8];

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

{ if (x&k) bit[i]=1; else bit[i]=0;

k*=2; } 

for (i=0;i<8;i++) printf(”  %d ”,bit[i]);

getch();

return 0;

}

background image

Język ANSI C – operatory bitowe

Operatory przesunięć bitowych (ang. bitshift operators) 

Operatory bitowe przesuwają bity swego argumentu znajdującego się po lewej 

stronie operatora o zadaną liczbę bitów w lewo lub w prawo. Wyrażenia z użyciem tych 
operatorów można zapisać następująco:

E1<< E2      lub     E1>>E2,

gdzie E1 reprezentuje przed wykonaniem operacji wzorzec bitowy, który ma zostać 

przesunięty,  dla operatora<< w lewo, a dla operatora >> w prawo.

Jeśli nie ma nadmiaru arytmetycznego, dla operatora << przesunięcie jest 

równoważne mnożeniu przez        a na najmłodsze pozycje pierwszego argumentu 
wchodzą zera.  Działanie  operatora  >>  odpowiada dzieleniu całkowitemu przez

dla typów bez znaku ( unsigned), wtedy na skrajne pozycje z lewej strony 

wchodzą zera.  Dla typów ze znakiem, jeżeli wchodzą zera dla liczb nieujemnych, a 
jedynki dla liczb ujemnych mówimy o przesunięciu arytmetycznym, a jeżeli zera

niezależnie od znaku liczby, to jest to tzw.  przesunięcie logiczne.

2

2

E

2

2

E

background image

Język ANSI C – operatory bitowe

Przykład. Użycie operatorów bitowych przesunięcia w lewo i w prawo.

#include <stdio.h>

#include <conio.h>

int main() {

int x1=‘A’, x2=‘0’;

int y1=3,y2=2;

printf(”\n %d”, x1<<y1);// kod ASCII  znaku ‘A’ jest równy 65  stąd 

// w wyniku przesunięcia otrzymujemy 520

printf(”\n %d ”, x2>>y2); // przesunięcie  prawo o 2 odpowiada dzieleniu

// całkowitemu, otrzymujemy 

getch();

}

background image

Język ANSI C – operatory bitowe

Przykład. Ustawianie określonego bitu w słowie.

Ustawianie bitu o numerze nr_bitu na 1

x= x | 1<< nr_bitu;

Najpierw  realizowane jest przesunięcie 1 o nr_bitu w lewo,

czyli wstawienie 1 na określoną, następnie wykonywana jest suma logiczna, co 

powoduje ustawienie bitu na 1, jeśli był równy 0.  

Ustawianie bitu o numerze nr_bitu na 0

x= x& ~(1<<nr_bitu);

Na miejsce bitu o numerze nr_bitu wstawiane jest 0, i następnie wykonywany jest 
iloczyn logiczny, co powoduje ustawienie bitu na 0, jeżeli był równy 1. 

background image

Język ANSI C – operatory bitowe

Przykład. Dane jest słowo 8-bitowe. Napisać funkcję wyznaczającą wartość

dziesiętną  grupy bitów począwszy od pozycji p

int obl_wart_bitow (char  x, int n, int p)

// n – liczba bitów, p –pozycja ( pozycje numerowane od 0)   

{  

return x>>(p+1-n)& ~( ~0<<n); 

}

Zasada działania  funkcji tej jest następująca:

- przesunięcie bloku n-bitowego na najmłodsze pozycje ( pozycje 

o wagach od 1  do           ( działanie x>> (p+1-n)  )

- utworzenie maski wcinającej najmłodszych bitów ze słowa 8-bitowego

( maska ta ma 1 na najmłodszych bitach i zero na pozostałych)

- obliczenie iloczynu bitowego przesuniętego bloku n-bitowego i maski.

1

2

n

background image

Język ANSI C – operatory bitowe

Przykład. Operatory bitowe (ciąg dalszy).

Tworzenie maski

- ~0  - oznacza utworzenie słowa składającego się z samych jedynek,

- ~0<<n – przesunięcie maski w lewo o pozycji , powoduje, że na 

najmłodszych n pozycjach pojawiają się zera,

- ~( ~0<<n) – po zanegowaniu na najmłodszych  pozycjach pojawiają się

jedynki, a na pozostałych zera, czyli utworzona została

potrzebna maska.

background image

Język ANSI C – operatory bitowe

Zadania z operatorów do realizacji na laboratorium.

1. Dla zadanej liczby dodatniej typu char zanegować jej bity przy użyciu operatora ~, i 

obliczyć przy użyciu kodu U2 wartość bezwzględną otrzymanej liczby, porównać z 
wynikiem na ekranie.

2. Dla zadanej liczby ujemnej  typu char zanegować jej bity przy użyciu operatora ~, i 

obliczyć przy użyciu kodu U2 wartość bezwzględną otrzymanej liczby, porównać z 
wynikiem na ekranie.

3. Wyznaczyć wzorzec bitowy danej liczby typu short int i zapisać w tablicy, 

wydrukować tablicę.

4. Utworzyć maskę bitową zawierającą same zera poza wybranym bitem równym 1 

stosując operatory przesunięć bitowych.

5. Wyznaczyć dla wartości typu char wartość dziesiętną wybranej grupy bitów 

począwszy od pozycji o indeksie p.  

6. Sprawdzić czy n-ty bit ma wartość 1.

7. Zmienić wartość n-tego bitu liczby stosując operatory bitowe.

8. Wstawić do słowa kodowego typu char na pozycję najstarszą wartość 1, jeśli 

liczba jedynek jest nieparzysta, lub zero jeżeli jest parzysta. 

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Zasięg

Jeżeli pewien obiekt (np. zmienna) zostanie zdefiniowany w programie, to można 

go użyć w odpowiedniej części programu, której rozmiar jest określany przez tzw. 

zasięg identyfikatora tego obiektu (zmiennej).  W języku C wyróżniamy cztery zasięgi:

-zasięg bloku

-zasięg  funkcji

-zasięg prototypu

-zasięg pliku

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Zasięg  bloku cz. 1

Blok to lista instrukcji  umieszczona w klamrach {  }. Wszystkie identyfikatory 

zadeklarowane na początku bloku mają zasięg ograniczony do bloku, w którym zostały 

zdefiniowane.  

{

int  i,j;

i+=1;

j*=2;......

}

Ciało funkcji stanowi blok, stąd parametry formalne mają zasięg ograniczony do ciała 

funkcji. 

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory 

Zasięg  bloku cz. 2

Gdy bloki są zagnieżdżane ( jeden blok znajduje się wewnątrz drugiego bloku) 

definicja identyfikatora w bloku zewnętrznym rozciąga się również na  blok wewnęrzny. 

Jeżeli w bloku wewnętrznym zdefiniowano identyfikator o tej samej nazwie co 

identyfikator zdefiniowany w bloku zewnętrznym, to identyfikator z bloku zewnętrznego 

nie będzie dostępny. Mówimy wtedy, że identyfikator wewnętrzny przesłania 

identyfikator zewnętrzny.

{     

double x=20;

{

int i, x[10];

....

}

x+=10;

}   

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory cz. 3  

Zasięg  prototypu

Zasięg ten odnosi się do nazw zdefiniowanych w prototypach funkcji. W prototypach 

nie muszą występować nazwy parametrów, jeżeli jednak występują, to nie muszą być 

zgodne z nazwami parametrów formalnych, ani też ich nazwy nie powodują konfliktu z 

jakimikolwiek innymi nazwami. 

Przykład.

double * f2  (int *pd, int n);

Prototyp funkcji zwracającej wskaźnik do double. Nazwy pd i  nie muszą występować.

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Zasięg  funkcji

Odnosi się on do etykiet stosowanych w instrukcjach skoku goto. Etykiety wewnątrz 

funkcji nie mogą się powtarzać. 

Zasięg pliku

Identyfikatory zdefiniowane na zewnątrz wszystkich bloków mają zasięg ograniczony 

do pliku. Oznacza to, że są one widoczne od miejsca, w którym zostały zdefiniowane do 

końca pliku. Definicje umieszczone w pliku nagłówkowym, który został włączony 

dyrektywą   #include, obowiązują do końca pliku, w którym została umieszczona ta 

dyrektywa. 

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Klasy pamięci dla zmiennych

Klasa pamięci określa typ pamięci, w której przechowywana jest zmienna. Klasa 

pamięci zmiennej określa moment utworzenia zmiennej, czas przechowywania jej 

wartości, jak również moment usunięcia danej zmiennej. Wyróżnia się następujące klasy 

pamięci

- klasa pamięci auto

- klasa pamięci  static

- klasa pamięci register

- klasa pamięci external

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Klasa pamięci auto ( zmienne automatyczne)

Zmienna zdefiniowana wewnątrz funkcji otrzymuje domyślną klasę auto ( zwana jest 

zmienną automatyczną). Definicję zmiennej automatycznej można zapisać następująco

auto int liczba;

jednak zwykle słowo auto jest pomijane.  Pamięć dla zmiennej jest alokowana 

(przydzielana), gdy sterowanie programu wchodzi do bloku zawierającego definicję 

danej zmiennej i jest dealokowana, gdy sterowanie opuszcza ten blok. Termin auto 

wywodzi się stąd, iż proces ten odbywa się automatycznie bez udziału programisty. 

Zmienna typu auto jest widoczna tylko w bloku, w którym znajduje się jej definicja.

Jeżeli zmienna typu auto jest jednocześnie definiowana i inicjalizowana, to jej 

inicjalizacja jest powtarzana za każdym razem, gdy sterowanie programu wchodzi do 

bloku ją zawierającego. 

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Klasa pamięci static

Zmienna o klasie pamięci static może być zdefiniowana wewnątrz bloku np. 

wewnątrz funkcji albo też na zewnątrz wszystkich bloków. Zmienne statyczne są 

tworzone przed rozpoczęciem wykonywania programu i istnieją przez cały czas jego 

wykonywania.   

Definicja zmiennej statycznej typu int ma postać

static int liczba;

Zmienne statyczne zdefiniowane wewnątrz bloku mają ten sam zasięg co inne 

zmienne zdefiniowane w bloku.  Jednak zachowują one swą wartość po opuszczeniu 

bloku przez sterowanie programu. Powoduje to na przykład  w przypadku funkcji, że 

wartość statycznej zmiennej lokalnej może być przechowywana pomiędzy kolejnymi 

wywołaniami funkcji.  

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Przykład. Funkcja zliczająca i zwracająca ilość swoich wywołań.

int uchwyt_bledu (void)

{

static int liczba;

liczba++; 

return liczba;

}

Zmienna liczba jest inicjalizowana tylko jeden raz przy pierwszym wywołaniu funkcji. 

Przy każdym kolejnym wywołaniu, wartość zmiennej liczba jest zwiększana o 1 z 

przechowywana między wywołaniami funkcji, gdy sterowanie programu opuszcza blok 

funkcji.

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Zmienna statyczna c.d.

W przypadku zmiennej statycznej, która została zdefiniowana poza wszystkimi 

blokami ( na zewnątrz wszystkich funkcji), definicja taka ogranicza widoczność zmiennej 

do pliku, w którym definicja ta wystąpiła.  

Przykład. Zasięg zmiennej statycznej.

W skład projektu wchodzą dwa pliki : plik1.c i plik2.c

// plik1.c

static double x;

int f1 (void)

{        ….}

double f2( double x)

{……..}

// plik2.c

static int x;
char * f3( char *s)
{ …} 

W obu plikach występują zmienne o nazwie x, jednak są one dostępne tylko tam,  
gdzie występują ich definicje.   

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Klasa pamięci register

Definiując zmienną typu register tworzy się zalecenie dla kompilatora, aby 

umieścił daną zmienną w rejestrze procesora, traktowanym jako komórka pamięci. 

Powodem stosowania takiego zalecenia jest czas dostępu, który jest zwykle dla 

rejestrów znacznie krótszy niż dla pamięci zewnętrznej. Kompilatory mogą 

uwzględniać to zalecenie lub nie, z drugiej strony jednak sam kompilator stara się 

umieszczać w rejestrach częściej używane zmienne np. liczniki pętli. Jeżeli 

zmienna nie stanie się zmienną register, to będzie zmienną automatyczną.

#include <stdio.h>

#include <conio.h> 

int main() {

register int i;

for (i=1;i<1000;i++)   sum+=i;   

printf(”\n Suma=%d”,suma); getch(); }

background image

Język ANSI C – zasięgi, klasy pamięci i kwalifikatory  

Klasa pamięci extern ( program z jednym plikiem źródłowym)

background image

Język ANSI C – pliki 

Wprowadzenie cz. 1

Plik jest podstawową jednostką służącą do przechowywania informacji w każdym 

systemie operacyjnym. Każdy plik ma swoją nazwę, długość w bajtach, atrybuty 

określające sposób korzystania z pliku oraz nadane uprawnienia dla poszczególnych 

użytkowników określające sposób korzystania z pliku. 

W systemach komputerowych występują różnego rodzaju urządzenia, do których 

przesyłane są dane czy też są z nich pobierane. System operacyjny izoluje jednak 

programy użytkowe od szczegółów pracy poszczególnych urządzeń.  Jest to 

realizowane przy użyciu tzw. strumieni.  Strumienie stanowią element pośredniczący 

między programem a systemem operacyjnym. Wyróżniamy strumienie binarne, które 

stanowią ciągi bajtów bez żadnej specjalnej struktury.  Plik związany ze takim 

strumieniem jest to tzw. plik binarny. Strumień może  też  posiadać pewną strukturę –

składać się z linii tekstu zakończonych znakiem końca linii. Plik związany z takim 

strumieniem to tzw. plik tekstowy). 

background image

Język ANSI C – pliki 

Wprowadzenie cz. 2

Strumienie są zwykle buforowane, oznacza to, że np. zapis w programie do 

pliku jest tylko zapisem do pewnego obszaru pamięci. Zawartość bufora jest 

zapisywana na nośniku, gdy bufor zostanie napełniony, lub też  program zażąda 

tego w sposób jawny.   Długość pliku może być ograniczona wielkością nośnika lub 

też ograniczenie może wynikać z pewnych własności systemowych (zakres typu 

całkowitego). 

Elementy pliku są zwykle dostępne sekwencyjnie, co oznacza, że w danym 

momencie istnieje dostęp tylko do jednego elementu pliku. Liczba elementów pliku 

może się zmieniać w trakcie przetwarzania pliku.   Koniec pliku jest zaznaczany z 

punktu widzenia języka C znakiem EOF( ang. end-of-file). W pliku jest to znak ctrl-Z 

(ASCII 26).

background image

Język ANSI C – pliki 

Z każdym plikiem jest związana pewna zmienna, tzw. wskaźnik pliku 

określająca aktualnie dostępny element pliku. 

Numeracja elementów pliku zaczyna się od zera. 

Identyfikacja pliku w systemie operacyjnym może się odbywać poprzez 

wskaźnik do pliku (ang. file pointer) lub też uchwyt pliku (ang. handle) bedący

pewną liczbą identyfikującą plik w ramach systemu operacyjnego.

Język C nie ma wbudowanych operacji wejścia-wyjścia związanych z 

realizacją funkcji plikowych, stosowane są dla ich realizacji funkcje biblioteczne z 

pliku stdio.h.

Aby rozpocząć realizację operacji plikowych na istniejącym pliku lub też 

utworzyć nowy plik, należy zdefiniować wskaźnik do pewnej struktury zawierającej 

konieczne informacje dla uzyskania dostępu do pliku.

background image

Język ANSI C – pliki 

Definicja wskaźnika do pliku może mieć następującą postać:

FILE *fp;

FILE jest typem strukturowym zdefiniowanym w pliku stdio.h.

Przetwarzanie pliku w trakcie działania programu może polegać na wykonywaniu 

różnego rodzaju operacji na pliku np. utworzeniu lub otwarciu pliku, zapisie elementów, 

odczycie elementów, usuwaniu elementów czy też porządkowaniu (np. sortowaniu). 

Rozpoczęcie operacji na pliku wymaga jego utworzenia lub otwarcia.

W języku C plik jest tworzony lub otwierany przy użyciu funkcji fopen (istnieje też 

funkcja open do tzw. operacji niskopoziomowych). 

Po zakończeniu operacji na pliku, plik jest zamykany przy użyciu funkcji fclose.

Zamknięcie pliku powoduje zarejestrowanie zmian dokonanych w pliku w trakcie jego 

przetwarzania. 

background image

Język ANSI C – pliki 

Funkcja fopen i parametry otwarcia pliku cz.1

Funkcja fopen posiada dwa parametry. Pierwszy jest parametrem typu tablica znaków

określający nazwę pliku, drugi parametr też będący tablicą znaków, określa tzw. tryb 

utworzenia lub otwarcia pliku. 

Przykład.

FILE *fp;

fp=fopen("Plik1.dat", "w");

Nazwa pliku podana bez ścieżki dostępu oznacza, że plik będzie się znajdował w tym 

katalogu, w którym zapisano projekt. Można też podać ścieżkę dostępu do pliku w 

sposób następujący:

fp=fopen("C:\\moje dokumenty\\Plik2.dat", "w");

(należy stosować podwójny ukośnik dla uzyskania pojedyńczego znaku \, dla tego znaku 

wymgana jest tzw. sekwencja ucieczki).

background image

Język ANSI C – pliki 

Funkcja fopen i parametry otwarcia pliku cz.2

Funkcja fopen zwraca wskaźnik do pliku, jeśli jego otwarcie lub utworzenie było 

możliwe. Jeżeli nie było to możliwe, funkcja fopen zwraca zerowy wskaźnik NULL. 

Wskazanym jest sprawdzanie uzyskanej wartości wskaźnika przed rozpoczęciem 

operacji plikowych w następujący sposób

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

main() {

FILE *fp;

fp=fopen("Plik1.dat", "w");

if (fp!=NULL) {   //  wystarczy if (fp)

printf(" Plik został utworzony"); getch();}

else  printf("\n Plik nie zostal utworzony"); getch(); exit(1);}

background image

Język ANSI C – pliki 

Funkcja fopen i parametry otwarcia pliku cz.3

Tryb

Jeśli plik istnieje

Jeśli plik nie 

istnieje

"r"

Otwiera plik do czytania

Błąd

"w"

Otwiera nowy plik, jeśli 

istniał plik o danej nazwie 

jego zawartość jest 

kasowana

Tworzy nowy plik

"a"

Otwiera plik do 

dopisywania

Tworzy nowy plik

Tryby otwarcia plików cz. 1

background image

Język ANSI C – pliki 

Tryby otwarcia plików cz. 2

Funkcja fopen i parametry otwarcia pliku cz.4

Tryb

Jeśli plik istnieje

Jeśli plik nie 

istnieje

"r+"

Otwiera plik do odczytu i 
zapisu

Błąd

"w+"

Otwiera nowy plik do 

zapisu i odczytu, jeśli istniał 

plik o danej nazwie jego 

zawartość jest kasowana

Tworzy nowy plik

"a+"

Otwiera plik do 

dopisywania i odczytu

Tworzy nowy plik

background image

Język ANSI C – pliki 

Funkcja fopen i parametry otwarcia pliku cz.4

Powyższe tryby dotyczą zasadniczo plików tekstowych ( zależy to od ustawienia 

zmiennej systemowej _fmode). Dla plików binarnych należy dodać do nazwy trybu 

literę b, np. "rb", "wb", "r+b", "w+b". Dla trybów tekstowych należy dodać literę t, czyli 

"rt", "wt", "r+t", "w+t".

background image

Język ANSI C – pliki 

Standardowe funkcje plikowe /ANSI C i BB/

fopen

putc

feof

fflush

fclose

getc

ferror

setbuf

ftell fgetc

fgetpos

setvbuf

fwrite

fprintf

fsetpos

fread

fscanf

remove

fseek

fputs

rewind

fputc

fgets

clearerror

Pewnych funkcji ze standardu nie ma w BB, natomiast  w BB występuje cały szereg 

dodatkowych funkcji plikowych(np. do operacji niskopoziomowych czy też  do działań na 
katalogach, które są specyficzne dla  danej grupy systemów operacyjnych).

background image

Język ANSI C – pliki 

Funkcja fopen

FILE *fopen( const char *file_name,  const char *access_mode);

Argument pierwszy wskazuje plik do otwarcia, argument drugi access_mode określa czy 

plik (strumień) zostanie otwarty do zapisu, odczytu czy obu tych operacji. Określa on też 

tryb (binarny czy tekstowy). Funkcja zwraca wskaźnik do pliku (wskaźnik do struktury 

FILE wykorzystywanej przy dostępie do strumienia) albo też NULL.

FILE *fp;

fp=fopen (”Plik3.dat”, ”r+b”);

Maksymalną liczbę otwartych plików określa stała FOPEN_MAX, maksymalną długość 

nazwy stałą FILENAME_MAX.

background image

Język ANSI C – pliki 

Funkcja fclose

int fclose (FILE *fp);

Funkcja ta zamyka plik (strumień) związany ze strukturą FILE wskazywaną przez fp.

Funkcja zwraca 0, jeśli działanie się powiodło lub też EOF. W przypadku strumieni 

wyjściowych, strumień jest opróżniany przed zamknięciem pliku. 

FILE *fp;

fclose (fp);

background image

Język ANSI C – pliki 

Funkcja ftell

long int ftell(FILE *fp);

Zwraca pozycję wskaźnika pliku wskazywanego prze fp. Dla plików binarnych 

pozycja jest mierzona w bajtach od początku pliku.  Jeżeli powstał błąd, zwraca -1L i 

nadaje zmiennej globalnej errno wartość dodatnią.  errno jest ustawiana na jedną z 

dwóch wartości :

EBADF Niewłaściwy wskaźnik do pliku  

ESPIPE Niedopuszczalna operacja seek na urządzeniu

background image

Język ANSI C – pliki 

Funkcja fwrite

size_t  fwrite(void *buffer, size_t size, size_t count, FILE *fp );

Funkcja zapisuje do pliku wskazywanego przez fp, z miejsca pamięci 

wskazywanego przez buffer,  count bloków danych, każdy o rozmiarze size. Funkcja 
zwraca liczbę zapisanych bloków.

Przykład.  

int i=5;

FILE *fplik; 

fplik=fopen(”Plik4.dat”, ”w+b”);

fwrite(&i, sizeof(int),1,fplik);

fclose(fplik);

background image

Język ANSI C – pliki 

Funkcja fwrite

size_t  fread(void *buffer, size_t size, size_t count, FILE *fp );

Funkcja wczytuje z pliku wskazywanego przez fp, do miejsca pamięci 

wskazywanego przez buffer,  count bloków danych, każdy o rozmiarze size. Funkcja 

zwraca liczbę odczytanych  bloków.

Przykład.  

int i;

FILE *fplik; 

fplik=fopen(”Plik4.dat”, ”r+b”);

fread(&i, sizeof(int),1,fplik);

printf(”\n Element=%d”, i);

fclose(fplik);

background image

Język ANSI C – pliki 

Funkcja fseek

int fseek(FILE *file_pointer, long int offset, int whence );

Funkcja ustawia nową pozycję bieżącą pliku wskazywanego przez fp. Następna 

operacja plikowa rozpocznie się od tej pozycji. Nowa pozycja jest oddalona o offset 

bajtów od punktu odniesienia określonego przez trzeci parametr whence. Parametr ten 

może przyjmować następujące wartości:

SEEK_SET – przesunięcie jest realizowane względem początku pliku,

SEEK_CUR – przesunięcie jest realizowane względem bieżącej pozycji, 

SEEK_END – przesunięcie jest realizowane względem końca  pliku

Funkcja zwraca wartość różną od zera w przypadku wystąpienia błędu.     

background image

Język ANSI C – pliki 

Przykład. Zapis 5 liczb typu int i odczyt pliku.

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

{ int i, buf, tab[5]={ 1,-1,2,3,5};

FILE *fp;
fp=fopen("Pliktest1.dat","w+b");

for (i=0;i<5;i++)                         // Zapis 5 liczb do pliku

fwrite(&tab[i],sizeof(int),1,fp);

fclose(fp);   // zamiast zamykania i ponownego otwierania 

// można użyć  fseek(fp,0,0) lub rewind.

fp=fopen("Pliktest1.dat","r+b");

for (i=0;i<5;i++)                         // Odczyt 5 liczb z pliku

{  fread(&buf,sizeof(int),1,fp);

printf("\n Element pliku nr %d =%d",i,buf); }

fclose(fp); getch(); return 0; }

background image

Język ANSI C – pliki 

Przykład. Dany jest plik test1.dat liczb typu int, dopisać zadaną ilość liczb n=5 do pliku 
( na końcu pliku) i odczytać plik.

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

{ int i,  buf, ilosc_elementow_typu_int, n=5;

FILE *fp;

fp=fopen("Pliktest1.dat","r+b");
fseek(fp,0,SEEK_END);
for (i=0;i<n;i++)

{ printf("\n Podaj liczbe :");

scanf("%d",&buf):
fwrite(&buf,sizeof(int),1,fp); }     

// Wyznaczenie ilości elementów w pliku po dopisaniu        

ilosc_elementow_typu_int= ftell(fp)/sizeof(int);

background image

Język ANSI C – pliki 

Przykład. cd.

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

fread(&buf,sizeof(int),1,fp);
printf("\n Element pliku nr %d =%d",i,buf); 

}

fclose(fp); 
getch();
}

background image

Język ANSI C – pliki 

Przykład. Dany jest plik test2.dat liczb typu double, zsumować  liczby dodatnie w pliku, 
a następnie wyznaczyć wartość minimalną w pliku.

#include <stdio.h>
#include <conio.h>

int main()

{ int i,  ilosc_elementow_typu_double;

double buf, suma_d=0, amin; 

FILE *fp;

fp=fopen("Pliktest2.dat","r+b");
fseek(fp,0,SEEK_END);
ilosc_elementow_typu_double= ftell(fp)/sizeof(double);

// Wyznaczanie sumy liczb dodatnich 
for (i=0;i< ilosc_elementow_typu_double;i++)  

{ fread(&buf,sizeof(double),1,fp);

if (buf>0)  suma_d+=buf;

}

background image

Język ANSI C – pliki 

Przykład. cd.

fseek(fp, 0, SEEK_SET);

fread(&amin,sizeof(double),1,fp);

for (i=1;i< ilosc_elementow_typu_double;i++)

fread(&buf,sizeof(double),1,fp);
if (buf<amin) amin=buf;  

}

printf("\n Element minimalny =%f",amin); 
fclose(fp); 

getch();
}

background image

Język ANSI C – pliki 

Przykład. Dany jest plik test1.dat liczb typu int , zamienić miejscami element drugi i 
elementem czwartym.

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

{ int i, buf1,buf2, buf, ilosc_elementow_typu_int;

FILE *fp;

fp=fopen("Pliktest1.dat","r+b");
fseek(fp,0,SEEK_END);
ilosc_elementow_typu_int= ftell(fp)/sizeof(int);
if (ilosc_elementow_typu_int<4)

{ printf("\n Nie ma wystarczajacej liczby elementow");

getch();
fclose(fp);
exit(1);      }               

background image

Język ANSI C – pliki 

Przykład.  c.d.

fseek (fp,1*sizeof(int),SEEK_SET);
fread(&buf1,sizeof(int), 1,fp);

fseek (fp,3*sizeof(int),SEEK_SET);
fread(&buf2,sizeof(int), 1,fp);

fseek (fp,1*sizeof(int),SEEK_SET);
fwrite(&buf2,sizeof(int), 1,fp);

fseek (fp,3*sizeof(int),SEEK_SET);
fwrite(&buf1,sizeof(int), 1,fp);

fseek(fp,0,0);

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

{ fread(&buf,sizeof(int),1,fp);

printf("\n Element pliku nr %d =%d",i,buf); }

fclose(fp); getch(); }

background image

Język ANSI C – pliki 

Przykład.  W przykladzie  przedstawiono dwie  metody odczytu pliku.

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

int main(int argc, char **argv)

{  FILE *fp;

double x[8]={1.5,2,3.5,4.5,5.5,6.8,7.5,8}, buf;

int i,k,ilosc_bajtow_w_pliku,ilosc_elementow_typu_double_w_pliku;

fp=fopen("pliktest.dat","w+b");

if (fp)   { printf("\n Plik zostal utworzony");   getch();  }

else  { printf("\n Plik nie daje utworzyc"); getch(); exit(1);}

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

fwrite(&x[i],sizeof(double),1,fp);

fclose(fp);

background image

Język ANSI C – pliki 

fp=fopen("pliktest.dat","r+b");

// Metody odczytu pliku

// Metoda 1 - z użyciem wyznaczania liczby elementów pliku

fseek(fp,0,2);

ilosc_bajtow_w_pliku=ftell(fp);

ilosc_elementow_typu_double_w_pliku=\

ilosc_bajtow_w_pliku/sizeof(double);

printf("\n Metoda 1");

fseek(fp,0,0);

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

{

fread(&buf,sizeof(double),1,fp);

printf("\n Element %d = %lf",i,buf);

}

getch();

background image

Język ANSI C – pliki 

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

i=1;

// Metoda 2 - użycie sprawdzania wartości zwracanej przez  funkcję fread

clrscr();

fseek(fp,0,0);

printf("\n Metoda 3");

while (fread(&buf,sizeof(double),1,fp))

printf("\n Element %d = %lf",i++,buf);

getch();

fclose(fp);

return 0;

}

background image

Język ANSI C – pliki 

Przykład. Tworzenie kopii pliku, należy utworzyć kopię pliku pliktest.dat

o nazwie plikcopy.dat w bieżącym katalogu. 

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

int main(int argc, char **argv)

{  FILE *fp,*fp1;  char bufc;

double x[8]={1.5,2,3.5,4.5,5.5,6.8,7.5,8}, buf;

int i,k,ilosc_bajtow_w_pliku,ilosc_elementow_typu_double_w_pliku;

fp=fopen("pliktest.dat","w+b");

if (fp)   { printf("\n Plik zostal utworzony"); getch();  }

else  { printf("\n Plik nie daje utworzyc"); getch(); exit(1);}

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

fwrite(&x[i],sizeof(double),1,fp);

background image

Język ANSI C – pliki 

Przykład. c.d. (tworzenie kopii pliku)

fp1=fopen("plikcopy.dat","w+b");// utworzenie nowego pustego pliku

fseek(fp,0,0);

while ( fread(&bufc,sizeof(char),1,fp)) // kopiowanie bajt po bajcie

fwrite(&bufc,sizeof(char),1,fp1);

printf("\n Kopia pliku");

i=1;

fseek(fp1,0,0);

while (fread(&buf,sizeof(double),1,fp1))

printf("\n Element %d = %lf",i++,buf);

getch();

return 0;

}

background image

Język ANSI C – tablice znaków 

Tablice znaków (łańcuchy)

Tablice znaków stanowią specjalny rodzaj tablic o budowie ułatwiającej 

przetwarzanie tekstów. Przetwarzanie obejmuje szereg operacji takich jak tworzenie, 

modyfikacją i przeszukiwanie. 

Tablice znakowe mogą być definiowane w sposób następujący:

char s1[5];

char s2[5 ]=”ABCD”;

char s3[ ]=”abcd”;

Definicje tablic s2 i s3 zawierają też inicjalizację.

Tablice znaków  zakończone są znakiem ‘\0’. Znak ten umożliwia wykrycie końca 

tablicy, a tym samym umożliwia traktowanie tablic znaków w nieco inny sposób niż 

zwykłych tablic.  

background image

Język ANSI C – tablice znaków

Przykładowo, tablica s2 ma następującą budowę:        

'A'

'B'

'C'

'D'

'\0'

Tak więc definiując tablicę należy przewidzieć jedną komórkę na znak 
końcowy ‘\0’. 

Budowa tablicy znaków

background image

Język ANSI C – tablice znaków

Stałe łańcuchowe i wskaźniki do znaków cz. 1

Stałe łańcuchowe ( stałe typu tablica znaków), np. ”Tekst” , są przechowywane w 

pamięci jako tablice znaków z ostatnim elementem równym ‘\0’. 

”Tekst” jest typu char *, czyli wskaźnik do znaku. Wskaźnik do znaku może więc 

zostać zainicjowany stałą łańcuchową

char  *ps=”Tekst”;     // sposób 1                             

Inicjalizacja taka jest równoważna parze instrukcji

char *ps;    // sposób 2

ps=”Tekst”;

W przypadku   sposobu 1 do wskaźnika ps jest przypisywany wskaźnik do tablicy 

znaków, a nie do *ps ( czyli nie do miejsca wskazywanego przez ps).  

background image

Język ANSI C – tablice znaków

Stałe łańcuchowe i wskaźniki do znaków cz. 2

Warto też zauważyć, że przy definicji  tablicy znakowej

char s2[5];

nie jest możliwa realizacja przypisania w programie

s2=”ABCD” ;// przypisanie błędne

Wynika to z faktu, że s2 jako nazwa tablicy jest typu stały wskaźnik do znaku, który to 

wskaźnik nie może być zmieniony poprzez przypisanie.

background image

Język ANSI C – tablice znaków

Wczytywanie i drukowanie tablic znakowych cz.1 

W języku C istnieje specjalny deskryptor formatu %s umożliwiający wczytywanie i 

drukowanie tablic znakowych przy użyciu funkcji scanf i printf, istnieją też funkcje 

biblioteczne realizujące te operacje.

Jeśli zdefiniowano tablicę znakową

char s1[5];

można ją wczytać  i wydrukować w poniższy sposób:

printf(”\ Podaj lancuch :”);

scanf(”%s”,s1);       /// nie stosuje się znaku & przed s2, gdyż s2 jest  

//wskaźnikiem.

printf(”\n Wczytany lancuch to :%s ”, s1);

background image

Język ANSI C – tablice znaków

Wczytywanie i drukowanie tablic znakowych cz.1 

Jednak wczytywanie łańcuchów przy użyciu funkcji printf nie pozwala na wczytanie 

łańcuchów zawierających spacje, gdyż wczytywanie łańcucha jest przerywane po 

napotkaniu spacji. Dla takich łańcuchów należy zastosować funkcję gets lub też funkcję

fgets. Funkcja gets te ma następujący prototyp:

char *gets(char *s);

Opis działania funkcji gets:

Funkcja wczytuje   znaki ze standardowego wejścia ( stdin) aż do momentu 

napotkania znaku nowej linii (Enter). Wczytywane znaki są wyświetlane na ekranie i 

zapamiętywane począwszy od miejsca wskazywanego przez  s. Znak nowej linii jest 

zastępowany w łańcuchu znakiem końca łańcucha '\0'. Ciąg wejściowy może zawierać 

pewne białe znaki (np. spacje i znaki tabulacji poziomej).  Funkcja zwraca s, gdy 

operacja się powiodła, lub NULL w przypadku wystąpienia błędu.

background image

Język ANSI C – tablice znaków

Wczytywanie i drukowanie tablic znakowych cz.2 

Długość wczytywanego ciągu znaków nie jest ograniczana, co przy ciągach 

dłuższych niż to wynika z argumentu funkcji gets, może powstać uszkodzenie

sasiednich obszarów pamięci. 

Przykład.

char lan [20];

printf ("\n Podaj lancuch:");

gets(lan);

Bardziej uniwersalną funkcją służącą do wczytywania łańcuchów jest fgets.

background image

Język ANSI C – tablice znaków

Wczytywanie i drukowanie tablic znakowych cz.3

Funkcja fgets ma nastepujący prototyp:

char *fgets(char *s, int n, FILE *stream);

Funkcja ta czyta do łańcucha znaki ze strumienia wejściowego (pliku) określonego 

przez wskaźnik stream. Funkcja kończy wczytywanie znaków po przeczytaniu - 1 
znaków lub też po pojawieniu się znaku nowej linii.  Funkcja wpisuje znak nowej linii  do 
do łańcucha. Funkcja zwraca łańcuch lub NULL w przypadku pojawienia się końca pliku 
lub błedu. 

Przykład. Wczytywanie ze standardowego strumienia wejściowego

char lan [20];

printf ("\n Podaj lancuch:");

fgets(lan,15,stdin);

background image

Język ANSI C – tablice znaków

Wczytywanie drukowanie tablic znakowych cz.4

Do drukowania tablic znakowych można zastosować funkcje puts i fputs.

Prototyp funkcji puts ma postać

int puts(const char *s);

Funkcja wyprowadza łańcuch na wyjście standardowe (stdout) i dołącza znak nowej 
linii. W przypadku pomyślnej realizacji funkcja zwraca wartość nieujemną, w 
przeciwnym przypadku EOF.

int fputs(const char *s, FILE *stream);

Funkcja zapisuje łańcuch do do strumienia wyjściowego określonego przez 

wskaźnik stream. Funkcja nie zapisuje do pliku znaku '\0'.

W przypadku powodzenia operacji funkcja zwraca wartość nieujemną, w przypadku 
błędu wartość EOF.

background image

Język ANSI C – tablice znaków

Przykład. Zapis do pliku dwóch łańcuchów i odczyt.

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <string.h>

int main(int argc, char **argv) {

char s1[10]="ABCDE";

char s2[10]="abcde", s3[10], s4[10];

FILE *fp;

fp=fopen("Plik1.txt","w+");

fputs(s1,fp);

fputc('\n',fp);

fputs(s2,fp);

fputc('\n',fp);  // dopisanie znaku nowej linii, aby funkcja

// fgets czytała tylko pierwszy łańcuch z pliku

background image

Język ANSI C – tablice znaków

Przykład. c.d. Odczyt  pliku i wydruk.

fseek(fp,0,0);

fgets(s3,10,fp);

printf("%s",s3);

fgets(s4,10,fp);

printf("%s",s4);

getch();

fclose(fp);

return 0;

}

background image

Język ANSI C – tablice znaków

Standardowe funkcje łańcuchowe cz. 1

Poniżej omówione zostaną wybrane najczęściej spotykane funkcje związane z 

przetwarzaniem łańcuchów (pełny zestaw w <string.h> i <stdlib.h>.

Funkcje te to:

strlen, strcpy, strcat, strcmp, strlwr, strupr, atoi, itoa, strchr, strstr.

Funkcja strlen

size_t strlen(const char *s);

Funkcja oblicza długość łańcucha bez końcowego znaku '/0'. 

Przykład.

char s[20]="12345678";

int dl;

dl=strlen(s);//  dl będzie równe 8   

background image

Język ANSI C – tablice znaków

Standardowe funkcje łańcuchowe cz. 2

Funkcja strcpy

char *strcpy(char *dest, const char *src);

Kopiuje łańcuch src do łańcucha dest. Kopiowanie ulega zakończeniu po 

skopiowaniu znaku '\0' kończącego łańcuch src

Funkcja zwraca wskaźnik dest .

Przykład.

#include <stdio.h>

#include <string.h>

int main(void)  {

char lan1[10="ABC";

char lan2[ ]= "12345";

strcat(lan1, lan2);

printf("%s", lan1);

return 0;   }

background image

Język ANSI C – tablice znaków

Funkcja strcat

char *strcat(char *dest, const char *src);

Dołącza łańcuch src do końca łańcucha dest. Funkcja zwraca wskaźnik dest 

Długość połączonego łańcucha jest równa strlen(dest)+strlen(src).

Przykład.

#include <stdio.h>

#include <string.h>

int main(void)  {

char lan1[20]="abcde";

char lan2[ ]= "123456789";

strcat(lan1, lan2);

printf("%s", lan1);

return 0;   }

Standardowe funkcje łańcuchowe cz. 3

background image

Język ANSI C – tablice znaków

Standardowe funkcje łańcuchowe cz. 4

Funkcja strcmp

int strcmp(const char *s1, const char *s2);

Porównuje łańcuch s1 z łańcuchem s2, porównując kody znaków (np. kody  ASCII) 

obu łańcuchów.   Porównanie kończy się, gdy w jednym z łańcuchów zostanie 
napotkany znak o większym kodzie lub też zostanie osiągnięty koniec jednego z 
łańcuchów ( wtedy dłuższy łańcuch uważany jest za większy). 

Funkcja zwraca 

- wartość <0, gdy s1<s2,

-wartość    0, gdy s1==s2,

-wartość  >0, gdy s1>s2.

background image

Język ANSI C – tablice znaków

Standardowe funkcje łańcuchowe cz. 5

Przykład. Zastosowanie funkcji strcmp.

#include <stdio.h>

#include <string.h>

#include <conio.h>

int main(void)  {

char lan1[10]="abcde",lan2[10 ]; int p;

printf(" Podaj lancuch:");

scanf("%s", lan2);

p= strcmp(lan1,lan2);

if (p<0) printf(" lan1<lan2"); else   if ( p==0) printf("\n lan1=lan2");

else printf("\n lan1>lan2");

getch(); return 0;  }

background image

Język ANSI C – tablice znaków

Przykład. Wczytywanie dwuwymiarowej tablicy znaków (tablicy łańcuchów)
oraz sortowanie niemalejąco. (cz.1)
// cz. 1 programu
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main(int argc, char* argv[])
{   

char stab[5][10];
char spom[10];
int i,zam;

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

{

printf("\n lan%d :",i);
scanf("%s",stab[i]); // wczytywanie tablicy znaków będącej  wierszem 

}                                 // tablicy dwuwymiarowej

for(i=0;i<5;i++)    printf("\n lan %s",stab[i]);

background image

Język ANSI C – tablice znaków

Cz. 2 programu
do

zam=0;
for (i=0;i<4;i++)

if (strcmp(stab[i],stab[i+1])>0)

{  strcpy(spom, stab[i]);

strcpy(stab[i], stab[i+1]);
strcpy( stab[i+1],spom );
zam=1; 

}  

}

while (zam);

printf("\n\n Tablica po sortowaniu");
for(i=0;i<5;i++)

printf("\n lan %s",stab[i]);

getch();

return 0;}

background image

Język ANSI C - struktury

Język ANSI C - struktury

Struktury

Struktury ( zwane w innych językach programowania rekordami) stanowią typ 

służący do przetwarzania informacji powiązanych ze sobą. Definicja typu 
strukturowego ma następującą postać

struct nazwa_typu

{    typ_pola_1   nazwa_pola_1;

typ_pola_2  nazwa_pola_2;

.

.

typ_pola_n  nazwa_pola_n;

} ;

Tak więc definicja typu strukturowego składa się ze słowa kluczowego struct, po 
którym następuje nazwa danego typu strukturowego ( czasami określana jako 
etykieta), po czym po nawiasie otwierającym występują typy poszczególnych 
składowych struktury oraz ich nazwy. Składowe typu strukturowego zwane są polami 
struktury.

background image

Język ANSI C - struktury

Definicja typu strukturowego kończy się nawiasem zamykajacym.

W typie strukturowym mogą wystąpić pola,  które same mogą być typu strukturowego, 

mówimy wtedy o tzw. typie strukturowym zagnieżdżonym.   

Nazwy pól muszą być różne w ramach jednego typu strukturowego, jednak 

można stosować te same nazwy w ramach innych typów strukturowych.

Nazwa pola struktury może być taka sama jak nazwa danego typu 

strukturowego czy też zmiennej strukturowej. 

background image

Język ANSI C - struktury

Przykład. W ramach jednego typu danych chcemy przechowywać pewne informacje o 

pracownikach. Zdefiniujemy uproszczony typ strukturowy pozwalający na 

przechowywanie takich informacji ( w rzeczywistych sytuacjach może być konieczne 

stosowanie nawet kilkudziesięciu pól).

struct pracownik

{ char nazwisko [20];

char imie [20];

int wiek;

double dochod;

} rek1, rek2;

rek1, rek2 są  zmiennymi typu pracownik.  Zmienne strukturowe można też zdefiniować 

w sposób następujący:

struct pracownik rek3, rek4, rek5;

background image

Język ANSI C - struktury

Można też zdefiniować tablicę struktur

struct pracownik  pracownicy [20];

Zmienna pracownicy jest tablicą struktur składającą się z 20 struktur typu

pracownik.

Dla realizacji dostępu  do pól typu strukturowego,  w języku C wprowadzono 

specjalny operator dostępu do pól struktury – operator „.”( kropka). Operator ten jest 

stosowany w sposób następujący: jeśli mamy zmienną strukturową rek1 typu pracownik, 

to możemy wprowadzić wartość do jej pola dochod w sposób następujący:

rek1. dochod=1500;

W ogólnym przypadku, polami zmiennych strukturowych możemy posługiwać się jak 

zmiennymi takiego typu, jak typ danego pola struktury.

background image

Język ANSI C - struktury

Przykład. W ramach jednego typu danych chcemy przechowywać pewne informacje o 

pracownikach. Zdefiniujemy uproszczony typ strukturowy pozwalający na 

przechowywanie takich informacji ( w rzeczywistych sytuacjach może być konieczne 

stosowanie nawet kilkudziesięciu pól).

struct pracownik

{ char nazwisko [20];

char imie [20];

int wiek;

double dochod;

} rek1, rek2;

rek1, rek2 są  zmiennymi typu pracownik.  Zmienne strukturowe można też zdefiniować 

w sposób następujący:

struct pracownik rek3, rek4, rek5;

background image

Język ANSI C - struktury

Można też zdefiniować tablicę struktur

struct pracownik  pracownicy [20];

Zmienna pracownicy jest tablicą struktur składającą się z 20 struktur typu

pracownik.

Dla celów typem strukturowym,  w języku C wprowadzono specjalny operator 

dostępu do pól struktury – operator „.”( kropka). Operator ten jest stosowany w sposób 

następujący: jeśli mamy zmienną strukturową rek1 typu pracownik, to możemy 

wprowadzić wartość do jej pola dochod jak następuje:

rek1. dochod=1500;

W ogólnym przypadku polami zmiennych strukturowych możemy posługiwać się jak 

zmiennymi takiego typu, jak typ danego pola struktury.

background image

Język ANSI C - struktury

1. Pola typu numerycznego ( typy całkowite i typy rzeczywiste)

Jak zaznaczono powyżej, pola takie można stosować, jako zmienne danego typu

rek2. dochod=1000;

rek2. wiek=25;

pracownicy[0].dochod=1200;

pracownicy [0].wiek=24;

scanf(”%d”,&rek3.dochod);
scanf(”%d”,&rek3.wiek);

scanf (”%lf”, &pracownicy[1].dochod);
scanf (”%d”, &pracownicy[1].wiek);

Wprowadzanie/wyprowadzanie informacji z /do pól zmiennych strukturowych cz. 1

background image

Język ANSI C - struktury

2. Pola typu tablica znaków

strcpy (rek1.nazwisko, ” Kowalski”);

scanf(”%s”, rek2.nazwisko);

gets( rek3.nazwisko);

Wyprowadzanie informacji odbywa się podobnie jak dla innych zmiennych.

printf (”\n   %d ”, rek1.dochod);

printf(”\n    %s ”, rek1.nazwisko);

Wprowadzanie/wyprowadzanie informacji z /do pól zmiennych strukturowych cz. 2

background image

Język ANSI C - struktury

Inicjalizacja struktur

Zmienne typu strukturowego, podobnie jak tablice, mogą być inicjalizowane przy 
definicji.

Przykład. Inicjalizacja pól zmiennej typu student.

struct student 

{ char nazwisko[20];

char imie [20];

int rok studiow;

char wydzial[20];

};

struct student student1={ "Kowalski", "Marcin", 2, "EiA"};

struct student student2={ "Iksiński", "Andrzej", 3, "EiA"};

background image

Język ANSI C - struktury

Inicjalizacja tablic struktur

Przykład. Inicjalizacja tablicy struktur typu student

struct student 

{ char nazwisko[20];

char imie [20];

int rok studiow;

char wydzial[20];

};

struct student studenci[3]={ {”Kowalski”, ”Marcin”, 2, ”EiA”}, 

{ ”Iksiński”, ”Andrzej”, 2, ”EiA”}, 

{ ”Malinowski”, ”Dariusz”, 2, ”EiA”} }; 

background image

Przykład. Program rekordy1 wczytujący i drukujący pojedyncze struktury.
#include <condefs.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
// program rekordy1 wczytuje dane do struktur
// i następnie drukuje
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char **argv)
{  struct student

{   char nazwisko[20];

char imie [20];
int rok_studiow;

char wydzial[20];

};

Język ANSI C - struktury

background image

Język ANSI C – struktury

struct student student1, student2;

/* Bezpośrednie nadawanie wartości polom   struktur */

strcpy(student1.nazwisko,"Kowalski");

strcpy(student1.imie,"Jan");

student1.rok_studiow=2;

strcpy(student1.wydzial,"EiA");

background image

Język ANSI C – struktury

// Program rekordy1 cz. II

/* Do wczytywania pól struktury student 2   z klawiatury zastosowano trzy różne 
funkcje wczytywania   pól typu tablica znaków, by pokazać różne

sposoby wczytywania takich pól */

printf ("\n Podaj dane 2-go studenta ");

printf ("\n    Nazwisko: ");

scanf("%s",student2.nazwisko);

printf ("\n        Imie: ");

fflush(stdin);

fgets(student2.imie,15,stdin);

printf("\n Rok studiow :");

scanf("%d",&student2.rok_studiow);

printf ("\n     Wydział: ");

scanf("%s",student2.wydzial);

background image

Język ANSI C – struktury

// program rekordy1 cz. III  

/* Drukowanie  struktur student1 i student2*/

printf("\n\n Dane studenta 1 ");
printf("\n Nazwisko    :%s", student1.nazwisko);
printf("\n     Imie    :%s", student1.imie);
printf("\n Rok studiow :%d", student1.rok_studiow);
printf("\n Wydzial     :%s", student1.wydzial);

printf("\n\n\n Dane studenta 2 ");
printf("\n Nazwisko    :%s", student2.nazwisko);
printf("\n     Imie    :%s", student2.imie);
printf(" Rok studiow :%d", student2.rok_studiow);
printf("\n Wydzial     :%s", student2.wydzial);
getch();
return 0;} 

background image

Język ANSI C – struktury

Struktury zagnieżdżone

Struktury zagnieżdżone to takie struktury w których 

przynajmniej jedno  z pól jest typu strukturowego.

struct nazwa_typu

{    typ_pola_1   nazwa_pola_1;

struct nazwa_typu_strukturowego  nazwa_pola_2;

.

.

typ_pola_n  nazwa_pola_n;

} ;

background image

Język ANSI C – struktury

struct   data  

{

int dzien;
int miesiac;
int rok;

}

struct dane_studenta

{ char nazwisko[20];

char imie [20];

struct data data_ur ;

int rok studiow;

char wydzial[20];

};

struct dane_studenta dane_studenta1, dane_studenta2; 

background image

Język ANSI C – struktury 

Przykład . Program rekordy2 wczytuje dane do tablicy   struktur i następnie drukuje 

int main(int argc, char **argv)

{    struct data    {

int dzien;

int miesiac;

int rok;     };

struct dane_studenta

{  char nazwisko[20];

char imie [20];

struct data data_ur;

int rok_studiow;

char wydzial[20];   };

struct dane_studenta studenci[4];

background image

Język ANSI C – operatory 

// Program rekordy2 cz. II 

int i;

/* Bezpośrednie nadawanie wartości polom

tablicy struktur */

strcpy(studenci[0].nazwisko,"Kowalski");
strcpy(studenci[0].imie,"Jan");
studenci[0].rok_studiow=2;
studenci[0].data_ur.dzien=2;
studenci[0].data_ur.miesiac=5;
studenci[0].data_ur.rok=1980;
strcpy(studenci[0].wydzial,"EiA");

strcpy(studenci[1].nazwisko,"Nowak");
strcpy(studenci[1].imie,"Andrzej");
studenci[1].rok_studiow=2;
studenci[1].data_ur.dzien=2;
studenci[1].data_ur.miesiac=6;
studenci[1].data_ur.rok=1981;
strcpy(studenci[1].wydzial,"EiA");

background image

Język ANSI C – struktury

// program rekordy2 cz. III

for (i=2;i<4;i++)

{   printf ("\n Podaj dane studenta %i",i+1); 

printf ("\n    Nazwisko: ");    scanf("%s",studenci[i].nazwisko);   

fflush(stdin);

printf ("\n        Imie: ");         scanf("%s",studenci[i].imie);

fflush(stdin);

printf("\n Podaj date urodzenia ");     

printf("\n   dzien :");  scanf ("%d",&studenci[i].data_ur.dzien);

printf("\n miesiac :");   scanf ("%d",&studenci[i].data_ur.miesiac);

printf("\n     rok :");   scanf ("%d",&studenci[i].data_ur.rok);

printf("\n Rok studiow :");  scanf("%d",&studenci[i].rok_studiow);

printf ("\n     Wydział: ");  scanf("%s",studenci[i].wydzial);

fflush(stdin); }

background image

Język ANSI C – struktury

// Program rekordy2 cz. IV 

/* Drukowanie  tablicy struktur */

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

{

printf("\n\n Dane studenta %d ", i+1);

printf("\n Nazwisko    :%s", studenci[i].nazwisko);

printf("\n     Imie    :%s", studenci[i].imie);

printf(" data urodzenia :%d.%d.%d ", studenci[i].data_ur.dzien,\

studenci[i].data_ur.miesiac,studenci[i].data_ur.rok);

printf("\n Rok studiow :%d", studenci[i].rok_studiow);

printf("\n Wydzial     :%s", studenci[i].wydzial);

}

getch();

return 0;}

background image

Język ANSI C – struktury

Przykład. Zapis struktur do pliku i odczyt.

#include <condefs.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

struct student

{ char nazwisko[20];

char imie[20];  };

FILE *fp;

char s[20]="pliktest.dat";

background image

Język ANSI C – struktury

Przykład. c.d. Zapis i odczyt struktur

int main(int argc, char **argv)

{ char ch;  int i;

struct student tab[4]={ {"iksinski","jan"},{"ygrekowski","andrzej "},

{"wojcik","marcin"},{"kowalski","marek"}}; //inicjalizacja tablicy struktur

struct student tab1[4],st;

fp=fopen(s,"w+b");

fwrite(&tab,sizeof(student),4,fp);// zapis tablicy struktur do pliku,

// można zapisać 4 bloki pętla nie jest konieczna,

fseek(fp,0,SEEK_SET);

i=1;

while (fread(&st,sizeof(student),1,fp))

{ printf("\n Dane studenta %d",i++);

printf("\n Nazwisko:%s", st.nazwisko);

printf("\n Imie:%s", st.imie); }

getch(); return 0; } 

background image

Język ANSI C – struktury

background image
background image
background image
background image
background image