ANSI C

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ć:

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

minus (-) i argumentu ( zmiennej a )

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

dwóch argumentów (zmienne a i 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 && i
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 i 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 a

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ż x równa się 1), więc znowu dodawane

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

teraz fałszywe (bo x 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 i

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 i

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:

wyr1, wyr2,…,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

i 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 i 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 i 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 f może występować wewnątrz funkcji g , która

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

2. Deklaracja funkcji f wewnątrz funkcji g 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 f .

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 i wskaźnikowi px;

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

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

py=px;

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

printf(”\n i=%d”, *py); // drukowanie i 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 t 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 a 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ę b [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 i

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 n 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 n najmłodszych bitów ze słowa 8-bitowego

( maska ta ma 1 na n 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 n pozycji , powoduje, że na

najmłodszych n pozycjach pojawiają się zera,

- ~( ~0<<n) – po zanegowaniu na najmłodszych n 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 n 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 n 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 s znaki ze strumienia wejściowego (pliku) określonego

przez wskaźnik stream. Funkcja kończy wczytywanie znaków po przeczytaniu n - 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 s 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 s 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

Wyszukiwarka

Podobne podstrony:
ansi (2)
Jezyk ANSI C B W Kernighan D M Ritchie
ANSI C 14
Jezyk ANSI C Programowanie Wydanie II jansic
C Wyklady Biblioteki ANSI C
Dodatek E Standardowa biblioteka ANSI C
Jezyk ANSI C
ANSI C Linux Lab NotacjaPolska
ANSI C, Edukacja, C C++
ANSI C 14
ANSI ISO C++ Professional Programmer's Handbook FDRB5YOUKKKT5ZOHUIEY3BGDGFDRSREUCXGIOOI
C Wyklady Biblioteki ANSI C cz2
Język ANSI C B W Kernighan D M Ritchie
Cabling Standard ANSI TIA EIA 568 B id 107593
ANSI C wikibooks
Jezyk ANSI C Programowanie cwiczenia Wydanie II cwjans

więcej podobnych podstron