Documente Academic
Documente Profesional
Documente Cultură
double
else
enum
extern
float
int
long
register
return
short
struct
switch
typedef
union
unsigned
continue
for
signed
void
default
goto
sizeof
volatile
do
if
static
while
Cuvintele rezervate (sau cuvintele cheie) sunt utilizate n
construirea instruciunilor, declararea tipurilor de date sau drept
comenzi; n anumite situaii, pot fi redefinite (nlocuite cu alte
cuvinte).
Cuvintele rezervate se scriu cu litere mici.
1.3. Identificatori
Sunt nume date funciilor, variabilelor, constantelor, n vederea
utilizrii lor n programe.
Un identificator este o succesiune de litere i cifre, primul
caracter fiind obligatoriu o liter. Se pot utiliza literele mari i literele
mici din setul de caractere, precum i caracterul subliniere _
considerat liter.
Numrul de caractere din componena unui identificator nu este
limitat dar n mod implicit, numai primele 32 de caractere sunt luate n
consideraie. Aceasta nseamn c doi identificatori sunt diferii, numai
dac difer n primele 32 de caractere.
Standardul ANSI garanteaz 6 caractere / identificator.
Mediile de programare Turbo C i Turbo C++ permit
utilizatorului modificarea limitei de 32.
n limbajul C, literele mari difer de cele mici, aadar
identificatorii: aria_trg , Aria_trg , ARIA_TRG, difer ntre ei.
Se recomand ca identificatorii s fie nume sugestive pentru rolul
obiectelor pe care le definesc. De exemplu, funcia care calculeaz o
sum se va numi sum , cea care calculeaz factorialul, fact etc.
n mod tradiional, identificatorii de variabile se scriu cu litere
mici, constantele i macrodefiniiile cu litere mari etc.
Exemple:
Identificatori coreci
Identificatori incoreci
Observaii
$contor
$ - caracter interzis
contor_1, data_16
struct
cuvnt cheie
delta_ec_2, tabel_nume
tab nr.2
TipElementCurent
2abs, 5xx,
ncep cu o cifr
Observaii:
Cuvintele
cheie nu pot fi utilizate ca identificatori;
{
1.4. Comentarii
Sunt texte explicative plasate n textul programului, pentru a
facilita nelegerea lui i pentru a marca principalele aciuni.
Comentariile nu sunt luate n consideraie de ctre compilator i
ca urmare trebuie delimitate prin caractere speciale. Se delimiteaz
prin /* nceputul de comentariu i prin */ sfritul de comentariu.
Exemplu:
/* Acesta este un comentariu */
Dac se omite marcarea sfritului de comentariu, textul
programului (aflat dup comentariu) se consider ca fcnd parte din
acesta!
n limbajul C++ s-a mai introdus o convenie pentru a insera
comentarii i anume succesiunea :
//
marcheaz nceput de comentariu.
Comentariul delimitat prin // se termin pe acelai rnd pe care se
afl i nceputul lui, fr s mai fie necesar marcarea sfritului.
Observaii:
{ Comentariile pot fi introduse oriunde n programul surs;
{ Comentariile pot fi scrise pe una sau mai multe linii de text;
{ Nu este permis introducerea unui comentariu n interiorul altui
comentariu.
n general, se recomand introducerea de comentarii dup antetul
unei funcii, care s precizeze:
{ Aciunea sau aciunile realizate de funcie;
{ Tipul datelor de intrare i ieire;
{ Algoritmii realizai de funcie, dac sunt mai complicai;
{ Limite impuse datelor de intrare, dac este cazul.
void ff_1(void)
{
. . . .
}
Funcia ff_1 este fr tip, deci nu returneaz o valoare concret
i nu are parametri.
2.
void ff_2()
{
. . . .
}
Funcia ff_2 este fr tip i nu are parametri (variant de scriere).
3.
int ff_3()
{
. . . .
}
4.
Tipul structurat
{ tablou
{ ntreg
(int)
{ structur
{ real
(float )
{ uniune
{ adres
(pointer )
{ ir de caractere
{ enumerativ (enum )
16
16
long int
32
unsigned short
unsigned long
16
32
signed char
8
0 . . . 255 (fr semn)
unsigned char
Restriciile impuse de standardul ANSI sunt:
dim (short) m 16 bii ;
dim (int) m 16 bii ;
dim (long) m 32 bii ;
dim (short) [ dim (int) [ dim (long) ;
Observaie: declaraia short int este echivalent cu short iar
long int este echivalent cu long , fr s apar confuzii.
Constante de tip ntreg
Pot fi scrise n sistemul de numeraie zecimal (baza 10), octal
(baza 8) sau hexazecimal (baza 16).
O constant zecimal ntreag este un ir de cifre zecimale, cu
prima cifr diferit de zero. Constantele ntregi reprezentate pe 16 bii
sunt de tip int iar cele reprezentate pe 32 de bii sunt de tip long.
Dac dorim s reprezentm o constant ntreag pe 32 de bii,
dei ea se poate reprezenta pe 16 bii, constanta trebuie s aib sufixul
L sau l.
Constantele ntregi sunt, de regul, cu semn. Dac dorim s fie
fr semn, constanta se termin cu litera U sau u.
Constantele ntregi fr semn se utilizeaz pentru a economisi
memorie. Astfel, constantele de tip int din intervalul [32768, 64535] se
pstreaz n memorie pe 32 de bii, iar constantele de tip unsigned din
acelai interval se reprezint pe 16 bii.
Pentru a reprezenta constante ntregi de tip long, fr semn, se
utilizeaz sufixele echivalente: ul, lu, LU, UL.
O constant octal ntreag este o succesiune de cifre octale (0.
.7), prima cifr fiind un zero, nesemnificativ. Sufixele L, l, U, u, se pot
utiliza cu aceleai semnificaii ca la constantele zecimale.
O constant hexazecimal ntreag este o succesiune de cifre
hexazecimale (0. .9, A, B, C, D, E, F), sau (0. . 9, a, b, c, d, e, f)
primele dou caractere fiind 0x sau 0X. Sufixele L, l, U, u, se pot
utiliza cu aceleai semnificaii ca la constantele zecimale.
Exemple:
132
12345L
0400
04000L
0xabbf
constant
constant
constant
constant
constant
0X2ACFFBL
constant hexazecimal de tip long;
Indicarea tipului este util cnd se folosesc funcii de bibliotec
avnd argumente de tip long sau fr semn; tipul constantei trebuie s
fie compatibil cu tipul predefinit al argumentului.
Operaiile de citire i scriere a valorilor de tip ntreg, cu funciile
de bibliotec printf(. . .) i scanf(. . .), necesit specificatori de format
corespunztori.
Tipul
n zecimal
n octal
n hexazecimal
int
long
short
unsigned
%d
%ld
%hd
%du
%o
%lo
%ho
%ou
%x
%lx
%hx
%xu
-765,77
.255
69e4
0,255
690 000,0
.23E-2
0, 0023
222.7e2
3377.5678e-5
22270
0,033775678
Adresa
MEMORIE
Locaia par
Locaia impar
0000
11110000
10101010
Variabila
. . . .
0002
......
11010100
1 1 0 0 10 1 0
10101110
1 1 0 0 10 1 0
. . . .
. . . .
0026
00000000
10000000
x = 128
0028
00000000
11110000
y = 240
0030
0032
0034
00000000
00000000
00000000
00000000
00000000
00000000
0036
11110000
00111111
0038
1 1 0 0 10 1 0
1 1 0 0 10 1 0
z = 1.0
. . . .
Variabilele px, py, pz, sunt de tip pointer (adres); ele pot
furniza adresele variabilelor de tip corespunztor, dac sunt asociate
cu acestea prin atribuiri de forma:
px = &x; py = &y; pz = &z;
Din px = &x i din tabelul de mai sus, rezult px = 0026 ;
Analog, py = 0028, pz = 0030.
Observaii:
{ Variabilele de tip pointer se declar cu prefixul '*' : *p, *u, *v ;
{ Variabilele de tip pointer se asociaz cu adresa unui obiect prin
atribuiri de forma p = &var, unde var este o variabil declarat;
semnul '&' arat c se consider adresa lui var (care se transfer
n pointerul p);
{ O variabil de tip pointer trebuie declarat astfel:
<tip de baz> *<identificator> ;
unde tipul de baz reprezint tipul de date pentru care va memora
adrese.
Exemple:
float *a1, var_1; / /pointerul a1 va memora adrese pentru valori float
int *a2, var_2; // pointerul a2 va memora adrese pent ru valori int
a1 = &var_1
; // atribuire corect , var_1 este de tip float
a2 = &var_2
; // atribuire corect, var_2 este de tip int
a2 = &var_1
; // greit, pentru c a2 se asociaz cu variabile int
{ Operaia invers, de aflare a valorii din memorie, de la o anumit
adres, se realizeaz cu operatorul * pus n faa unui pointer:
int *p, x, y;
x = 128; p = &x;
// p = adresa lui x
y = *p;
// y = valoarea de la adresa p, deci y = 128
y = *&x; // y = valoarea de la adresa lui x, deci y = 128;
Aadar, operatorul * are efect invers fa de operatorul & i dac
se pun consecutiv, efectul este nul: x = *&x, sau p = &*p.
{ Un pointer poate fi fr tip , dac se declar cu void :
void *p ;
caz n care p poate fi asociat cu orice tip de variabile. Exemple:
int x;
float
y;
void *p;
. . . . . .
p = &x ; // atribuire corect, p este adresa lui x
p = &y ;
#include <stdio.h>
main ( )
{
int x = 77 ;
printf("Valoarea lui x este: %d \n", x);
printf("Adresa lui x este: %p \n", &x);
}
Funcia printf() utilizeaz specificatorul de format %p, pentru
scrierea datelor de tip adres.
2)
#include <stdio.h>
main ( ) // afisarea unei adrese si a valorii din memorie
{
char *adr_car, car_1='A' ;
adr_car = car_1; // pointerul ia valoarea adresei lui car_1
printf("Valoarea adresei: %p \n", adr_car);
printf("Continutul de la adr_car %c \n", *adr_car);
}
3)
#include <stdio.h>
main ( ) // perechi de instruct iuni cu acelasi efect
int x=177, y, *p ;
y = x + 111;
// y = 177+111=288
p = &x; y = *p + 111; // y = 177+111=28 8, acelasi efect
x = y ;
// x = 288
p = &x; *p = y ; // x = 288, adic valoarea lui y
x++ ;
// x = x+1, deci x = 299
p = &x ; (*p)++ ; // x = 299+1=300 }
Categorie
1
Selectori
Operatori
( )
[ ]
->
.
!
~
+
++
Op. unari
-&
*
sizeof
(tip)
3
Op. aritm._1
Op. aritm._2
Deplasri
<< >>
Relaionali
Egalitate
==
!=
Semnificaie
Asociere
stnga dreapta
Negare logic
Negare bit cu bit
Plus, minus (semne aritmetice)
Incrementare/ Decrementare
Luarea adresei
Indirectare
Dimensiune operand (n octei)
Conversie explicit de tip
dreapta stnga
st - dreapta
Adunare, scdere
st - dreapta
st - dreapta
st - dreapta
st - dreapta
8
9
10
Operatori
logici
11
Op. condiional
14
Op. de
atribuire
15
st - dreapta
st - dreapta
st - dreapta
st - dreapta
st - dreapta
dreapta-st.
&&
||
12
13
&
Virgula
=
*= /= %= += -=
&=
^=
|=
<<= >>=
,
Atribuire simpl
dreapta Atribuire produs, ct, rest, sum, dif. stnga
Atribuire i, sau excl., sau bit cu bit
Atribuire i deplasare stg., dreapta
Evalueaz op1, op2. Valoarea expr. st - dreapta
este op2.
apar doi operatori: cel de indirectare (derefereniere) i cel de post incrementare; se pune ntrebarea: ce se incrementeaz, p sau *p ?,
adic ce operator acioneaz primul ?. Din tabel, se vede c att ++
ct i * au acelai nivel de prioritate, dar ordinea de asociere este
dreapta-stnga, aadar, ++ i apoi *. Se incrementeaz aadar p nu *p.
Dac dorim s incrementm *p, trebuie scris:
x=(*p )++;
se scrie
if (x=2) . . .
echival en t
echival en t
echival en t
echival en t
cu
cu
cu
cu
x
y
u
a
+=
*=
/=
%=
3;
6.5;
v-2;
b;
unde (expr) este evaluat logic; dac este adevrat (diferit de 0), se
evalueaz expr_1 care devine valoare final pentru expresia
condiional; dac (expr) este fals (egal cu 0), atunci este evaluat
expr_2, care devine valoare final. Se garanteaz c una i numai una
dintre expr_1 i expr_2 este evaluat.
Exemplu: tiprirea unui vector numeric, cu un anumit numr de
elemente pe linie (de exemplu, 10), separate prin blank:
for(i =0 ; i<n; i++)
print f("% 6d %c ", a[ i] ,( i% 10 == 9 || i==n-1 ) ? '\n': '
');
observnd prezena caracterului special '\0' (octetul nul, care are rol de
terminator de ir).
Transmiterea tablourilor cu o dimensiune la funcii se face prin
declararea parametrului formal al funciei ca fiind tablou, ceea ce se
realizeaz punnd paranteze drepte. Nu este necesar prezena
explicit a dimensiunii tabloului ntre paranteze, deoarece ceea ce se
transmite efectiv este adresa de nceput a tabloului.
Dac totui, este necesar dimensiunea tabloului, aceasta se
poate preciza ntr-un parametru separat. n exemplul de mai jos, este
prezentat o funcie care calculeaz produsul scalar a doi vectori de
lungime n, reprezentai prin dou tablouri de numere reale:
float prod_s ca la r( floa t x[], float y[], int n)
{
float prod=0.0 ;
int i;
for (i=0; i<n; i++)
prod +=x[i ]* y[i] ;
retur n prod;
}
x[0][ 1]
x[0][ 2]
x[1][ 0]
x[1][ 1]
x[1][ 2]
2.3.2. Structuri
n multe aplicaii, este necesar gruparea datelor sub forma unei
mulimi de elemente care s poat fi prelucrate att element cu element
ct i global, ca mulime. Dac toate elementele sunt de acelai tip,
mulimea de elemente poate fi definit ca tablou; dac elementele sunt
diferite ca tip, atunci mulimea lor se definete ca structur .
Structura este o colecie de date de tipuri diferite, grupate sub
acelai nume. Un exemplu simplu de structur este data calendaristic;
ea conine 3 componente: zi (1, 2, . . . , 31) - de tip ntreg, luna - de
tip ir de caractere i anul - de tip ntreg.
Pentru a utiliza structuri n programe, acestea trebuie definite.
Sintaxa definirii unei structuri este:
struc t <nume >{
declara ti i de varia bi le ;
}
unde <n ume> este un identificator de tip de date definite de utilizator,
str uc t este cuvnt cheie iar declaraiile de variabile sunt cele
obinuite.
Dup o asemenea definiie, se pot declara variabile sau funcii de
tipul <nume> . Exemple:
struc t compl ex {f lo at re; float im};
struc t stude nt {c ha r nume[2 5] ;i nt gr;fl oa t
medie _a n} ;
sau, dac structura conine date mai complexe (tablouri, alte structuri),
se pot folosi mai multe niveluri de acolade:
struc t tty {int a[10]; int b[3]; char *s};
struc t tty
x =
{
Exemple:
COMPL EX z, zeta;
struc t stude nt sx;
z.re= 2.0;
z.im= 7.2;
zeta= z;// ec hi va le nt cu zeta.r e= z.re ; zeta.i m= z.im ;
sx.nu me=" Ni cu le sc u D. R. Liviu" ;
sx.gr = 8315;
sx.me die_ an = 8.99;
typed ef struc t
{ char
char
long
{ char
*oras ;
*stra da ;
cod; } ADRES A;
*nume; ADRESA adr;}
typed ef struc t
PERSO AN A;
PERSO ANA zz;
zz.nu me=" Gh eo rg he Hagi";
zz.ad r.or as =" Co ns ta nt a" ;
zz.ad r.st ra da =" B- du l Tomis 44";
zz.ad r.co d= 55 67 ;
z, *pz;
3 Instruciuni
Instruciuni simple
Instruciuni structurate
{ de atribuire
{ instr. compus
{ { . . . }
{ break
{ alternative
{ if
{ continue
{ goto
{ switch
{ repetitive
{ return
{ while
{ do while
{ for
3.2. Instruciunea if
Corespunde structurii alternative cu dou ramuri, sau unui bloc
de decizie cu dou ieiri. Sintaxa instruciunii if este:
if (expresie)
instructiune_1 ;
[else
instructiune_2 ; ]
Ramura else, inclus ntre [ ], este opional; instructiune_1 i
instructiune_2 pot fi oricare instruciuni ale limbajului, simple sau
structurate, inclusiv if. Dac este necesar, una sau ambele pot fi
nlocuite cu instruciuni compuse.
Efectul :
se
evalueaz expresia (se calculeaz valoarea expresiei) ;
{
{ dac este adevrat (valoare diferit de zero), se execut numai
instructiune_1 (instructiune_2 nu este luat n consideraie);
{ dac este fals (valoare = 0), se execut numai instruciune_2;
dac aceasta lipsete, se trece la instruciunea urmtoare din
program.
Observaii:
{ n C, valoarea logic "adevrat" este asociat cu " ! 0" iar
valoarea logic "fals" este asociat cu "= 0".
Valoarea expresiei poate fi de tip ntreg:
if (k) x=k+3 ; // pentru k<>0, se executa x=k+3
if (k=5) x=k+3 ; // se executa totdeauna x=k+3, pentru ca expr.=5
if (k==5) x=k+5 ; // se executa x=k+3, numai pentru k=5
{ Dac una sau ambele instruciuni din if, sunt tot instruciuni if,
else se asociaz cu cea mai apropiat instruciune if anterioar,
din acelai bloc, care nu are ramur else . Exemplu:
if (y==1)
if (a==2)
x=0;
else x=2;
Ramura else aparine lui if (a==2), cea mai apropiat
instruciune if anterioar, care nu are ramur else. Dac se dorete alt
apartene, se pote utiliza o instruciune compus:
if (y==1)
{
if (a==2)
x=0;
}
else x=2; // else apartine lui if (y==1)
3x 2+1 1
1. Se consider funcia f : R d R, f(x ) = x2+1 , x ! 0 .
3/2 , x = 0
S se afieze valoarea funciei, pentru o valoare a lui x introdus
de la tastatur.
#include <stdio.h>
#include <math.h>
int main(void) {
double x, f ;
printf("Introduceti valoarea lui x: ");
scanf("% lf ", &x); //t otdeauna, argumentul lui scanf este adresa:
&x
if (x !=0)
f=(sqrt(3*x*x+1)-1)/(x*x+1);
// instr_1
else
f=3.0/2.0 ;
// instr_2
printf("Valoarea functiei este: %lf \n", f);
return 0;
}
2. Se consider trei valori ntregi; s se determine cea mai mare.
Se utilizeaz instruciunea if pe mai multe niveluri.
a>b
b>c
return c
a>c
return b
return c
return a
if (a>b)
if (a>c) return a ; // intoarce ca rezultat valoarea a
else
return c ;
else
if (b>c) return b ;
else
return c ;
}
Funcia calcul(), de mai sus, se apeleaz cu trei argumente: op1,
op2 i un operator (+, -, *, /); ea returneaz rezultatul operaiei, n
funcie de operatorul de tip caracter, care a fost specificat n lista de
argumente.
Funcia exit(1) produce terminarea execuiei programului; dac
valoarea specificat ca parametru este zero, arat terminare normal,
n caz contrar definete o terminare anormal, deci prezena unei erori.
n cazul de mai sus, se produce o terminare forat, din cauza unei
erori de operator. Funcia calcul(), n mod normal, returneaz o
valoare real de tip double. Din cauza operatorului necunoscut, funcia
nu poate returna o valoare normal, fapt ce necesit terminarea forat
a programului, altfel eroarea va genera un lan de alte erori, foarte greu
de depistat.
Funcia exit() este o funcie de bibliotec.
Pentru utilizarea n programe trebuie specificate fiierele header
<stdlib.h> sau < process.h> .
{
int x=1;
while (x<=10) {
printf("x = %d \t p(x) = %d \n",x, x*x - 3*x +2);
x++ ;
}
}
Exemplul 2: Tabelarea valorilor funciei sinus(). Funcia sinus
este o funcie standard, se afl n fiierul math.h i are prototipul
double sin(double x);
Argumentul x este interpretat n radiani; pentru a utiliza n
program valori ale lui x n grade, acestea trebuie nmulite cu factorul
f=PI/180.
# include <stdio.h>
# include <math.h>
# define PI 3.14159 2653 5897 9
main()
{
int x=0 ;
double f=PI/180. 0 ;
while (x<=360) {
printf( "sin (%d) = %.16f\n",x ,sin (x*f ));
x++ ;
}
}
Valorile se afieaz cte una pe linie, deci programul afieaz
360 de linii. Pe ecran pot fi analizate doar ultimele 25 de linii. n
asemenea situaii se pune problema de a ntrerupe temporar execuia
programului, dup ce s-au afiat 25 de linii. Oprirea programului se
poate face n mai multe moduri; un mod simplu de oprire este apelarea
funciei getch() n momentul n care ecranul este plin. Apelarea funciei
getch() oprete execuia, deoarece se ateapt acionarea unei taste i
se afieaz fereastra utilizator. La acionarea unei taste, programul
intr din nou n execuie.
n exemplul urmtor se apeleaz funcia getch() dup afiarea a
23 de valori (linii); pe linia 24 se va afia textul:
Daca doriti sa continua ti, apasati o tasta!
Se utilizeaz valorile lui x =0, 1, . . . , 360, pentru a apela getch,
cnd x ia valorile 23, 46, 69, . . . , deci multiplu de 23. Aceasta se
exprim prin expresia x % 23 ==0.
# include <stdio.h>
# include <math.h>
# define PI 3.14159 2653 5897 9
main()
{
int x=0 ;
double f=PI/180. 0 ;
while (x<=360) {
printf( "sin (%d) = %.16f\n",x ,sin (x*f ));
x++ ;
if(x % 23==0){
printf( "Dac a doriti sa continua ti,
apasati o tasta! \n");
getch() ;
}
}
}
do
instructiune
while (expresie) ;
Efectul instruciunii do - while :
1. Se execut "instruciune";
2. Se evalueaz expresia;
3. Dac are valoarea "adevrat" (diferit de zero), se reia pasul 1.
4. Dac are valoarea "fals" (zero), execuia instruciunii do-while
se ncheie i se trece la instruciunea urmtoare din program.
Pe poziia "instruciune" este acceptat o singur instruciune C;
dac sunt necesare mai multe, acestea se includ ntre paranteze acolade
i formeaz astfel o singur instruciune, compus.
Observaii:
{
{
{
{
car = getch();
if (car == ' ') nr_sp++;
}
while (car != PUNCT);
printf("S-au gasit %d spatii albe \n", nr_sp);
return 0 ;
}
Programul de mai sus contorizeaz numrul de spaii albe dintr-o
fraz, introdus de la tastatur. La citirea caracterului punct ".", ciclul
do-while se ncheie i se afieaz numrul de spaii.
Analog, se poate contoriza tastarea unui caracter oarecare, prin
modificarea condiiei din instruciunea if(car == ' ') nr_sp++;
exemplu:
if (car == 'd') nr_sp++ ;
Exemplul urmtor este un program care calculeaz rdcina
ptrat dintr-un numr real pozitiv, prin metoda iterativ, a lui
Newton. Se utilizeaz irul (x n ) ncN , definit prin recuren:
x 2n +a
x n+1 = 2$x
, x 0 = 1.
n
Acest ir este convergent i are limita L = a .
Termenii irului se calculeaz succesiv: x 0 , x 1 , , x N , pn cnd
diferena dintre doi termeni consecutivi este mai mic dact o valoare
impus, de exemplu, = 10 10 :
x N x N1 [
Valorea lui x N este limita irului i deci x N = a .
#include <stdio.h>
#include <stdlib.h>
#define EPS 1e-10
//se calculeaza radical din a = numar real pozitiv
main( )
{
double a, x1, x2, y ;
printf("Introduceti valoarea lui a>0, a= ");
scanf(" %lf ", &a);
x2=1;
do {
x1=x2;
x2=0.5*(x1+a/x1);
if ((y=x1-x2)<0) y=-y ; // valoarea absoluta a lui y
}
while (y>EPS);
printf("a=% .11g \t radical(a)=% .11g\n", a, x2);
}
n program, x1 i x2 sunt dou valori consecutive ale termenilor
irului. Ele sunt necesare pentru estimarea erorii i oprirea procesului
de calcul, cnd eroarea este mai mic sau egal cu EPS.
Variabila y este utilizat pentru diferena a doi termeni
consecutivi, valoarea absolut a acesteia i compararea cu EPS.
Specificatorul .11g arat c valoarea se tiprete pe minim 11
spaii dup virgul, n formatul cel mai economic (normal sau cu
exponent).
Numrul de iteraii (de repetri ale buclei do-while) nu este
anterior cunoscut; el depinde de valorea EPS impus: cu ct aceast
valoare este mai mic, volumul de calcul (numrul de repetri) crete.
Pentru aflarea numrului de repetri, se poate introduce un contor,
iniializat cu zero, care este incrementat la fiecare trecere. n final,
valoarea contorului arat numrul de treceri prin do-while.
(k+1)(1 k+2)
k=0
specificat de argument.
continue;
Permite revenirea la nceputul blocului care se execut repetat,
nainte de ncheierea sa. La apariia instruciunii continue, se renun
la executarea instruciunilor urmtoare i se execut un salt la
nceputul blocului.
Prezena instruciunii mrete flexibilitatea programelor i
contribuie la rezolvarea mai simpl a unor ramificaii.
Nu se utilizeaz n cazul instruciunii switch.
4 Funcii
4.1. Definirea i apelul funciilor
Funciile sunt elementele constructive ale limbajului C i sunt de
dou categorii:
{ funcii standard (de bibliotec) definite n fiiere *.h: pr in tf () ,
sc an f( ), s in () , st rlen () , ge tc ha r( ), p ut char () , . . . ;
acestea pot fi utilizate n programe, prin specificarea fiierului
header n care se afl.
{ funcii definite de utilizator, altele dect cele standard.
n programul surs, o funcie definit de utilizator, are dou
pri: antetul i corpul funciei. O funcie poate avea un numr de
parametri (variabile) dar o singur valoare - valoarea funciei. Antetul
. . .
coincide cu tipul func ie i
. . .
"a" este conver ti ta la int
. . .
"c" este conver ti ta la int
. . .
printf ("%d\n", n) ;
Acelai lucru este valabil i la expresii n care intervin apeluri de
funcii. De exemplu, n secvena urmtoare nu se garanteaz care
funcie va fi apelat prima:
y = f( ) - g( ) ;
Dac f() este apelat prima, i calculul valorii lui f() are efecte
asupra lui g() nu se obine acelai rezultat ca n cazul apelrii mai nti
a lui g(). Dac ordinea este important, aceasta se poate impune prin:
y = -g( ) ; y = y + f( );
Exemplul 1 - (varianta 1, corect)
Programul ilustreaz necesitatea folosirii prototipului. Se
calculeaz valoarea maxim dintr-un tablou de pn la 20 de numere
reale, introduse de utilizator.
#incl ude <stdio .h >
#incl ude <conio .h >
#defi ne MAX 20
d ou ble
ma x( do ub le
*t ab ,
i nt
n) ;/ /p roto ti pu l
funct ie i
void main()
{
doubl e x[MAX] ;
int i;
print f("\ n Tastat i numere le ,t er mina ti cu 0:\n") ;
for(i =0; i<MAX; i++)
{
scanf (" %l f",& x[ i] );
if(x[ i] == .0) break;
} // la iesir e din for, i=nr. el em en te intro du se
print f("\ n Maximu l este %lf ", max(x ,i )) ;
getch ();
}
doubl e max(do ub le *tab, in t n)
/* functia max (),de tip double ; parame tr ii sunt:
adres a tablo ul ui si numaru l de eleme nt e */
{
int i; doubl e vmax= *t ab ;
for(i =1;i <n ;i ++ )
if(vm ax <* (tab +i ))
vmax= *( ta b+ i);
retur n vmax;
}
void main()
{
doubl e x[MAX] ;
int i;
print f("\ n Introd . numere le ,t er mina ti cu 0:\n") ;
for(i =0;i <M AX ;i ++ )
{
scanf (" %l f",& x[ i] );
if(x[ i] == .0) break;
} // la iesir e din for, i = nr.ele me nte
print f("\ n Maximu l este %lf ", max(x ,i )) ;
/ * f unct ia m ax e c onsi de ra ta d e ti p in t d eo ar ece nu
exist a proto ti p */
getch ();
}
doubl e max(do ub le *tab, in t n)
/* functia max (),de tip double ; parame tr ii sunt:
adres a tablo ul ui si numaru l de eleme nt e */
{
int i; doubl e vmax= *t ab ;
for(i =1;i <n ;i ++ )
if(vm ax <* (tab +i ))
vmax= *( ta b+ i);
retur n vmax;
}
Exemplul 2:
Programul surs este alctuit din dou fiiere, grupate ntr-un
proiect. Se calculeaz puterea ntreag a unui numr real.
// princ.c
#incl ude <stdio .h >
#incl ude <conio .h >
doubl e power( do ub le, int);
// protot ip funct ie
void main()
{
int i; double x;
print f( "\ n Numaru l real: ");
scanf (" %l f",& x) ;
print f( " Putere a intreaga : ");
scanf (" %d ",&i );
p ri nt f( "\n Re zu lt at ul e st e %l f\ n", p ow er (x ,i)) ;
getch () ;
}
// func.c
#incl ude <math. h>
doubl e power( do ub le a, int b)
{
int i, n; double p=1.; n=abs (b );
for(i =1 ; i<=n; i++)
p*=a;
if(b< 0) retur n (1/p);
else retur n( p) ;
}
Sunt mai multe puncte de ieire diferite, din funcia n_int dar
toate cu acelai tip de date de ieire.
Exemplul 3 - (varianta 2, corect)
% d" ,
TEM
in
ctype.h
string.h
math.h
stdlib.h
stdarg.h
time.h
limits.h
float.h
conio.h
R1
R2
R3
xf
Rn-1
Rn
SFF
variabil de acces
unde:
{ nume_fisier este un ir de caractere - numele fiierului, care
depinde ca form de sistemul de operare; de exemplu, la MS-DOS
se scrie
"c:\\us er\\ list a.tx t"
este
un
ir de caractere care descrie modul de acces:
{ mod
"r"
"w"
"a"
"r+"
"w+"
"a+"
Variabilele
blocul n care au
Tabloul a[]
programului.
Variabila k
k=2
k=3
i=2
k=4
Numele i prenumele
Nr.
leg.
Media
gen.
1/P
7.5
9.5
8.67
8.54
1/A
9.5
9.37
9.28
Moraru V. Vasile
5/M
8.5
9.5
9.89
9.22
6/M
7.5
10
9.56
8.95
. . . . .
. . .
. . .
. . .
. . .
. . . .
Zon de memorie
Parametrii de acces
sfrit
curent
Tablou de pointeri
P1 (adres)
Element 1
Element 2
P2
Element 3
P3
Element 4
P4
Pn-1
Element n-1
Pn
Element n
Figura 1
Parametrii
listei
lungime
nceput
curent
...
sfrit
...
NIL
NIL
NIL
informaie
util
inf.
Element 1
inf.
...
inf.
...
inf.
...
...
Fig. 2
Parametrii
listei
lungime
nceput
NIL
curent
...
...
sfrit
...
...
NIL
NIL
NIL
informaie
util
inf.
Element 1
inf.
...
inf.
...
inf.
...
...
Fig. 3
Totui, aceast variant nu este prea des folosit. Cnd sunt necesare
parcurgeri n ambele sensuri, se folosesc liste dublu nlnuite.
Pentru semnalarea situaiilor de eroare se va folosi urmtoarea
funcie, care tiprete irul primit i apoi foreaz oprirea programului:
void err_e xi t( co ns t char *s)
{
fprin tf (s tder r, "\n %s \n", s);
exit( 1) ;
}
new_el (D AT A x, LINK p)
LINK t = (LINK) malloc (siz eo f( EL EM EN T));
if (t==N ULL)
err_e xi t( "n ew_e l: Eroare de alocar e ");
t->da ta = x;
t->ne xt = p;
retur n t;
{
p->ne xt = new_e l( *t ab ++ , NULL);
p = p->nex t;
}
retur n t ;
}
realizeaz
operaiile dorite asupra datelor din fiecare element; funcia depinde de
tipul concret al datelor i deci este dependent de aplicaie.
p
q
Fig.4 Inserare element
p
Fig.5 tergere element
Dac p este NULL (nu exist element) sau p->next este NULL
(adic nu exist urmtorul element), nu avem nimic de fcut. Dac
elementul adresat cu p exist i nu este ultimul, se salveaz adresa de
legtur n p->next i apoi se elibereaz memoria ocupat de elementul
care se terge, adresat temporar cu q (fig.5).
6.5.3. tergerea tuturor elementelor unei liste
void del_l is t( LI NK t)
{
LINK p;
while (t != NULL ) {
p=t;
t=t-> ne xt ;
free( p) ;
}
}
7 Structuri de date:
ARBORI
SF1
sft.1
O1
SF2
sft2
O2
O3
sft3
O4
O5
sft4
O6
O7
O8
Figura 1.
rdcina
d
h
e
i
g
m
subarbore drept
subarbore stng
intrare
nod examinat
g
ieire
a
b
c
d
e
f
g
h
i
j
k
coada
b c d
c d
d e f
e f g
f g h i
g h i j
h i j k
i j k
j k
k
---------
intrare
Rdcin
ieire
informaie
ataat
h
Subarbore stng
Subarbore drept
Fig. 5
de parcurgere
g n o ;
n g o ;
g c a ;
care returneaz o valoare negativ dac a< b , zero dac a=b sau o
valoare pozitiv, dac a>b .
Funcia de cutare, n variant recursiv, se poate scrie astfel:
BTREE cauta (BTREE t, DATA x)
{
int y;
if(t= =NUL L || (y=cm p( x, t-.d) )= =0)
retur n t;
t=(y< 0) ? t->le ft : t->rig ht ;
retur n cauta( t, x) ;
}
Funcia ca uta( ) primete un pointer t la rdcina arborelui i o
valoare x i returneaz pointerul la nodul gsit (care conine x ) sau
NULL dac valoarea x nu exist n arborele t .
8 Tehnici de sortare
8.1. Introducere, definiii
Prin sortare se nelege ordonarea unei mulimi de obiecte de
acelai tip, pe baza unei componente de tip numeric, ce caracterizeaz
fiecare obiect.
arat
c,
cazul
datelor