Sunteți pe pagina 1din 230

LIMBAJUL C TEORIE ŞI APLICAŢI I 9

1 Algoritmi
1.1 Introducere
În scurta istorie, de aproximativ 50 de ani, a calculatoarelor electronice, o dată
cu suportul hardware, au evoluat spectaculos şi limbajele de programare, numărul
şi diversitatea lor fiind astăzi foarte mare.
Recomandările cu caracter general, standardizările limbajelor de programare s-
au impus abia la mijlocul deceniului opt, adică după aproape 30 de ani de
existenţă a calculatoarelor electronice. In aceste condiţii, criteriile de calificare a
programelor s-au diversificat, pe lângă cerinţele de funcţionare corectă şi de
performanţă (viteză de execuţie, capacitate), apărând cele legate de uşurinţa de
utilizare, respectiv uşurinţa cu care programul va putea fi modificat de alţii.
Aceste cerinţe de calitate au impus respectarea unor canoane (reguli) de
elaborare, care formează în ansamblu tehnologia programării.
Programarea structurată îşi propune să elaboreze produse software în care să
se distingă clar structurile principale ale programului (similar structurilor de
rezistenţă a clădirilor), structuri care vor fi proiectate, programate şi testate înainte
de abordarea oricărei probleme de detaliu.
Stilul acesta de abordare a problemelor, începând cu ansamblul şi coborând
treptat la detalii (top-down), caracterizează fiecare etapă de lucru pe parcursul
elaborării unui program structurat. Williams S. sintetizează [1] principalele
recomandări de programare structurală.
Vom prezenta în continuare principalele mijloace care se vor folosi pe parcursul
elaborării programelor în limbajul C.

1.2. Algoritmi şi organigrame


Pentru a elabora un program care să rezolve o problemă dată, este necesară
extragerea esenţei problemei, împărţind soluţia în paşi individuali de efectuat.
Secvenţa paşilor altfel obţinuţi, necesari pentru soluţionarea problemei, se
numeşte algoritm. Algoritmul este sâmburele care a dat naştere la disciplina
Informatică. Cuvântul algoritm provine de la matematicianul musulman Abu Ja
far Mohammed ibu Musa al-Khowârizmî (780?-850?), care în lucrarea “Kitab
hisab al-adad al-hindi:”calcule numerice folosind o metodă algebrică. Dicţionarul
explicativ al limbii române dă următoarea definiţie a algoritmului :
“ Ansamblul de simboluri folosite în matematică şi logică, permiţând găsirea în
mod mecanic (prin calcul) a unor rezultate “.
Exemplificăm noţiunea de algoritm.
Exemplul.1. Procedura de realizare şi turnare a unui element de beton.
1. Se aduc materialele necesare preparări betonului (nisip,balast,ciment,apă).
2. Se pune în funcţiune betoniera.
3. Se pun în betonieră pe rând, balastul, nisipul, cimentul.
LIMBAJUL C TEORIE ŞI APLICAŢI I 10

4. Se amestecă compoziţia pentru a obţine omogenizarea acesteia.


5. Se adaugă apa şi se continuă amestecarea o anumită durată de timp.
6. Se scoate din betonieră betonul proaspăt şi se transportă la locul turnării..
7. Se face turnarea betonului în cofrag pentru realizarea elementului dorit.
8. Dacă cantitatea de beton preparat şi turnat este mai mică decât volumul
elementului se reia procesul de la punctul 1, dacă nu se opreşte procesul de
preparare-turnare (STOP). Această procedură cunoscută de toţi constructorii,
are toate elementele unui program de calculator. Distingem:
 o secvenţă de iniţializare 1,
 o terminare normală 8.
Exemplul 2. Algoritmul lui Euclid –Pentru a obţine c.m.m.d.c. a două numere
întregi a şi b , b diferit de 0, împărţim pe a la b , dacă restul împărţirii r1 este
0, atunci b este c.m.m.d.c. a celor două numere, dacă restul r1 este diferit de 0,
se împarte b la r1 şi se obţine restul r2, dacă r2 este 0 se consideră r1 cmmdc
al celor două numere, dacă r2 este diferit de 0 se împarte r1 la r2, rezultă rest
r3 ş.a.m.d.
Ultimul rest nenul este cmmdc al celor două numere a, b.
După aceste exemple putem să definim un algoritm = un sistem de reguli prin
care informaţia iniţială este transformată într-o informaţie finală (rezultat)
folosind un număr finit de calcule sau operaţii intermediare (paşi).
Informaţia iniţială pentru care un algoritm este aplicabil se va numi informaţia
admisibilă a algoritmului respectiv, totalitatea informaţiilor admisibile formând
domeniul algoritmului.
Este absolut necesar ca un algoritm să fie caracterizat prin finitudine, claritate,
generalitate şi unicitate.
 Finitudinea unui algoritm se referă la faptul că pentru transformarea datelor
de intrare în datele de ieşire (soluţie) se folosesc un număr finit de calcule
(paşi).
 Unicitatea constă în faptul că după fiecare pas din procesul de transformare,
regulile algoritmului determină în mod unic pasul următor.
 Generalitatea algoritmului se referă la faptul că pentru orice informaţie din
domeniul algoritmului (pentru orice dată de intrare validă) se poate
determina o mărime de ieşire (soluţie). De exemplu, în cazul în care dorim să
scriem un program care rezolvă ecuaţia de gradul I: 3x+4=0, nu vom scrie un
program care rezolvă ecuaţia dată mai sus, ci un program general care
rezolvă orice ecuaţie de gradul I.
 Prin claritatea algoritmului se înţelege formularea precisă a regulilor după
care au loc transformările datelor de intrare până devin date de ieşire.
Reprezentarea grafică a unui algoritm se numeşte organigramă sau schemă
logică. Organigrama este constituită dintr-o serie de căsuţe denumite blocuri,
interconectate prin segmente direcţionate, care aratăă căile de derulare ale
LIMBAJUL C TEORIE ŞI APLICAŢI I 11

algoritmului. Organigramele sunt scrise folosind limbajul natural şi/sau folosind


expresii matematice sau logice.
Blocurile şi simbolurile care sunt folosite în schema logică sunt:
 căsuţa dreptunghiulară, specifică întreprinderea unei acţiuni (bloc de calcul)
 căsuţa romboidală, specifică luarea unei decizii (bloc de decizie)
 căsuţa paralelogram, specifică citirea sau tipărirea unor date (bloc de
intrare/ieşire)
 căsuţa eliptică, specifică începutul sau sfârşitul algoritmului (bloc
delimitator).
 căsuţa circulară, specifică continuării algoritmului ce se desfăşoară pe mai
multe pagini.
 săgeţile care unesc aceste blocuri.
În paragraful următor vor fi prezentaţi principalii algoritmi întâlniţi în tehnica
curentă de programare.
1.2.1. Algoritmi liniari
Algoritmii liniari sau secvenţiali sunt acei algoritmi care conţin doar secvenţe de
citire/scriere şi de calcul. Organigrama unui algoritm secvenţial are un parcurs
liniar de la debutul problemei (START) până la terminarea ei (STOP).
Exemplul 1
Să se descrie algoritmul rezolvării ecuaţiei de gradul I cu o necunoscută :
ax+b=0.a;b R a 0 şi să se construiască organigrama acestuia.
Rezolvare
1. Se citesc a şi b,a diferit de 0.
2. Se calculează x := -b/a.
3. Se tipăreşte x;
4. STOP.
Start

a, b

x := -b/a

Stop

Observăm că în pasul 2 al algoritmului am folosit operatorul := , în locul


operatorului = .
LIMBAJUL C TEORIE ŞI APLICAŢI I 12

Operatorul := poartă denumirea de operator de atribuire şi are


semnificaţia de atribuire a valorii obţinute prin evaluarea (calcularea)
expresiei din partea dreaptă a operatorului, variabilei din stânga
operatorului.
Un program de calculator va evalua întotdeauna expresia din dreapta
operatorului atribuire (în cazul nostru -b/a) rezultatul obţinut fiind atribuit
variabilei din stânga operatorului( în cazul nostru x).
Exemplul 2
Să se descrie algoritmul conversiei unghiului a din grade sexazecimale în radiani
şi să se realizeze organigrama (schema logică ) acestuia.
Rezolvare
1. Se citeşte a exprimat în grade sexazecimale.
2. Se calculează noua valoare a lui a exprimat în radiani a := a*π/180.
3. Se tipăreşte a;
4. STOP.

Start

a:= a*π/180

Stop

1.2.2. Algoritmi ramificaţi


Algoritmii ramificaţi sunt acei algoritmi care conţin pe lângă secvenţele de
citire/scriere şi de calcul ,şi secvenţe de decizie. In urma secvenţei de decizie doar
o singură secvenţă este posibilă, din două secvenţe existente. Organigrama unui
algoritm ramificat prezintă o bifurcare (ramificare) a parcursului în urma blocului
de decizie.
LIMBAJUL C TEORIE ŞI APLICAŢI I 13

Exemplul 3
Să se descrie algoritmul rezolvării ecuaţiei de gradul I, ax+b=0.a;b R, cu
verificarea coeficienţilor introduşi şi să se construiască organigrama acestuia.
Rezolvare
1 Se citesc coeficienţii a şi b.
2 Dacă a este zero tipărim mesaj de eroare; STOP.
3 Se calculează x := - b/a.
4 Se tipăreşte x.
5 STOP.
Observăm :
 O ieşire anormală a programului 2, respectiv o,
 O ieşire normală 3.
În organigramele următoare, vom renunţa la blocul START pentru economie de
spaţiu.

a, b

DA NU
a = 0

x := -b/a

Eroare x

STOP

Exemplul 4
Să se construiască algoritmul care calculează modulul unui număr şi să se
construiască organigrama acestuia.
Rezolvare
1 Se citeşte numărul nr.
2 Dacă numărul este mai mic decât zero, atunci nr := -nr.
3 Dacă numărul este mai mare sau egal cu 0, atunci nr := nr.
4 Se tipăreşte numărul nr.
5 STOP.
LIMBAJUL C TEORIE ŞI APLICAŢI I 14

nr

DA NU
nr < 0

nr := -nr

nr

Exemplul 5
Să se construiască algoritmul care determină valoarea maximă dintre cele trei
valori citite de la tastatură şi să se deseneze schema logică a acestui algoritm.
Rezolvare 1
1. Se citesc cele trei variabile a,b,c.
2. Se notează d=max (a,b,c).
3. Se fac comparaţiile : dacă a>=b şi a>=c rezultă d= a.
4. dacă b>=a şi b>=c rezultă d= b.
5. dacă c>=b şi c>=a rezultă d= c.
6. se tipăreşte max=d
7. STOP
Această metodă implică efectuarea a 6 comparaţii. Următoarea metodă foloseşte
mai puţine comparaţii.
Rezolvare 2
1. Se citesc cele trei variabile a, b, c.
2. Se notează d=max (a,b,c).
3. Se fac comparaţiile : dacă a>=b şi a>=c rezultă d= a.
4. Dacă a>=b şi a<c rezultă d=c.
5. Dacă a<b şi b>=c rezultă d=b.
6. Dacă a<b şi b<=c rezultă d=c.
7. Se tipăreşte max=d.
8. STOP.
Algoritmul pentru determinarea valorii maxime dintre cele trei valori a,b,c
LIMBAJUL C TEORIE ŞI APLICAŢI I 15

START

TIPAREŞTE
MESAJ

CITEŞTE
a,b,c

da da
a>=b a>=c d=a
nu nu
da
b>=c d=b
d=c

nu
d=c

max=d

STOP

Exemplul 6
Să se realizeze algoritmul şi schema logică pentru ordonarea în sens crescător a 3
numere de tip intreg.
Rezolvare Fie a, b, c cele 3 valori întregi ce trebuie ordonate, se notează cu
a,b,c cele 3 valori de tip intreg. Se realiză o funcţie ordonat care ordonează 2
valori x,y astfel: Dacă x>y este necesar ca x să schimbe locul cu y. Folosim o
variabilă temporară t şi efectuăm următoarele operaţii : t=y, y=x,
x=t, Dacă x<y nu este necesară permutarea dintre x şi y. Această funcţie se aplică
de 3 ori valorilor a, b, c astfel : Ordonat (a, b) a<b. Ordonat (b, c) ) b<c dar
a?b. Ordonat (a, b) a<b<c
LIMBAJUL C TEORIE ŞI APLICAŢI I 16

START

CITEŞTE a,b,c

nu
a>b

da

t=b
b=a
da
a=t

nu
b>c

da

t=c
c=b
b=c

nu
a>b
da
t=b
b=a
a=t

STOP

Ordonarea a trei numere (varianta 1)


LIMBAJUL C TEORIE ŞI APLICAŢI I 17

START
ORDONAT X,Y

CITEŞTE
a,b,c
nu
X>Y

x(1)=a da
y(1)=b
t=y
z(1)=c
y=x
x=t

ordonat
x(1),y(1)
RETURN

ordonat
y(1),z(1)

ordonat
x(1),y(1)

tipareste
a,b,c

STOP

Ordonare a trei numere (varianta 2)


După primele două apeluri, în c avem maximul dintre valorile iniţiale, dar despre
ordinea dintre a şi b nu putem spune cu siguranţă nimic (ex. Iniţial a=5, b=4, c=3),
de aceea este necesară şi o rearanjare a valorilor a şi b. (ultimul apel).

1.2.3. Algoritmi ciclici


Algoritmii ciclici sunt acei algoritmi care conţin bucle sau cicluri (reluarea
anumitor secvenţe ale algoritmului de un număr finit de ori), în funţie de
îndeplinirea unei condiţii. Organigrama unui algoritm ciclic conţine un parcurs
LIMBAJUL C TEORIE ŞI APLICAŢI I 18

care este reluat de mai multe ori în funcţie de o condiţie impusă într-un bloc de
decizie.

Exemplul 7
Să se descrie algoritmul care calculează suma a n numere citite de la tastatură şi să
se construiască organigrama acestuia.
Rezolvare
1. Se citeşte n.
2. Se iniţializează o variabilă contor i cu valoarea 0.
3. Se citeşte un număr de la tastatură.
4. Se adună acest număr la sumă şi se incrementează contorul (se măreşte cu 1).
5. Dacă valoarea contorul este mai mic decât numărul n, se revine la pasul 3.
6. Se tipăreşte suma.
În acest program observăm că secvenţa 3 - 4 se repetă de n ori.

s := 0

i := 0

nr

s := s + nr

i := i + 1

i < n

În pasul i := i + 1, se evaluează expresia din dreapta operatorului (valorii lui i se


adaugă 1), rezultatul obţinut fiind atribut lui i. În urma acestei operaţii i va fi mai
mare cu 1.
LIMBAJUL C TEORIE ŞI APLICAŢI I 19

În expresia s := s + nr, se evaluează expresia din dreapta operatorului atribuire,


(valorii lui s se adaugă valoarea lui nr), rezultatul obţinut fiind atribuit lui s. În
urma acestei operaţii s creşte cu nr.
Exemplul 8
Să se descrie algoritmul care calculează factorialul unui număr întreg şi să se
construiască schema logică a acestuia.
Rezolvare
Factorialul unui număr n este produsul numerelor de la 1 la numărul n inclusiv.
1. Se citeşte n.
2. Se iniţializează o variabilă fact cu valoarea 1.
3. Se iniţializează o variabilă contor i cu valoarea 1.
4. Se înmulţeşte fact cu contorul i, valoarea obţinută fiind atribuită variabilei
fact şi se incrementează contorul cu 1.
5. Dacă contorul este mai mic sau egal decât numărul n, se revine la pasul 4.
6. Se tipăreşte fact.
În acest program observăm că secvenţa 4 se repetă de n ori.

fact := 1

i := 1

fact := fact ∙ i

i := i + 1

i ≤ n

fact

Dacă o schemă logică este greu de înţeles, putem parcurge algoritmul pentru un
anumit număr de paşi, pe hârtie.
Să încercăm să parcurgem algoritmul nostru pentru n=3.
1. n := 3; variabilei n i se atribuie valoarea 3,
2. fact := 1; variabilei fact i se atribuie valoarea 1,
3. i := 1; variabilei contor i se atribuie valoarea 1,
LIMBAJUL C TEORIE ŞI APLICAŢI I 20

4. fact := 1 * 1 = 1; se înmulţeşte fact cu i, valoarea obţinută fiind atribuită


variabilei fact,
i := 1 + 1 = 2; se incrementează contorul i cu 1,
5. 2 ≤ 3; da, se revine la pasul 4,
4. fact := 1 * 2 = 2;
i := 2 + 1 = 3;
5. 3 ≤ 3; da, se revine la pasul 4,
4. fact := 2 * 3 = 6;
5. 4 ≤ 3; nu,
7. tipărim fact, adică 6.
Exemplul 9
Să se determine cel mai mare divizor comun a două numere intregi şi pozitive,
(algoritmul lui Euclid).
Rezolvare
Pentru a determina c.m.m.d.c. a două numere a şi b, întregi şi pozitive a>b, se va
aplica următorul procedeu:
Se împarte a la b şi se obţine un rest r, dacă r=0 cmmdc al celor două numere
este b, dacă nu se va împărţii b la rest r şi se obţine un nou rest r1.
Dacă restul r1 =0 cmmdc este r, dacă nu se va împărţii r la r1 şi se continuă ciclul
până când restul devine =0.
Ultimul rest diferit de zero este c.m.m.d.c. al celor două numere a,b. Pentru a
relua procesul împărţirii şi determinarea restului, se consideră că cel mai indicat
este folosirea unui ciclu cu paşi necunoscuţi, la care părăsirea ciclului se face când
restul împărţirii devine zero.
Pentru a nu folosi o mulţime de variabile în care să se depoziteze valorile
resturilor se foloseşte o permutare între a cu b şi b cu r.

q=a/b
r=a-b*q
Dacă r=0 c.m.m.d.c. =b.
Dacă r≠0 a devine b iar r devine b şi se reia procesul .
Dacă a<b nu este necesară permutarea lui a cu b, fiincă după primul ciclu se
realizează această permutare.
LIMBAJUL C TEORIE ŞI APLICAŢI I 21

START

CITEŞTE
a,b

q=a/b
r=a-b*q

da
r=0 cmmd=b

nu

a=b AFISEAZA
b=r cmmd

STOP

Cel mai mare divizor comun a doua numere


LIMBAJUL C TEORIE ŞI APLICAŢI I 22

2. Mediul de programare turbo c 2.0

Mediul integrat de dezvoltare Turbo C 2.0 (Integrated Development Environment)


permite editarea, depanarea programelor sursă scrise în limbajul C şi conţine :
 Compilator.
 Editor.
 Depanator.
 Utilitare.
Lansarea mediului integrat Turbo C2.0
Mediul integrat lucrează sub prompterul Dos şi lansarea lui se efectuează prin
emiterea comenzii :
TC Enter.
Dacă directorul de lucru este TC.
Dacă directorul în care se află utilitarul TC este diferit de directorul TC, este
necesar ca în fişierul Autoexec.bat, să se specifice calea spre directorul ce conţine
utilitarul TC.
După emiterea comenzii este afişat ecranul principal ,ce conţine în partea
superioară o linie de meniuri derulante pe verticală, fereastra de editare, fereastra
de mesaje şi linia de referinţe rapide.

2.1. Mediul de lucru


Pentru a stabili mediul de lucru, trebuie să se efectueze la prima lansare pe
calculator configurarea directoarelor. Se apasă tasta F10 pentru a apela linia de
meniuri şi se tastează O, pentru deschiderea meniului Options, sau se tastează
combinaţia ALT şi O . Se alege din meniul Options, submeniul Directories ce va
deschide o fereastră ce conţine rublicile :
Include directories.
Library directories.
Output directories.
Turbo C.
La fiecare rublică sunt afişatedirectoarele configurate la momentul respectiv.
Pentru a funcţiona corect, este necesar să se modifice rublicile în conformitate cu
directoarele existente pe calculator.
Se va considera că există pe hardul calculatorului directoarele :
C:\TC
C:\TC\INCLUDE
LIMBAJUL C TEORIE ŞI APLICAŢI I 23

C:\TC\LIB
C:\TEMPC
Pentru a indica directorul ce conţine fişierele header (cu extensia h), se va alege
opţiunea Include directories şi se apasă Enter. În fereastra ce apare se va tasta
discul,directorul, ce conţine fişierele header, în cazul de faţă C:\TC\INCLUDE
Pentru a indica directorul ce conţine fişierele de bibliotecă, se va alege opţiunea
Library directories şi se apasă Enter. În fereastra ce apare se va tasta
discul,directorul, ce conţine fişierele header, în cazul de faţă C:\TC\LIB .
Pentru a indica directorul ce va conţine fişierelede obj, map, exe, se va alege
opţiunea Output directory şi se apasă Enter. În fereastra ce apare se va tasta
discul,directorul, ce va conţine fişierele de ieşire, în cazul de faţă C:\TEMPC .
Pentru a indica directorul ce conţine fişierele necesare lucrului cu mediul Turbo,
la opţiunea Turbo C se va alege C:\TC .
După realizarea acestor configurări se va apăsa ESC, pentru a reveni în meniul
Options şi se alege submeniul Save options se apasă Enter, care va rescrie
fişierul TCCONFIG.TC , de pe hardiscul calculatorului, iar la o nouă lansare a
mediului Turbo C, setările se păstrează, nefind necesar o nouă configurare.
Observaţie:
Se recomandă s-ă fie realizat directorul de ieşire TEMPC, pentru a se găi mai uşor
fişierele EXE, sau pentru a şterge fişierele OBJ, MAP, EXE.

2.1.1. Apelarea meniului, taste universale


Apelarea unui meniu de pe bara de meniuri, se face cu combinaţia de taste
ALT+tasta corespunzătoare primului caracter din meniul dorit.
Exemplu:
ALT+F =meniul File.
ALT+O =meniul Options.
ALT+E =meniul Edit.
ALT+R = meniul Run.
ALT+C =meniul Compile.

Pentru o apelare mai rapidă a unui meniu, sau a unei opţiuni dintr-un meniu, se
pot folosi tastele universale sau combinaţia de taste. Când se folosesc tastele
universale, operaţia curentă este întreruptă şi se execută operaţia ataşată tastei
apelate. Doar în cazul că în lucru este o fereastră de dialog, se introduce
informaţia cerută de fereastra de dialog şi apoi se poate apela o tastă universală.
LIMBAJUL C TEORIE ŞI APLICAŢI I 24

TASTA Funcţia realizată


F1 Afişează help pentru operaţia curentă
F2 Salvează fişierul curent
F3 Încarcă un fişier în procesul de editare
F4 Execută programul până la linia curentă (linia pe care este cursorul)
F5 Focalizarea/defocalizarea ferestrei curente
F6 Bascularea între ferestrele active
F7 Rulează programul în mod depanare trasând în funcţii
F8 Rulează programul în mod depanare sărind peste funcţii
F9 Compilare şi legare
F10 Basculare între meniu şi fereastra activă
CTRL/F1 Ajutor doar în editare pentru obiecte C
CTRL/F2 Resetează programul –Run/program reset
CTRL/F3 Afişează stiva cu funcţiile apelate
CTRL/F4 Evaluează sau modifică o expresie
CTRL/F7 Adaugă o expresie watch
CTRL/F8 Pune sau şterge un punct de întrerupere
CTRL/F9 Execută programul
SHIFT/F10 Indică numărul versiuni Turbo
ALT/F1 Readuce pe ecran ultimul ajutor
ALT/F3 Alege un fişier din lista pick
ALT/F5 Bascularea înte ecranul utilizatorului şi ecranul Turbo
ALT/F6 Bascularea între fereastra watch şi fereastra de mesaje
ALT/F7 Salt la eroarea precedentă
ALT/F8 Salt la următoarea eroare
ALT/F9 Compilare şi realizarea fişierului OBJ
ALT/B Deschiderea meniului Break
ALT/C Deschiderea meniului Compile
ALT/D Deschiderea meniului Debug
ALT/E Intrarea în Editor
ALT/F Deschiderea meniului File
ALT/O Deschiderea meniului Options
ALT/P Deschiderea meniului Project
ALT/R Deschiderea meniului Run
ALT/X Ieşirea din Turbo şi revenirea în linia de comandă DOS

2.1.2.Meniul principal
Meniul principal permite alegerea următoarelor meniuri:
FILE Gestionarea fişierelor, directoarelor şi ieşirea din programul Turbo.
EDIT Permite editarea fişierului sursă.
LIMBAJUL C TEORIE ŞI APLICAŢI I 25

RUN Permite controlul execuţiei programului rezultat în urma compilării şi


lincheditării fişierului sursă.
COMPILE Compilează şi creazăfişierul executabil.
PROJECT Permite controlul programelor cu surse multiple.
OPTIONS Permite stabilirea opţiunilor de compilare, definirea de macrouri,
modificarea fişierelor de configurare.
DEBUG Controlează sesiunea de depanare a programului executabil.
BREAK/WATCH Facilitează depanarea prin lucrul cu puncte de întrerupere şi
supravegherea expresiilor.

2.1.2.1.Meniul FILE
Meniul File poate fi apelat prin ALT/F, sau tastând F în meniul principal.
Opţiunile meniului :
Load =încarcă un fişier în editor, prin tastarea numelui fişierului, sau se poate lăsa
forma generală *.C, care va deschide o fereastră, ce conţine lista fişierelor cu
extensia C , folosind tastele de navigare (săgeţi), se selectează fişierul dorit şi se
apasă Enter.
Pick =permite selectarea unui fişier din lista ultimilor 8 fişiere editate, sau
selectând ultima opţiune load file, se poate specifica un alt fişier decât cele
prezentate.
New =Permite crearea de fişier nou în procesul de editare, cu numele generic
NONAME.C, care la prima salvare poate lua numele inpus de utilizator.
Save =Salvarea fişierului în procesul de editare.
Write To =Salvarea pe disc a fişierului curent, sub un nou nume impus de
utilizator.
Directory =Afişează lista intrărilor într-un director specificat, sau se apasă Enter
pentru directorul curent, permiţând încărcarea în editor a fişierului selectat.
Change Dir = Afişează directorul curent şi permite schimbarea directorului curent.
Os Shell = Permite ieşirea temporară din meniul Turbo şi introducerea de comenzi
pe linia DOS, iar pentru revenire din DOS în meniu, se face prin tastarea
cuvântului Exit.
Quit = Permite părăsirea mediului Turbo şi revenire sub prompterul DOS.

2.1.2.2. Meniul Edit


Realizarea programului sursă se poate face cu orice editor ASCII, dar se
recomandă folosirea editorului propriu al mediului Turbo.
Lansarea procesului de editare se face prin comanda EDIT, din meniul EDIT sau
combinaţia de taste ALT/E , care are ca efect activarea ferestrei de editare şi
cursorul de editare se poziţionează în text.
LIMBAJUL C TEORIE ŞI APLICAŢI I 26

Introducerea textului se face normal ca şi în alte editoare, trecerea pe rând nou se


face apăsând tasta ENTER.
În partea superioară a ferestrei de editare se află linia de stare, care oferă
informaţii despre fişierul ce se editează, starea tastelor speciale de editare.
Informaţiile prezentate pe linia de stare sunt :
Line, col, insert, tab, fill, indent, numele fişierului ce se editează.
Line = indică numărul liniei din fişier pe care este poziţionat cursorul de editare.
Col = indică numărul coloanei din fişier pe care este poziţionat cursorul de
editare.
Insert = indică modul de de editare cu posibilitatea de a insera text la poziţia
cursorului de editare, dacă se apasă tasta Insert, se va bascula pe modul Overwrite
ce are ca efect ştergerea caracterului de deasupra cursorului de editare şi scrierea
noului caracter editat.
Indent = indică modul de lucru autoindentare.
Tab = indică modul de a insera taburi (spaţiu liber de 8 caractere) în editare.
Fill = dacă modul tabulare este activ, opţiunea fill complectează începutul liniilor
cu un număr optim de taburi.
Unindent = permite ca tasta BACKSPACE să efectueze salt înapoi cu un nivel de
indentare.
Nume fişier = indică discul, directorul şi numele fişierului ce se editează.
Comenzile de editare
Comenzi pentru deplasarea cursorului de editare
Deplasarea cursorului în cadrul fişierului aflat în procesul de editare se realizează
folosind tastele de navigare rapidă sau combinaţii de taste astfel :
CTRL/S sau săgeată la stânga = deplasarea cursorului spre stânga cu o poziţie.
CTRL/D sau săgeată la dreapta = deplasarea la dreapta cu o poziţie a cursorului.
CTRL/A sau CTRL/săgeată stânga = deplasează cursorul la primul caracter din
cuvântul precedent.
CTRL/F sau CTRL/săgeată dreapta = deplasează cursorul la primul caracter din
cuvântul următor.
CTRL/E sau săgeată în sus = deplasează cursorul de editare cu un rând (linie) în
sus.
CTRL/X sau săgeată în jos = deplasează cursorul de editare cu un rând (linie) în
jos.
CTRL/R sau PGUP = deplasează cursorul şi textul în sus cu un ecran de editare.
CTRL/C sau PGDN = deplasează cursorul şi textul în jos cu un ecran de editare.
CTRL/W = deplasează textul cu o linie în jos dar cursorul rămâne pe poziţia
curentă.
LIMBAJUL C TEORIE ŞI APLICAŢI I 27

CTRL/Z = deplasează textul cu o linie în sus dar cursorul rămâne pe poziţia


curentă.
CTRL/S sau HOME = deplasează cursorul pe prima coloană (la inceputul liniei)
a liniei curente.
CTRL/QD sau END = deplasează cursorul pe ultima coloană (la sfârşitul liniei) a
liniei curente.
CTRL/QE = deplasează cursorul pe prima linie din ecranul de editare.
CTRL/QX = deplasează cursorul pe ultima linie din ecranul de editare.
CTRL/PGUP = deplasează cursorul la primul caracter din fişier.
CTRL/PGDN = deplasează cursorul la ultimul caracter din fişier.
Comenzi de ştergere sau inserare.
INS = activează sau dezactivează modul de inserare.
BACKSPACE = şterge caracterul din stânga cursorului de editare.
DEL = şterge caracterul din dreptul cursorului de editare.
CTRL/T = şterge cuvântul din dreapta cursorului de editare.
CTRL/N = inserează o linie (rând) goală în poziţia cursorului de editare.
CTRL/Y = şterge linia pe care este situat cursorul de editare.
CTRL/QY = şterge textul de la poziţia curentă a cursorului până la sfârşitul liniei.
Comenzi diverse.
Tab = inserează un spaţiu liber de 8 caractere sau cu o valoare impusă prin
opţiunea Tab size din meniul Options/environment.
CTRL/O şi F = activează sau dezactivează modul de editare optimă astfel:
Dacă modul de editare optimă este activ la inceputul fiecărei linii se complectează
cu un număr optim de spaţii sau taburi.
CTRL/O şi I = activează sau dezactivează modul de editare autoindentare astfel :
Modul de autoindentare activat va deplasa cursorul de editare după apăsarea tastei
ENTER sub coloana de început a liniei liniei anterioare.
CTRL/K şi S = salvează fişierul fără a părăsi editorul.
CTRL/K şi P tipăreşte la imprimantă blocul marcat iar în lipsa acestuia tipăreşte
tot fişierul.
F3 = încarcă în editor un fişier existent în procesul de editare, sau crează un fişier
nou.
Comenzi de realizare,mutare,copiere,ştergere a blocurilor.

Blocul reprezintă o porţiune de text delimitată de markeri.


În cadrul unui fişier poate exista un singur bloc asupra căruia se pot efectua
următoarele operaţii :
LIMBAJUL C TEORIE ŞI APLICAŢI I 28

Marcarea începutului unui bloc la poziţia curentă a cursorului de editare prin


combinaţia de taste CTRL/K şi apoi B.
Marcarea sfârşitului de bloc prin deplasarea cursorului de editare la poziţia
dorită şi realizarea combinaţiei de taste CTRL/K şi apoi K, ce are ca efect
punerea în evidenţă a blocului, prin schimbarea culorii de fond a zonei ocupată de
bloc.
Copierea unui bloc la poziţia curentă a cursorului : se deplasează cursorul de
editare la poziţia dorită şi se realizează combinaţia de taste CTRL/K şi apoi C, ce
are ca efect, copierea blocului în prealabil realizat şi delimitarea acestei copii cu
markeri.
Ştergerea blocului se realizează prin combinaţia de taste CTRL/K şi Y, ce are ca
efect ştergerea blocului marcat.
Activarea sau dezactivarea afişări blocului marcat se realizează prin
combinaţia de taste CTRL/K şi H , dacă un bloc este marcat (afişat cu un fond
diferit de restul documentului), asupra lui se pot efectua operaţiile de copiere,
mutare, stergere.
Mutarea unui bloc se realizează cu combinaţia de taste CTRL/K şi V , ce are ca
efect mutarea blocului marcat la poziţia curentă a cursorului de editare.
Inserarea unui fişier dacă în cadrul fişierului ce se editează, se doreşte inserarea
conţinutului unui fişier existent pe hard disc, se realizează combinaţia de taste
CTRL/K şi R, care va deschide o fereastră de dialog, în care se va scrie calea şi
numele fişierului ce se inserează, textul inportat va fi marcat ca bloc.
Scrierea unui bloc intr-un fişier de pe hard disc se realizează prin combinaţia de
taste CTRL/K şi W, care va deschide o fereastră de dialog, în care se va specifica
calea şi numele fişierului în care se va scrie blocul marcat.
Meniul Compile.
Meniul compile permite compilarea fişierului sursă şi crearea programului
executabil. Selectarea meniului Compile se face prin combinaţia de taste ALT/C
sau tastând C, când meniul principal este activ.
Opţiunile meniului Compile sunt :
Compile to obj = compilează fişierul sursă scris în C şi crează un fişier obiect cu
acelaş nume ca şi fişierul sursă, dar extensia este obj. Alegerea acestei opţiuni se
poate face şi folosind combinaţia de taste ALT/F9.
Make exe file = crează fişierul executabil prin operaţiile de compilare şi
lincheditare (legare), iar numele fişierului executabil este indentic cu fişierul sursă
dar va avea extensia exe.
Link exe file = realizează ediţia de legături şi fişierul executabil.
Build all = crează fişierul executabil compilând şi lincheditând toate fişierele
proiectului.
Primary C file = încarcă în editor fişierul sursă sau headerul în care s-au detectat
erori la compilare.
LIMBAJUL C TEORIE ŞI APLICAŢI I 29

Get info = afişează informaţiile despre ultima compilare.

2.1.2.3. Meniul Run


Meniul Run permite depanarea programului sursă, după ce au fost eliminate
erorile de compilare şi lincheditare.
Meniul Run se apelează combinaţia de taste ALT/R sau tasta R când meniul
principal este activ.
Opţiunile meniului Run sunt :
Run = CTRL/F9 execută programul executabil cu extensia exe, rezultat în urma
compilări şi lincheditări, dacă sursa a fost modificată de la ultima compilare, va
reface operaţiile de compilare lincheditare si apoi rulează fişierul executabil.
Program reset = CTRL/F2 închide sesiunea curentă de depanare.
Go to cursor = F4 execuţia programului se face până la poziţia curentă a
cursorului de editare.
Trace info = F7 execuţia programului se face instrucţiune cu instrucţiune,
inclusiv în interiorul funcţiilor apelate, fără însă a intra în funcţiile de bibliotecă.
Step over = F8 execută programul instrucţiune cu instrucţiune , sărind peste
apelurile de funcţii, fără a se intra în interiorul funcţiei apelate.
User scrin ALT/F5 afişează ecranul utilizatorului, revenirea în procesul de
editare se face apăsând orice tastă.

2.1.2.4. Meniul Debug.


Meniul Debug se apelează folosind combinaţia de taste ALT/D sau tastând D în
meniul principal activat.
Opţiunile meniului Debug sunt :
Evaluate = permite evaluarea şi modificarea valorii unei expresii, pentru
introducere de nume, iar evaluarea sau modificarea deschide câte o fereastră.
Ferestrele folosite sunt :
Evaluate
Result.
New value.
Find function = permite afişarea în fereastra de editare a definiţiei unei funcţii,
această opţiune se poate utiliza numai într-o sesiune Debug.
Call stack= permite deschiderea unui meniu intr-o fereastră, în care se poate
selecta funcţia, din lista de funcţii apelate până la punctul curent de execuţie a
programului şi permite vizualizarea liniei executate curentă dintr-o anumită
funcţie.
Source debugging = permite introducerea a trei valori, care vor determina modul
de depanare introdus în fişierul executabil.
LIMBAJUL C TEORIE ŞI APLICAŢI I 30

On depanarea se face cu depanatorul din Turbo Debugger sau depanatorul


integrat, şi această valoare este implicită.
Standalone depanarea se face doar cu Turbo Debugger.
None programul nu poate fi depanat în nici un mod.
Display swapping = permite trei valori care determină cazurile pentru care Turbo
C realizează automat bascularea între ecranul utilizatorului şi ecranul de editare în
cadrul unei sesiuni de depanare.
Smart trecerea se face la fiecare scriere pe ecran a programului.
Always trecerea se face la execuţia fiecărei instrucţiuni.
None trecerea dintr-un ecran in altul nu se face în nici o situaţie.
Refresh display = reface conţinutul ecranului editorului, dacă acesta a fost distrus
accidental.

2.1.2.5. Meniul Break/watch.


Apelarea meniului Break/watch se face prin combinaţia de taste ALT/B, sau
tastând B în cadrul meniului principal activat.
Prin meniul Break/watch se poate efectua depanarea programului prin intermediul
punctelor de întrerupere şi urmărirea expresiilor.
Opţiunile meniului Break/watch sunt :
Add watch = permite introducerea unei expresii de supraveghere în fereastra de
urmărire.
Delete watch = şterge expresia curentă din fereastra de urmărire.
Edit watch = permite intr-o fereastră separată editarea expresiei curente din
fereastra de urmărire.
Remove all watches = şterge fereasta de urmărire.
Toggle breakpoint = stabileşte sau anulează un punct de întrerupere în linia în
care este poziţionat cursorul.
Clear all breakpoint = şterge toate punctele de întrerupere din cadrul
programului.
View new breakpoint = deplasează cursorul la următorul punct de intrerupere.
Ordinea de parcurgere a punctelor, este determinată de ordinea în care au fost
stabilite şi nu de ordinea fizică în fişier.

2.1.2.6. Meniul options


Meniul Options poate fi apelat prin combinaţia de taste ALT/O sau tastând O în
meniul principal activat.
Prin intermediul acestui meniu se apelează submeniuri, prin care se stabilesc
opţiunile generale ale modului de lucru ale compilatorului, modului de lucru al
LIMBAJUL C TEORIE ŞI APLICAŢI I 31

editorului de legături, modul de lucru al depanatorului, controlează locaţiile


fişierelor, argumentele programului.
Submeniurile meniului Options sunt :
Compiler. Linker. Environment.
Directories. Arguments. Save options. Retrieve options.
COMPILE.
Submeniul Compile permite stabilirea opţiunilor compilatorului prin indicarea
modelului de memorie,editarea macrodefiniţiilor,opţiuni pentru crearea fişierului
obiect, specificarea procesorului pentru care se generează codul, a modelului în
virgulă flotantă, modului de aliniere, etc.
Opţiunea Model.
Permite stabilirea modelului de memorie :
TINY. = 64 Ko pentru cod,date şi tabele.
SMALL. = 64Ko pentru cod + 64 Ko pentru date.
MEDIUM. = 64Ko pentru date statice şi 1 Mo pentru cod.
COMPACT. = 65 Ko pentru cod şi 1 Mo pentru date.
LARGE. = 1Mo pentru date şi 1 Mo pentru cod.
HUGE. = 1 Mo pentru date, 1Mo pentru cod şi 64 Ko pentru date statice.
Opţiunea Defines.
Permite introducerea de macrodefiniţii pentru preprocesor.
MAX=50;
Simbolul MAX a fost definit cu valoarea 50.
Opţiunea Instruction set.
Permite specificarea procesorului pentru care se va genera codul.
Opţiunea Floating point.
Permite stabilirea modului de lucru în virgulă flotantă.
Utilizare coprocesor matematic 8087, 80287
Emulare coprocesor matematic
None – nu se foloseşte virgulă flotantă.
LIMBAJUL C TEORIE ŞI APLICAŢI I 32

3. Structura unui program sursă în limbajul C.


Cel mai scurt program sursă C este de forma:
void main ()
{
}
Acest program nu face nimic, dar este programul minimal pe care compilatorul C
îl poate compila.
void main () este o funcţie. Funcţia void main () nu poate lipsi din nici un
program C, fiind funcţia de intrare în program. După numele funcţiei, şi cele două
paranteze urmează o paranteză acoladă deschisă, respectiv o paranteză acoladă
închisă. Cele două paranteze definesc corpul funcţiei.
Un program C care va afişa un mesaj este:
#include <stdio.h>
void main ()
{
printf("Acest program afiseaza un mesaj");
printf("\nAcesta este mesajul");
}
În acest program, în corpul funcţiei void main () avem două rânduri în plus. Un
rând care este terminat prin; (punct şi virgulă) se numeşte o instrucţiune. În cazul
nostru funcţia void main (), conţine două instrucţiuni. Funcţia void main () poate
conţine oricâte instrucţiuni dorim, fiecare instrucţiune trebuind separată prin;.
Vom anticipa şi vom dezvălui faptul că printf() (cuvântul cheie care apare în cele
două instrucţiuni) este tot o funcţie, dar o funcţie de bibliotecă, adică inclusă în
limbaj. Funcţia printf() este folosită pentru afişarea mesajelor pe ecran. Funcţia
printf() este echivalentă cu instrucţiunea write din Pascal.
Faţă de celelalte limbaje de programare, limbajul C nu are un set de instrucţiuni
de bază. Astfel, pentru a folosi funcţia printf(), va trebui să indicăm numele
fişierului bibliotecă în care această funcţie este declarată. Funcţia printf() este
declarată în fişierul stdio.h, extensia h provine de la numele header, şi este un
fişier de bibliotecă care conţine o mulţime de funcţii de intrare/ieşire (standard
input/output).
Pentru a include acest fişier header în programul nostru, vom adăuga un cuvânt
cheie la începutul fişierului, sub forma:
#include <stdio.h>
Cuvintele cheie care încep cu simbolul # (diez), se numesc directive procesor, sau
directive preprocesor. In cazul nostru am folosit directiva include care include
fişierul stdio.h în programul nostru.
Se remarcă faptul că limbajul C este un limbaj bazat pe funcţii. Pe lângă funcţiile
de bibliotecă şi funcţia void main (), putem defini şi funcţii proprii care ne ajută la
segmentarea programului. Definirea funcţiilor va fi descrisă mai pe larg în
capitolul Funcţii.
LIMBAJUL C TEORIE ŞI APLICAŢI I 33

Să vedem un program C mai complex şi să încercăm să punem în evidenţă


diferitele părţi ale unui program C.
#include <stdio.h>
#define PI 3.1415

void titlu();

void main ()
{
int raza=5;
float aria;

aria=PI*raza*raza;
titlu();
printf("Aria cercului de raza %d este %f", raza, aria);
}

void titlu()
{
/* Functie care afiseaza un mesaj*/
printf("Program pentru calculul ariei unui cerc");
}
Programul nostru C conţine la început zona directivelor preprocesor. Directiva
#include am văzut-o mai sus. Directiva #define permite definirea unor constante.
In cazul nostru am definit constanta PI.
Programul conţine două funcţii: funcţia void main () şi funcţia titlu(). Toate
funcţiile definite de utilizator, în cazul nostru funcţia titlu(), trebuiesc declarate la
începutul fişierului, după zona directivelor preprocesor.
Funcţia titlu() care este definită după funcţia void main () conţine o singură
instrucţiune. Inainte de instrucţiunea printf(), în corpul funcţiei titlu(), avem un
text cuprins între simbolurile /* şi */. Acest text se numeşte comentariu şi este
folosit pentru a furniza lămuriri privind părţi ale programului, pentru programator.
Textele cuprinse între /* şi */ sunt ignorate de către compilator.
La începutul funcţiei void main () este zona de declarare a variabilelor. In
programul nostru avem o variabilă întreagă numită raza, iniţializată la valoarea 5,
şi o variabilă reală numită aria.
În continuare, funcţia void main () conţine trei instrucţiuni: o instrucţiune de
calcul, o instrucţiune de apel a funcţiei titlu() şi o instrucţiune de tipărire folosind
funcţia printf().
Atenţie, limbajul C face distincţie intre literele mari şi mici.

3.1. Crearea unui program


Pentru a crea un program (un executabil), folosind limbajul C, trebuiesc parcurse
trei etape:
LIMBAJUL C TEORIE ŞI APLICAŢI I 34

1. Crearea fişierului sursă C


2. Compilarea programului
3. Linkeditarea programului
Crearea fişierului sursă C poate fi făcută în editorul programului Turbo C.
Pentru a crea un fişier sursă, se lansează programul Turbo C şi se deschide
meniul FILE cu combinaţia ALT/F, apoi cu săgeată în jos se selectează opţiunea
NEW care are ca efect deschiderea automată a ferestrei de editare.
Se editează linie cu lunie fişierul. Trebuiesc respectate regulile de sintaxă, după
cum au fost prezentate mai sus.
Textul programului sursă poate fi salvat într-un fişier pe disc, selectând comanda
Save din meniul File (Alt+F). In fereastra de dialog deschisă la prima salvare va
apare numele generic NONAME.C, se tastează numele fişierului (respectând
convenţia DOS) şi se apasă tasta <Enter>.La o nouă salvare a fişierului nu mai
este necesar indicarea numelui fişierului, considerându-se vechiul nume.
Dacă se doreşte opţinerea mai multor fişiere sursă cu conţinut puţin diferit , se
recomandă folosirea opţiunii Write to care deschide o nouă fereastră de dialog , în
care se va specifica numele ce se dă fişierului duplicat, care urmează a fi
modificat.
Compilarea programului sursă se poate face selectând comanda Compile to OBJ
din meniul Compile (Alt+C). Compilarea crează un fişier obiect (object file).
Fişierul obiect este un fişier binar cu extensia obj, care conţine transformarea
instrucţiunilor cuprinse în fişierul sursă C în instrucţini care pot fi executate de
procesor (cod maşină). Fişierul obj nu poate fi rulat direct de către sistemul de
operare. El este un fişier intermediar.În urma procesului de compilare , dacă sunt
erori de sintaxă sau de apelare a funcţiilor, acestea vor fi afişate intr-o fereastră de
mesaje, cu specificarea erorii şi poziţia în program a erorii.
Se vor analiza erorile şi cauzele ce au produs aceste erori , iar dacă aceste erori
sunt greu de eliminat se va analiza cu atenţie meniurile lui Turbo C, respectiv
căile de căutare pentru fişierele necesare lucrului.
Se vor elimina toate erorile şi abia apoi se poate trece la pasul următor.
Linkeditarea fişierului obiect se poate face selectând comanda Link to EXE din
meniul Compile (Alt+C). Linkeditarea va adăuga fişierului obiect, cod maşină
care permite accesul la dispozitivele de intrare/ieşire pentru un anumit sistem de
operare. In urma linkeditării rezultă fişierul executabil, cu extensia exe. Acest
fişier, care se numeşte şi fişier program, sau program pe scurt, poate fi rulat
(executat) de către sistemul de operare.
Compilarea/Linkeditarea poate fi făcută şi într-un singur pas dacă se selectează
comanda Run din meniul Run (Alt+R). Această comandă compilează,
linkeditează şi lansează în execuţie programul nostru.
LIMBAJUL C TEORIE ŞI APLICAŢI I 35

3.2. Tipuri de date.


Un tip de dată reprezintă o mulţime de valori pe care le poate lua o dată. In C
există tipuri de date standard şi tipuri de date definite de utilizator. Tipurile de
date standard în C vor fi prezentate mai jos.

3.2.1. Tipul întreg


Permite reprezentarea numerelor întregi. Tipuri mai uzuale sunt:
Numele Domeniul de valori Lungi Reprezentare
tipului mea
în
octeţi
unsigned 0 … 255 1 întreg fără
char semn
unsigned 0 … 65535 2 întreg fără
int semn
int -32768 … 32767 2 întreg cu semn
long -2.147.483.648 … 4 întreg cu semn
2.147.483.647
Dacă se depăşeşte domeniul de valori al unui tip de dată, fie va fi semnalată o
eroare la execuţie, fie rezultatul afişat va fi eronat.

3.2.2. Tipul real


Permite reprezentarea numerelor reale. Atenţie, reprezentarea numerelor reale în
orice sistem de calcul este aproximativă, pentru că numărul de zecimale care
poate fi reţinut este limitat de tipul de dată.
Numele tipului Domeniul de valori Lungimea Reprezentare
în octeţi
float 3.4E-38 … 3.4E+38 4 virgulă mobilă
double 1.7E-308 … 1.7E+308 8 virgulă mobilă
long double 3.4E-4932 … 1.1E+4932 16 virgulă mobilă
3.2.3. Tipul caracter
Este format din caracterele codului ASCII. Codul ASCII permite reprezentarea a
256 de caractere. Tipul caracter este reţinut pe un octet.
Numele tipului Domeniul de valori Lungimea Reprezentare
în octeţi
unsigned char 0 … 255 1 întreg fără semn
char -128 … 127 1 întreg cu semn
LIMBAJUL C TEORIE ŞI APLICAŢI I 36

3.3. Constante şi variabile


3.3.1. Constante
In C constantele trebuiesc precedate de cuvântul cheie const. Declararea unei
constante se face:
const [tipul de data] numele_constantei = valoarea;
O constantă nu poate fi iniţializată decât odată cu declararea ei. Dacă tipul de dată
nu este precizat, constanta este implicit de tip întreg. Constantele trebuiesc
declarate la începutul funcţiei, sau la inceputul fişierului după directivele
preprocesor.
#include <stdio.h>
const a=2;
void main ()
{
const b=3;
const float pi=3.1415;

}
În programul de mai sus, constanta a este declarată după directivele preprocesor.
Ea este implicit de tip întreg şi are valoarea 2. Constantele b şi pi sunt declarate la
începutul funcţiei main. Constanta b este de tip întreg şi are valoarea 3, pe când
constanta pi este de tip float şi are valoarea 3.1415;
Nu se permit operaţii de modificare a valoarilor constantelor prin atribuire,
compilatorul semnalând o eroare la compilare.
#include <stdio.h>
const a=2;
void main ()
{
const b=3;
const float pi=3.1415;

a=4; Eroare. Se încearcă modificarea valorii unei
constante
pi=3.14; Eroare. Se încearcă modificarea valorii unei
constante
}

3.3.2. Variabile
Declararea unei variabile în C se face:
tipul_de_data numele_variabilei [=valoare];
Variabilele trebuiesc declarate la începutul funcţiei, sau la începutul fişierului
după directivele preprocesor. Valorile variabilelor pot fi modificate pe parcursul
programului.
LIMBAJUL C TEORIE ŞI APLICAŢI I 37

#include <stdio.h>
int a=2;
void main ()
{
int b=3, c;
float d;
char ch='a';

a=4; Corect. Se modifică valoarea variabilei a.
ch='1'; Corect. Se modifică valoarea variabilei d.
}
Variabilele a, b şi c sunt de tip întreg. Variabila a este declarată la începutul
fişierului după directivele preprocesor şi este iniţializată cu valoarea 2. Variabilele
b şi c sunt declarate la începutul funcţiei main, variabila b este iniţializată cu
valoarea 2, variabila c este neiniţializată. Variabila d este de tip float şi este
neiniţializată. Variabila ch este de tip char şi este iniţializată cu valoarea a.
Să reţinem că operatorul = în C este operatorul de atribuire. Remarcăm că tipului
de dată caracter i se poate atribui o valoare caracter. O valoare caracter în C este
reprezentată prin 'caracter'. In cazul nostru, variabila caracter ch este iniţializată cu
valoarea a.

3.3.2.1. Variabile locale şi globale


Am văzut mai sus că variabilele pot fi declarate fie la începutul fişierului după
directivele preprocesor, fie în interiorul unei funcţii. Variabilele care sunt
declarate în interiorul unei functii (între acolade) se numesc variabile locale.
Variabilele locale pot fi folosite doar în interiorul funcţiei în care au fost declarate.
Variabilele care au fost declarate la începutul fişierului, după directivele
preprocesor, pot fi folosite în toate funcţiile programului. Aceste variabile se
numesc variabile globale.
#include <stdio.h>
void test();
int a=2; Variabila a este globală.
void main ()
{
int b; Variabila b este locală în funcţia void main ().
float pi=3.1415;
test();
}

void test()
{
int c; Variabila c este locală în funcţia test().
c=b*2; Eroare. Variabila b este locală în funcţia void main ().
c=a*2;
}
În programul de mai sus, variabila a este o variabilă globală de tip întreg,
iniţializată cu 2. Variabila b este o variabilă de tip întreg locală în funcţia void
LIMBAJUL C TEORIE ŞI APLICAŢI I 38

main (), variabila de tip float pi este locală în funcţia void main () şi este
iniţializată cu valoarea 3.1415.
Variabila c de tip întreg este locală în funcţia test(). Instrucţiunea c=b*2; va
produce o eroare la compilare pentru că variabila b fiind locală în funcţia void
main () nu poate fi folosită în funcţia test(). Instrucţiunea c=a*2; este corectă
pentru că variabila a este globală.

3.3.2.2. Convenţia de denumire a variabilelor şi constantelor.


Deşi nici chiar părinţii limbajului nu au menţionat de o convenţie de denumire a
variabilelor sau constantelor, în practica modernă de programare se recomandă
folosirea unei convenţii de denumire a acestora pentru a uşura munca
programatorului. In cazul programelor mari, care conţin mii de instrucţiuni, este
necesară respectarea unei ordini privind denumirea variabilelor. De exemplu, dacă
am declarat o variabilă de tip întreg cu numele a, şi undeva în program îi vom
atribui valoarea 3.4, uitând faptul că variabila este de tip întreg, variabila a va
conţine doar 3, adică partea întreagă a valorii. Acest lucru duce la rezultate
eronate în continuare. Autorii recomandă folosirea a unu - trei litere în faţa
numelui unei variabile, pentru a indica tipul de dată a variabilei.
De exemplu
intraza, intcontor semnifică variabile de tip int
flarie, flx1 semnifică variabile de tip float
lnga, lngb semnifică variabile de tip long
dblsuma, dblfx semnifică variabile de tip double
chinitiala, chcod semnifică variabile de tip char
sznume semnifică variabile de tip şir de caractere.
3.4. Funcţii. Introducere
Un program scris în limbajul C este alcătuit din una sau mai multe funcţii. O
funcţie are următoarea structură :
Tip_de_data Nume(Lista declaratiilor parametrilor formali)
{
Declaratii;
Instructiuni;
}
Primul rând reprezintă antetul funcţiei, iar zona dintre parantezele acoladă
reprezintă corpul funcţiei.
În limbajul C funcţiile returnează sau nu o valoare şi în cazul că returnează, tipul
funcţiei este indentic cu tipul valoarei returnate (int, float, double, char), iar în
cazul că nu returnează o valoare tipul funcţiei este void care trebuie indicat, în
cazul că nu este indicat se consideră că funcţia returnează o valoare de tip întreg,
chiar dacă în cadrul funcţiei nu este specificat explicit că returnează o valoare.
O funcţie poate avea zero sau mai mulţi parametrii formali, în cazul că nu are
parametrii formali se va specifica prin cuvântul void sau nu se va scrie nimic între
LIMBAJUL C TEORIE ŞI APLICAŢI I 39

paranteze, în cazul că sunt mai mulţi parametri formali, aceştia sunt separaţi prin
virgulă între ei.
Prin intermediul parametrilor se transferă datele de la apelarea funcţiei în
interiorul funcţiei. Mai jos, sunt prezentate câteva exemple.
void main(void) sau void void main () funcţia principală cu numele main nu
returnează valoare şi nu are parametrii formali.
float factorial (int n) funcţia cu numele factorial returnează o valoare
de tip float şi are un parametru formal cu numele
n de tipul int.
puts ("şir de caractere") funcţii standard de bibliotecă pentru afişarea pe
monitor a şirului de caractere incluse intre " ".
float fxy (int n, float x) funcţia cu numele fxy returnează o valoare de tip
float şi necesită la apelare parametri formali de
tipul int, float.
În cadrul unui program o funcţie are o singură definiţie, dar poate fi apelată de
mai multe ori. Apelarea unei funcţii se efectuează prin numele funcţiei urmat de
lista parametrilor efectivi astfel :
Nume (lista parametrilor efectivi);
Parametrii efectivi pot fi o expresie, un nume de variabilă. Parametrii efectivi
trebuie să corespundă cu parametrii formali ai funcţiei prin ordine şi tip. Dacă
funcţia returnează o valoare ea se apelează ca un operand din cadrul unei expresii.
a=factorial (j); funcţia factorial va returna în variabila a valoarea
rezultată prin calculul funcţiei cu parametrul efectiv j.
Dacă parametrii efectivi sunt nume de tablouri, obligatoriu în antetul funcţiei se
va indica parametrii fictivi ca fiind tablouri.
double a [10];
int n;

citm (n,n,a);

Funcţia citm va avea antetul :
void citm (int n, int m, double []) sau
void citm (int n, int m, double [10])

3.4.1. Funcţii standard de intrare ieşire


Setul de operaţii care permit transferul de date între periferice şi program
formează operaţiile de intrare ieşire, operaţiile de introducere a datelor de la un
periferic se numesc operaţii de citire, iar operaţiile de ieşire a datelor spre un
periferic se numesc operaţii de scriere sau afişare (tipărire).
Limbajul C nu dispune de instrucţiuni specifice operaţiilor de intrare ieşire şi
pentru a realiza aceste operaţii foloseşte funcţii standard de intrare ieşire.
Funcţiile utilizate cel mai frecvent sunt :
getch(), gets(), scanf() pentru citirea darelor de la tastatară,
putch(), puts(), printf() pentru tipărirea datelor pe ecran.
LIMBAJUL C TEORIE ŞI APLICAŢI I 40

Funcţia getch() citeşte de la tastatură caracterul tastei apăsate fără ecou pe


ecranul monitorului, şi returnează codul ASCI I al caracterului. Apelul funcţiei se
face astfel :
getch (); când se doreşte să se apese o tastă pentru
continuarea programului şi vizualizarea ferestrei utilizatorului.
putch (getch ()); când funcţia getch returnează codul ASCII pentru
a fi afişat de funcţia putch.

La apelarea funcţiei getch() dacă se apasă tasta ENTER valoarea returnată este
13.
Funcţia gets() citeşte de la tastatură un şir de caractere terminat prin apăsarea
tastei <Enter>. Funcţia gets() returnează adresa de început a zonei de memorie în
care se păstrează şirul de caractere citite de la tastatură. Citirea se efectuează cu
ecou pe ecranul monitorului. Parametrul funcţiei gets() este adresa unui tablou
unidimensional de tip char (caracter), apelul funcţiei gets() este precedat de o
declaraţie a unui tablou de tip caracter astfel :
char tabel1 [20]; declararea unui tablou cu numele tabel1 de tip
char cu lungimea 20.

gets ( tabel1); citeşte şirul de caractere şi îl transferă la adresa
lui tabel1.
Funcţia scanf() permite citirea datelor de la tastatură respectând un format de
citire, iar apelul funcţiei este de forma :
scanf (control, parametru1, parametru2, …, parametruln);
unde control este un şir de caractere ce definesc formatele de citire a datelor de
intrare, parametrul1, parametrul2, …, sunt adresele la care se păstrează datele
citite.
Specificatorii de format definesc conversiile din formate externe în cele interne şi
încep cu caracterul procent % urmat de 1 sau 2 litere ce definesc formatul astfel :
%c se foloseşte pentru a citi un singur caracter,
char d;
scanf (“%c”,&d ); citeşte caracterul curent şi depozitează codul
ASCII al caracterului citit la adresa variabilei d de tip caracter.
%s se foloseşte pentru a citi un şir de caractere terminat prin caracterul alb
(spaţiu), fie la caracterul prin care se ajunge la lungimea maximă de caractere
specificată de formatul de citire. După ultimul caracter citit se păstrează automat
caractrul NUL.
char text1 [15];
LIMBAJUL C TEORIE ŞI APLICAŢI I 41

scanf (“%s”,&text1); se tastează LABORATOR, şirul de caractere


LABORATOR este citit şi pus la adresa tabloului
text1.

char text1 [4];


char text2 [5];
scanf (“%4s”,&text1);
scanf (“%5s”,&text2); se tastează LABORATOR, şirul de caractere
LABORATOR este citit şi primele 4 caractere
LABO sunt puse la adresa tabloului text1 iar
caracterele RATOR sunt puse la adresa tabloului
text2.

%d se foloseşte pentru a citi valori întregi din domeniul –32768 la +32767, numele
poate fi precedat de semnul minus şi opţional de semnul plus. Funcţia scanf
returnează o valoare întreagă = cu numărul de câmpuri citite corect. Dacă în
specificatorul de format sunt dispuse cifre, ce indică lungimea maximă a
câmpurilor ce se citesc, este indicat să se introducă cu mare atenţie şirul de date
ce urmează a fi citite.
int i;
scanf (“%d”,&i); se citeşte o valoare intreagă şi se stochează la
adresa variabilei i de tip int (intreg).
int l,m,n ; declararea a trei variabile de tip int (intreg).
scanf (“1%d %3d %2d”,&l,&m,&n) ; dacă se tastează 653276 valoarea 6 va fi
păstrată în variabila l, valoarea 532 va fi păstrată
în variabila m iar valoarea 76 va fi păstrată în
variabila n, respectându-se lungimea formatelor
de citire.
Dacă data de intrare este a12345 funcţia scanf nu va citi considerând că este o
eroare, începutul datei începe cu un caracter diferit de cifră şi va returna valoarea
zero.

%o se foloseşte pentru a citi un întreg octal


%x %X se foloseşte pentru a citi un întreg de tip hexazecimal, cifrele hexazecimale
mai mari de 9 se vor reprezenta prin litere mari sau mici.
%u se foloseşte pentru a citi întreg zecimal de tipul unsigned.
%f se foloseşte pentru a citi numerele zecimale cu sau fără exponent şi păstrate în
format flotant simplă precizie, în domeniul modul 3,4∙10-38 3,4∙1038 a datelor de
tip float,
float a1,b; declaraţii de tip float pentru a1 şi b
LIMBAJUL C TEORIE ŞI APLICAŢI I 42

scanf (“%f %f”,&a1,&b); citirea a două valori separate prin caracterul, de


format float şi depozitarea valorilor citite la
adresele lui a1 şi b.
%lf se foloseşte pentru a citi numerele zecimale cu sau fără exponent şi păstrate în
format flotant dublă precizie în domeniul 1,7∙10-308 1,7∙10308 a datelor de tip
double,
double a ; declararea variabilei a de tip double
scanf (“%lf”,&a); citirea unei date reale de tip double, care se
atribuie variabilei a.
%Lf se foloseşte pentru a citi numerele zecimale cu sau fără exponent şi păstrate în
format flotant long double în domeniul 3,4∙10-4932 1,1∙104932.
Funcţia putch() afişează un singur caracter pe monitor şi are ca parametru o
expresie sau o apelare a funcţiei getch(),
putch (getch ()); va afişa caracterul citit de funcţia getch.
Funcţia puts() afişează pe monitor şirul de caractere delimitate de dublu apostrof
sau şirul de caractere din cadrul unui tablou unidimensional.
puts (“\n Apasa o tasta pentru terminarea programului”);
are ca efect trecerea cursorului de afişare pe rând nou datorită caracterelor \n şi
apoi se va afişa şirul de caractere Apasa o tasta pentru terminarea programului.
Funcţia printf() este folosită pentru a afişa sub controlul unui format, datele de
ieşire, folosind apelarea astfel :
printf (control, parametru1, parametru2, …);
unde control este un şir de caractere care indică formatele de afişare şi textul ce
se poate afişa, parametru1, parametru2, …, pot fi expresii sau denumirea
variabilelor a căror valoare se va afişa.
%c se foloseşte pentru a afişa un singur caracter,
char d;
printf (“%c”,d); afişează caracterul stocat la adresa variabilei d,
de tip caracter.
%s se foloseşte pentru a afişa un şir de caractere păstrat într-un tablou,
char text1 [15];
printf (“%s”,text1); se afişează şirul de caractere pus la adresa
tabloului text1.
printf (“%s”,”erton”); se afişează şirul de caractere erton dispuse intre “
“.
Dacă în formatul de tipărire se folosesc valori numerice, care să indice lungimea
zonei de afişare , va afecta astfel tipărirea :
printf (“*%8s*”,”erton”); se afişează între caracterele * * pe un spaţiu de 8
caractere cuvântul erton astfel :
* erton*, dacă valoarea 8 din formatul de tipărire este precedat de caracterul –,
afişarea se va face tot pe un spaţiu de 8 caractere, cuvântul erton este urmat de
spaţiu liber de 3 caractere astfel : *erton *.
LIMBAJUL C TEORIE ŞI APLICAŢI I 43

%d se foloseşte pentru a afişa valori intregi din domeniul –32768 la +32767,


int i;
printf (“%d”,&i); se afişează valoarea intreagă depozitată la adresa
variabilei i de tip int (intreg).
int n,m ;
n=45;
m=30:
printf (“*8d*”,n); se afişează * 45* lungimea zonei este de 8
caractere dispuse cu valoarea aliniată la dreapta.
printf (“*08d*”,n); afişează *00000045* dispunând zerouri în faţa
valorii zerouri până la lungimea indicată.
printf (“*-8d*”,n); afişează *45 * asigurând un spaţiu de 8
caractere cu alinierea la stânga valorii.
%f se foloseşte pentru a afişa numerele zecimale cu sau fără exponent şi păstrate
în format flotant simplă precizie, în domeniul modul 3,4∙10-38 3,4∙1038 a datelor
de tip float. Numărul zecimalelor afişate implicit este 6, dacă în specificatorul de
format se specifică mărimea cîmpului aceasta devine prioritară. Dacă numărul de
zecimale specificate în format este mai mic decât numărul de zecimale calculate,
se va rotunji valoarea.
float a1,b; declaraţii de tip float pentru variabilele a1 şi b
printf(“%f %f”,&a1,&b); afişarea a două valori de format float şi
depozitate la adresele lui a1 şi b.
float a1,b;
a1=23;
b=43.56;
c=43.34;
printf(“%f %f %f”,&a1,&b,&c); se afişează cele 3 valori cu un număr de 6
zecimale (număr de zecimale implicit) astfel :
23.000000 43.560000 43.340000
printf(“%5.1f %6.2f %6.1f”,&a1,&b,&c);
se afişează pe un câmp de 5 caractere valoarea lui a1 cu 1 zecimală astfel :
23.0
valoarea b se va afişa pe un câmp de 6 caractere cu spaţiu de 2 caractere pentru
zecimale astfel : 43.56 iar pentru valoarea c se va afişa pe un spaţiu de 6
caractere o singură zecimală, prin rotunjirea valorii astfel : 43.3 alinierea
valorilor afişate este la dreapta pentru lungimea câmpului rezervat.

%lf se foloseşte pentru a afişa numerele zecimale cu sau fără exponent şi


păstrate în format flotant dublă precizie în domeniul 1,7∙10-308 1,7∙10308 a datelor
de tip double,
double a; declararea variabilei a de tip double
printf (“%lf”,&a); afişarea valori variabilei a de tip double.

%Lf sefoloseşte pentru a afişa numerele zecimale cu sau fără exponent şi păstrate
în format flotant long double în domeniul 3,4∙10-4932 1,1∙10 4932 .
LIMBAJUL C TEORIE ŞI APLICAŢI I 44

float ar;

printf (“aria=%f\n”,ar); va afişa textul aria= urmată de valoarea variabilei
ar şi apoi trecerea pe rând nou datorită caracterelor speciale \n .
Pentru a dispune valorile pe câmpuri separate printr-un spaţiu de 8 caractere (tab),
în specificatorul de format se vor folosi caracterele
float a1,b;
a1=23;
b=43.56;
c=43.34; de indicare a lui tab astfel \t.
printf(“%f\t%f\t%f”,&a1,&b,&c); se afişează cele 3 valori cu un număr de 6
zecimale (număr de zecimale implicit) astfel :
23.000000 43.560000 43.340000
%e sau %E se foloseşte pentru a afişa numerele zecimale de tip float sau double
spre formatul cu parte întreagă.parte fracţională exponent. Numărul zecimalelor
afişate depinde de specificatorul de format, dacă precizia nu este specificată, se
vor afişa 6 zecimale ( a se vedea exemplele de la % f).
Exponentul va avea caracterul e sau E dispus în faţa funcţie de caracterul
specificat în format :
float a =4.123456, b=23.45, c=0.45;
printf (“a=%e b=%e c=%E ”,a,b,c );
va afişa :
a=4.123456e+00 b=2.345e+01 c=4.5E-01.
%g sau %G se foloseşte pentru a afişa numerele zecimale cu sau fără exponent
fie ca în cazul specificatorului de format %f fie ca în cazul specificatorului de
format %e în funcţie de mărimea valori astfel ca afişarea să ocupe un număr
minim de caractere. Specificatorul de format %g sau %G va afişa maxim 6
zecimale dacă acestea sunt semnificative.
float a=123.45678, b=23.45;
printf (“a=%g b=%g ”,a, b);
va afişa
a=1.234568e+03 b=23.45.
Datele de tip float au o precizie de 7 zecimale iar datele de tip double au o precizie
de 15 zecimale. Funcţiile de intrare ieşire au prototipurile în fişierele stdio.h şi
conio.h care trebuie incluse în fiecare fişier sursă .
%o datele de tip intreg (int) sau datele de tip intreg fără semn (unsigned) sunt
convertite în octal şi apoi sunt afişate sub specificatorul de format :
printf (“++%6o++”.123); va afişa pe un câmp de 6 caractere valoarea 123
convertită în octal=173 astfel : ++ 173++ , caracterele ++ au fost puse pentru a
se delimita lungimea câmpului afişat.
LIMBAJUL C TEORIE ŞI APLICAŢI I 45

%x sau %X este folosit pentru a converti datele de tip int sau unsigned în
hexazecimal şi apoi folosind specificatorul de format le va afişa. Specificatorul
%x va afişa cifrele mai mari de 9 cu caractere minuscule, iar %X va afişa cu
caractere majuscule.
printf (“%5x\t%x”,124,124); va afişa pe un câmp de 5 caractere : 7c
urmat de un spaţiu de 1 tab apoi afişarea cu caractere majuscule a valorii mai
mare decât 9 astfel 7C
%u este folosită pentru a afişa o dată de tip unsigned în zecimal.
%l poate precede caracterele d, o, x, X, u pentru a converti datele din long în
long unsigned astfel :
%ld converteşte data de tip long în zecimal
%lu converteşte din long unsigned în zecimal
%lo converteşte din long sau long unsigned în octal
%lx converteşte din long sau long unsigned în octal.
#include<stdio.h>
#include<conio.h>
void main ()
{
int a,d; declarare de variabilă de tip întreg max 32767
unsigned b; declarare de variabilă de tip fără semn 65535
long c; declarare de variabilă intreagă long max
2147483647
d=scanf ("%u,%d,%ld",&b,&a,&c); citirea a trei valori: unsigned, intreg, intreg
long.
printf ("unsigned %u int %d long %ld\n",b,a,c);afişarea celor trei valori citite.

}
Dacă se introduc valorile 65535, 32767, 3456789, ce se află în
Domeniul fiecărei tip de variabilă, aceste date vor fi citite corect şi apoi afişate
corect. Dacă se introduc valorile -234, 33000, 234567se va observa că data
–234 nu va fi citită fincă are semnul minus, iar adoua valoare 33000 nu este
citită, fincă valoarea depăşeşte domeniul variabilei de tip intreg.
Se recomandă ca funcţie de domeniul valorilor variabilelor folosite, s-ă se
aleagă tipul variabilei.

3.5. Instrucţiuni. Expresii. Operatori


3.5.1. Instrucţiuni.
Prelucrarea datelor de intrare, de ieşire, sau din interiorul programului se
realizează cu ajutorul instrucţiunilor. Ordinea de efectuare a acestor
instrucţiuni depinde de structura de control a programului. Structura de control
LIMBAJUL C TEORIE ŞI APLICAŢI I 46

a programului poate fi :
 Structura secvenţială.
 Structură alternativă.
 Structură ciclică condiţionată anterior.
 Structură selectivă.
 Structură ciclică condiţionată posterior.

3.5.1.1. Instrucţiunea vidă.


Instrucţiunea vidă se realizează prin caracterul; şi este folosită unde se cere
prezenţa unei instrucţiuni fără efect, în cadrul structurilor ciclice sau alternative.

3.5.1.2. Instrucţiunea expresie.


Instrucţiunea expresie are forma :
expresie;
În funcţie de tipul expresiei instrucţiunea expresie se numeşte de atribuire sau de
apel.
A=5; este o instrucţiune de atribuire şi are ca efect
atribuirea valorii 5 variabilei A.
B[2]=2.5; este o instrucţiune de atribuire şi are ca efect
atribuirea valorii 2,5 variabilei indexate B[2].
X=X+2; este o instrucţiune de atribuire şi are ca efect
mărirea valorii lui X cu 2.
puts (“Dati o valoare”); este o instrucţiune de apel a funcţiei puts.
I++; este o instrucţiune expresie şi măreşte valoarea lui
I cu o unitate.
J--; este o instrucţiune expresie şi micşorează
valoarea lui J cu o unitate.

3.5.1.3. Instrucţiunea compusă.


Instrucţiunea compusă se realizează prin includerea mai multor instrucţiuni şi
declaraţii între două acolade deschis inchis.

{
declaratii;
instructiuni;
}
Declaraţiile din cadrul unei instrucţiuni compuse au efect numai asupra
variabilelor declarate de ele şi numai in efectuarea instrucţiunii compusă.
Instrucţiunea compusă se foloseşte în cadrul structurilor ciclice sau alternative.

LIMBAJUL C TEORIE ŞI APLICAŢI I 47

{
puts (“ dati valoarea elementului”);
s canf (“%d”, &a[i]);
}

3.5.1.4. Instrucţiunea de atribuire.


Am amintit în capitolul “Tipuri de date. Constante şi variabile” despre operatorul
=. Operatorul = este operatorul de atribuire. Instrucţiunea în care apare operatorul
de atribuire se numeşte instrucţiune de atribuire. Sintaxa instrucţiunii de atribuire
este:
nume_variabila = expresie;
Termenul stâng al instrucţiunii de atribuire nu poate fi decât o variabilă. Dacă în
partea stângă a operatorului nu se găseşte o variabilă, compilatorul va semnala o
eroare la compilare Lvalue required.
Termenul drept al instrucţiunii de atribuire este o expresie. O expresie este un
grup de variabile şi constante legate între ele prin operatori matematici (adunare,
scădere, etc.).
În momentul rulării programului, instrucţiunea de atribuire este rezolvată în doi
paşi. Primul pas, constă în evaluarea expresiei din dreapta operatorului atribuire.
Rezultatul obţinut este atribuit variabilei din stânga operatorului.
#include <stdio.h>
void main ()
{
int i;
double d;
printf("Program care dubleaza valorile a 2 variabile");
printf("\nTastati un intreg si un real:");
scanf("%d %lf", &i, &d);
i=i*2;
d=d*2;
printf("\nDublul numarului intreg este: %d", i);
printf("\nDublul numarului real este: %f", d);
}
Dacă cele două numere au fost 5 şi 4.7, programul va produce pe ecran următorul
rezultat:
Dublul numarului intreg este: 10
Dublul numarului real este: 9.400000

3.5.2. Operatori.
Am amintit mai sus că o expresie este un grup de variabile şi constante legate
între ele prin operatori. Termenii care intervin într-o expresie se mai numesc şi
operanzi. Limbajul C pune la dispoziţia utilizatorului un mare număr de operatori.
Vom prezenta în continuare principalele grupe de operatori
LIMBAJUL C TEORIE ŞI APLICAŢI I 48

3.5.2.1. Operatori aritmetici.


In C, avem următorii operatori aritmetici:
- minus unar
+ plus unar
* înmulţire
/ împărţire
% restul împărţirii întregi
+ adunare
- scădere
Exemplu
Să se scrie programul C care calculează ecuaţia de gradul I (vezi organigrama de
la Algoritmi liniari). Coeficienţii a şi b sunt întregi.
Rezolvare
Chiar dacă coeficienţii a şi b sunt întregi, soluţia x a ecuaţiei poate fi reală, astfel
vom declara variabila x de tip float.
#include <stdio.h>
void main ()
{
int a, b;
float x;
printf("Program care rezolva ecuatia de gradul I ax+b=0");
printf("\nDati coeficientii intregi a si b ");
scanf("%d %d", &a, &b);
x=-b/a;
printf("Solutia ecuatiei %dx+%d=0 este: %f", a, b, x);
}
Dacă la mesajul Dati coeficientii intregi a si b, vom tasta 2 şi 3, programul
va produce pe ecran următorul rezultat:
Solutia ecuatiei 2x+3=0 este: -1.000000
Observăm că soluţia este incorectă. Problema constă în instrucţiunea de atribuire
x=-b/a;. Expresia din partea dreaptă a operatorului de atribuire, care este evaluată
prima, conţine doi operanzi de tip întreg şi doi operatori minus unar şi împărţire.
Pentru că toţi operanzii expresiei sunt de tip întreg, programul va evalua expresia
şi va atribui un întreg variabilei din stânga, adică x. Rezultatul întreg este obţinut
prin trunchiere (adică eliminarea zecimalelor). Pentru ca programul să atribuie
variabilei din stânga o valoare de tip real (float), trebuie ca unul din termenii
expresiei să fie de tip float. Nu putem să schimbăm tipul de dată al variabilelor a
şi b, pentru că în enunţ s-a cerut ca a şi b să fie întregi.
LIMBAJUL C TEORIE ŞI APLICAŢI I 49

3.5.2.2. Typecasting.
Din fericire, limbajul C permite schimbarea tipului de dată a unei variabile într-o
expresie cu ajutorul operatorului typecast. Operatorul typecast este folosit sub
forma:
(tip de data)nume_de_variabila
De reţinut faptul că tipul de dată al varibilei nu este schimbat în program, ci doar
valoarea variabilei în expresia în care apare operatorul typecast este modificată la
tipul tip de dată. Astfel încât problema corect rezolvată este:
#include <stdio.h>
void main ()
{
int a, b;
float x;
printf("Program care rezolva ecuatia de gradul I ax+b=0");
printf("\nDati coeficientii intregi a si b ");
scanf("%d %d", &a, &b);
x=-(float)b/a;
printf("Solutia ecuatiei %dx+%d=0 este: %f", a, b, x);
}
Observăm că în expresia -b/a am folosit operatorul typecast, transformând-o sub
forma -(float)b/a. Pentru că operatorul typecast (float) este în faţa variabilei b,
programul va considera valoarea lui b de tip float, astfel unul din operanzii din
expresie este de tip float şi rezultatul returnat în urma evaluării expresiei este
float. Remarcăm în plus că tipul de dată al variabilei b nu a fost schimbat, pentru
că instrucţiunea
printf("Solutia ecuatiei %dx+%d=0 este: %f", a, b, x);
foloseşte specificatorul de format %d pentru a tipări valoarea variabilei b, care produce
rezultatul aşteptat pe ecran:
Solutia ecuatiei 2x+3=0 este: -1.500000

3.5.2.3. Operatori relaţionali.


In limbajul C operatorii relaţionali sunt:
< mai mic
<= mai mic sau egal
> mai mare
>= mai mare sau egal
== egal
!= diferit
Vom aminti aici un operator care nu poate fi clasificat în nici o grupă, dar care
este foarte interesant, el nefiind prezent în nici unul din celelalte limbaje clasice
de programare, şi anume operatorul decizie. Operatorul decizie ?, este folosit
pentru a selecta din două expresii, doar una, în funcţie de o condiţie impusă în
stânga operatorului. Sintaxa folosirii operatorului expresie este:
nume_de_variabila = conditie ? expresie1 : expresie2;
LIMBAJUL C TEORIE ŞI APLICAŢI I 50

Dacă condiţia este adevărată, valoarea expresiei 1 este atribuită variabilei. Dacă
condiţia nu este adevărată (falsă), valoarea expresiei 2 este atribuită variabilei.
Exemplu
Sa se scrie programul C care citeşte un număr întreg de la tastatură şi afişează
mesajul Numarul este p, dacă numărul este par, sau Numarul este i, dacă numărul
este impar, folosind doar operatorii aritmetici şi decizie.
Rezolvare
#include <stdio.h>
void main ()
{
int a, b;
char ip;
printf("Tastati un intreg");
scanf("%d", &a);
b=a%2;
ip= b==0 ? 'p':'i';
printf("Numarul este %c", ip);
}
Am folosit doi dintre operatorii prezentaţi mai sus. In instrucţiunea de atribuire
b=a%2;, b va avea valoarea 0 dacă a este par şi 1 dacă a este impar, pentru că
operatorul % returnează restul împărţirii lui a la 2.
În expresia din următoarea instrucţiune de atribuire b==0 ? 'p':'i'; condiţia este b
egal cu zero. Dacă b este egal cu zero, variabilei ip din stânga operatorului de
atribuire i se va atribui expresia 'p' (adică ip='p'). Dacă b nu este egal cu zero
(condiţia nu este adevărată), variabilei ip i se va atribui expresia 'i' (adică ip='i'). În
final, programul va afişa pe ecran:
Numarul este i
dacă valoarea variabilei a este impară.
Exemplu
Să se scrie programul C care citeşte două numere reale de la tastatură şi compară
cele două numere folosind operatorul decizie. Programul să afişeze Numărul a >
b, dacă a este mai mare decât b, sau Numarul a < b, dacă a este mai mic decât b.
Rezolvare
#include <stdio.h>
void main ()
{
float a, b;
char op;
printf("Tastati doua numere reale");
scanf("%f %f", &a, &b);
op= a>b ? '>':'<';
printf("Numarul %f %c %f", a, op, b);
}
Să remarcăm instrucţiunea de atribuire op= a>b ? '>':'<';. Condiţia este a>b. Dacă
condiţia este adevărată, variabila op de tip caracter va primi valoarea '>'. Dacă
condiţia este falsă, variabila op va primi valoarea '<'. Dacă a este 3.5 şi b este 4.2,
programul va afişa pe ecran mesajul:
LIMBAJUL C TEORIE ŞI APLICAŢI I 51

Numarul 3.500000 < 4.200000

3.5.2.4. Operatorii logici.


In limbajul C există trei operatori logici:
! negare
&& şi logic
|| sau logic
Operatorul negare produce următorul rezultat:
dacă operandul are o valoare diferită de 0, rezultatul este 0, altfel rezultatul
operaţiei este 1.
Operatorul sau logic produce următorul rezultat:
dacă cel puţin unul din operanzi are o valoare diferită de 0, rezultatul este 1, altfel
este 0.
Operatorul şi logic produce următorul rezultat:
dacă ambii operanzi sunt diferiţi de 0, rezultatul este 1, altfel rezultatul operaţiei
este 0.
Exemplu
Să se scrie programul C care citeşte două numere întregi de la tastatură şi verifică
dacă ambele numere sunt pare. Dacă ambele numere sunt pare programul afişează
mesajul: Numerele sunt pare: d. In celelalte cazuri programul va afişa: Numerele
sunt pare: n. Verificarea numerelor se va face folosind doar operatori.
#include <stdio.h>
void main ()
{
int a, b;
int p1, p2;
char pp;
printf("\nProgram care verifica daca 2 numere intregi sunt pare");
printf("\nDati 2 numere intregi");
scanf("%d %d", &a, &b);
p1= a%2 ? 0 : 1;
p2= b%2 ? 0 : 1;
pp= p1 && p2 ? 'd' : 'n';
printf("Ambele numere sunt pare: %c", pp);
}

3.5.2.5. Operatorii de incrementare şi decrementare.


Sunt folosiţi pentru a aduna 1 sau pentru a scădea 1 la valoarea unei variabile de
tip întreg. Sintaxa operatorilor de incrementare ++, sau decrementare -- este:
variabila++
variabila--
Dacă operatorul de incrementare, decrementare apare în urma numelui variabilei,
vom spune că operaţia de incrementare/decrementare este postfixată. Dacă
operatorul de incrementare sau decrementare apare în faţa variabilei
++variabila
LIMBAJUL C TEORIE ŞI APLICAŢI I 52

--variabila
vom spune că operaţia de incrementare/decrementare este prefixată. Dacă operaţia
de incrementare/decrementare prefixată este folosită într-o expresie, întâi se
incrementează/decrementează valoarea variabilei, noua valoare fiind folosită în
expresie.
Dacă operaţia de incrementare/decrementare postfixată este folosită într-o
expresie, întâi se evaluează expresia cu valoarea variabilei
neincrementată/nedecrementată şi apoi se incrementează/decrementează valoarea
variabilei.
#include <stdio.h>
void main ()
{
int a, b;
a=3;
b=++a;
printf("\nIncrementare prefix a=%d, b=%d", a, b);
a=3;
b=a++;
printf("\nIncrementare postfix a=%d, b=%d", a, b);
a=3;
b=--a;
printf("\nDecrementare prefix a=%d, b=%d", a, b);
a=3;
b=a--;
printf("\nDecrementare postfix a=%d, b=%d", a, b);
}
Programul va produce următorul rezultat pe ecran:
Incrementare prefix a=4, b=4
Incrementare postfix a=4, b=3
Decrementare prefix a=2, b=2
Decrementare postfix a=2, b=3
Înainte de fiecare instrucţiune de tipărire, variabila întreagă a are valoarea 3.
Variabila a este folosită în câte o instrucţiune de atribuire, aplicând asupra
variabilei operatorii de incrementare prefix/postfix şi de decrementare
prefix/postfix.
În toate cazurile, valoarea variabilei a este incrementată sau decrementată de către
operatori. După incrementare, variabila a va avea valoarea 4, respectiv 2 după
decrementare.
În expresii, folosind operatorul prefix, variabila b va primi valoarea
incrementată/decrementată a variabilei a, pe când folosind operatorul postfix,
variabila b va primi valoarea variabilei a neincrementată/nedecrementată.

3.5.3. Instrucţiunea if.


Instrucţiunea if se foloseşte la realizarea structurilor alternative şi are următoarele
forme de scriere :
LIMBAJUL C TEORIE ŞI APLICAŢI I 53

Forma 1
if (expresie)
instructiunea 1;
else
instructiunea 2;
instructiunea 3;
Se evaluează expresia din parantezele de după if şi dacă această expresie este
adevărată (are valoarea diferită de zero) se va efectua instrucţiunea 1, apoi se va
continua programul cu unstrucţiunea 3 dinafara instrucăiuni if. Dacă valoarea
expresiei din parantezele de după if este falsă (are valoarea zero) se va efectua
instrucţiunea 2 şi se va continua cu instrucţiunea 3.
Instrucţiunile 1 sau 2 pot fi instrucţiuni simple sau compuse sau chiar o nouă
instrucţiune de tip if, în acest ultim caz se consideră instrucţiunile if imbricate.
Forma 2
se evaluează expresia şi dacă aceasta este adevărată, se execută instrucţiunea 1, iar
dacă expresia este falsă, se va executa expresia 2 dinafara instrucţiunii if.
if (expresie)
instructiunea 1;
instructiunea 2;

Exemplu
Să se calculeze f(x) =4x2+7 pentru x<0 , f(x)=3x2-1 pentru x>=0.
Rezolvare
#include <conio.h> includerea fişierelor ce conţin funcţiilor pentru
#include <stdio.h> citirea şi afişarea datelor.
#include <math.h> includerea fişierului ce conţine funcţiile
matematice.
void main () funcţia principală
{
float x,fx; declaraţii de variabile de tip real simplă precizie

puts ("Dati marimea lui x"); instrucţiune de apelare a funcţiei de afişare a


mesajului Dati marimea lui x

scanf ("%f",&x); instrucţiune de apelare a funcţiei de citire a lui x


cu formatul de citire de tip intreg

if (x<0) începutul instrucţiunii if şi x<0 expresia de


condiţionare (decizie)

fx = 4*x*x+7; dacă expresia de conditionare (decizie) este


adevărată, se execută instrucţiunea 1 din cadrul lui
if, care este în acest caz o instrucţiune de atribuire
else
LIMBAJUL C TEORIE ŞI APLICAŢI I 54

eticheta ce delimitează instrucţiunea 1 de


instrucţiunea 2 a instrucţiunii if

fx=3*x*x-1; dacă expresia de conditionare (decizie) este falsă,


se execută instrucţiunea 2 din cadrul lui if, care
este în acest caz o instrucţiune de atribuire

printf ("f(x)=%f\n",fx); instrucţiunea 3, de după instrucţiunea if cu rolul


de apelare a funcţiei de tipărire cu format de tip
real simplă precizie pentru valoarea variabilei fx,
\n are rolul să indice trecerea la rând nou

puts ("Apasa o tasta"); instrucţiune de apelare a funcţiei de afişare a


mesajului Apasa o tasta

getch (); instrucţiune de apelare a funcţiei de citire a unui


caracter fără ecou, în acest caz folosită pentru
oprirea temporară a execuţiei, până la apăsarea
unei taste, co scopul de a păstra ecranul
utilizatorului pentru citirea datelor afişate
}

Exemplu
În exemplul de mai jos este folosită instrucţiunea if în varianta II, fără
folosirea explicită a instrucţiunii 2 din corpul ei.
Să se determine f(x)=x+4 pentru x<0, f(x)=x2 pentru x>=0.
Rezolvare
#include <stdio.h> includerea fişierelor ce conţin funcţiilor pentru
#include <conio.h> citirea şi afişarea datelor.
void void main ()
{
float x,fx;
puts ("se calculeaza fx =");
puts ( "dati valoarea lui x ");
scanf ("%f",&x); citirea valorii de tip real simplă precizie a lui x şi
dispunerea valorii citite la adresa lui x

if (x<0) începutul instrucţiunii if şi x<0 expresia de


condiţionare, dacă x<0 se va executa instrucţiunea
compusă 1, dacă nu se va sări peste instrucţiunea
LIMBAJUL C TEORIE ŞI APLICAŢI I 55

compusă 1 şi se continuă execuţia cu instrucţiunea


de după instrucţiunea if

{ începutul instrucţiunii 1compuse


fx=x+4;
printf ("f(x)=%f\n",fx);
goto salt1; salt necondiţionat la eticheta salt 1
} sfârşitul instrucţiunii compuse 1

fx=x*x; instrucţiunea de după instrucţiunea if


printf ("f(x)=%f \n",fx);
salt1: eticheta la care se sare datorită instrucţiunii goto
puts ("apasa o tasta ");
getch ();
}

Exemplu
Să se calculeze aria unui cerc dacă raza cercului este mai mare decât zero.
#include <conio.h>
#include <math.h>
#include <stdio.h>
void main () funcţia principală
{
float r,a,pi; declaraţii de variabile de tip real simplă precizi,
separarea variabilelor din listă prin caracterul ,

puts ("dati raza cercului"); instrucţiune de apelare a funcţiei de afişare a


şirului de caractere (mesajul), daţi raza cercului

scanf ("%f" ,&r); instrucţiune de apelare a funcţiei de citire cu


format de tip real , pentru citirea datei r şi
dispunerea valorii citite la adresa lui r

if (r>0) inceputul instrucţiunii if şi r>0 expresia de


condiţionare, dacă expresia r>0 este adevărată se
va executa instrucţiunea compusă 1, în caz contrar
se va continua execuţia cu instrucţiunea 2

{ începutul instrucţiunii compusă 1

pi=3.14156; instrucţiune de atribuire


a=pi*r*r; instrucţiune de atribuire
printf("aria cerc=%f",a);instrucţiune de apelare a funcţiei de tipărire

} sfârşitul instrucţiunii compuse 1


else
LIMBAJUL C TEORIE ŞI APLICAŢI I 56

puts (“Raza este <=0”); instrucţiunea 2 din cadrul instrucţiunii if, de


apelare a funcţiei puts(), pentru afişarea şirului de
caractere dispus între dublu apostroafe

puts ("apasa o tasta"); instrucţiunea 3 din afara instrucţiunii if, de apelare


a funcţiei puts(),pentru afişarea şirului de
caractere dispus între dublu apostroafe

getch(); instrucţiune de apelare a funcţiei de citire a unui


caracter, în cazul de faţă cu rolul de a păstra
ecranul utilizatorului până la apăsarea unei taste

} închiderea corpului funcţiei principale void main


()
Exemplu
Să se calculeze f(x)=4x2+7 pentru x<0, f(x)=4 pentru x=0, f(x)=3x2-1 pentru
x>=0.
Rezolvare
Pentru a calcula f(x) pe cele 3 domenii se va folosi instrucţiunea if de două ori,
una inclusă în alta de tip if imbricat, astfel :
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main ()
{
float x,fx;
puts ("dati marimea lui x");
scanf ("%f",&x);
if (x<0)
fx = 4*x*x+7;
else
if ( x==0) if imbricat
fx=4;
else
fx=3*x*x-1;
printf ("f(x)=%f\n",fx);
puts ("apasa o tasta");
getch ();
}
La execuţia programului, după citirea valorii ce este atribuiă variabilei x,
instrucţiunea if va evalua expresia x<0 . Să considerăm că s-a citit pentru x o
valoare negativă x=-2, după evaluarea expresiei x<0 -2<0, adevărat, se va
continua execuţia cu instrucţiunea 1 a primului if fx = 4*x*x+7, apoi se va
continua cu instrucţiunea 3 dinafara instrucţiunii 1 if, care va afişa valoarea
lui f(x). Să considerăm că valoarea citită de la tastatură pentru x este 0, în
acest caz instrucţiunea 1 if, după evaluarea expresiei x<0 0<0 fals, ce are ca
LIMBAJUL C TEORIE ŞI APLICAŢI I 57

efect continuarea execuţiei cu instrucţiunea 2 din cadrul instrucţiunii1 if, dar


instrucţiunea 2 este tot o instrucţiune if, care va evalua expresia din cadrul ei.
Evaluarea expresiei x==0 (x indentic zero şi nu x=zero) rezultă adevărat şi se
execută instrucţiunea 1 din cadrul instrucţiunii 2 if, fx=4, se continuă cu
instrucţiunea 3 care este aceeaşi cu instrucţiunea 3 de la instrucţiunea 1 if.
Să considerăm că valoarea citită pentru x este 3, în acest caz instrucţiunea 1 if,
după evaluarea expresiei x<0 3<0 fals, ce are ca efect continuarea execuţiei
cu instrucţiunea 2 din cadrul instrucţiunii1 if, dar instrucţiunea 2 este tot o
instrucţiune if, care va evalua expresia din cadrul ei.
Evaluarea expresiei x==0 3==0 (x indentic zero şi nu x=zero) rezultă fals şi se
execută instrucţiunea 2 din cadrul instrucţiunii 2 if, fx=3*x*x-1, se continuă
cu instrucţiunea 3 care este aceeaş cu instrucţiunea 3 de la instrucţiunea 1 if.
Aceste două instrucţiuni if dispuse una în alta, se numesc instrucţiuni if
imbricate.

Exemplu
Să se calculeze x=-b/a, rădăcina ecuaţiei de forma ax+b=0 (dacă a este
diferit de zero). Dacă a este zero se va afişa mesajul nedeterminare dacă b
egal zero se va afişa mesajul solutia este x=0, dacă b este diferit de zero se va
calcula valoarea lui x şi se va afişa această valoare.
Rezolvare
#include<stdio.h>;
#include<conio.h>;
void main ()
{
float x,a,b;
puts("se calculeaza radacina ecuatiei ax+b=0");
puts("dati pe a, b");
scanf("%f,%f",&a,&b); apelarea funcţiei de citire de la tastatură cu
formatul de tip rel simplă precizie a două
valori separate prin caracterul virgulă
if(a != 0) instrucţiunea if evaluează expresia a!= 0
( a este diferit de zero) şi dacă aceasta este
adevărată se va executa instrucţiunea 1 din
cadrul lui if
{ începutul corpului instrucţiunii compuse 1
x=-b/a;
printf ("a=%f b=%f x=%f \n",a,b,x);
} terminarea corpului instrucţiunii compuse 1
else
if (b==0)
puts ("ecuatie nedeterminata");
LIMBAJUL C TEORIE ŞI APLICAŢI I 58

else
puts ("ecuatia nu are solutie");
puts("apasati o tasta");
getch();
}
Probleme propuse
1. Să se determine aria unui triunghi când se dau cele 3 laturi: a, b, c. Ca cele 3
valori date să formeze un triunghi trebuie să se respecte condiţiile:
cele 3 numere > 0
între numerele a, b, c, să existe relaţiile:
a > b+c
b > c+d
c > a+b
a b c
Aria = p p a p b p c , unde p =
2

2. Să se determine cantitatea de căldură necesară topirii unei cantităţi de gheaţă cu


masa m de la temperatura t1 până la temperatura t2.
Condiţii: t1 < 0 şi t2 > 0
Q = Q1 + Q2 + Q3
Q1 = c g 0 t1 m
Q2 = c m
Q3 = m c a t 2
cg = căldura specifică gheţii
c = căldura latentă de topire a gheţii
ca = căldura specifică a apei
Date de intrare : t1, t2, m
Date de ieşire : Q
3. Să se determine alungirea sau scurtarea unui tirant, folosind formula
l F l / EA .
unde
A = aria secţiunii transversale [cm2]
l = lungimea tirantului [cm]
E = modulul de elasticitate [daN/cm2]
F = forţa ce acţionează [daN] (Dacă F < 0 compresiune, altfel întindere)
Date de intrare : A, l, E, F.
Date de ieşire : l
4. Să se determine valoarea lui F(x):
LIMBAJUL C TEORIE ŞI APLICAŢI I 59

x3 3 x 0
F x x x 1 x 1
2
x 4 x 1
Date de intrare : x
Date de ieşire : F(x)
5. Să se citească o valoare de la tastatură şi să se verifice dacă valoarea citită este
un număr. Dacă valoarea este un număr să se afişeze numărul, în caz contrar să se
afişeze mesajul valoarea introdusă nu este un număr.
6. Să se determine soluţiile x şi y ale sistemului:
ax + by = c
dx + ey = f
Sistemul este compatibil dacă: a e b d 0
Date de intrare : a, b, c, d, e, f
Date de ieşire : x, y
7. Să se calculeze aranjamente de x luate câte y.
Date de intrare : x, y
Date de ieşire: Axy
8. Să se calculeze numărul de combinaţii a x luate câte y.
Date de intrare : x, y
Date de ieşire : Cxy
Condiţii : x > 1, y < x, y > 1

3.5.4. Instrucţiunea for.


Instrucţiunea for se utilizează pentru realizarea structurilor ciclice condiţionate
anterior. Sintaxa instrucţiunii for este :
for (expresie1; expresie2; expresie3)
Instructiune simpla sau compusa;
Expresia 1 are rolul de a iniţializa variabila ciclului for, expresia 2 are rolul de a
condiţiona continuarea ciclului for, iar expresia 3 are rolul de a reiniţializa variabila de
contor. Instrucţiunea for se execută astfel :
1. se evaluează expresia 1 şi valoarea acestei expresi devine valoarea de început
a variabilei de contor din ciclul for.
2. se evaluează expresia 2 şi dacă este adevărată se execută instrucţiunea care
este în corpul lui for, dacă expresia 2 este falsă se părăseşte ciclul for şi se
trece la următoarea instrucţiune.
3. după executarea pasului 2 se execută expresia 3 de modificare a valorii
variabilei de contoar şi se reia pasul 2.
LIMBAJUL C TEORIE ŞI APLICAŢI I 60

Instrucţiunea for nu se execută niciodată dacă expresia 2 are valoarea zero de la


început.
Dacă imediat după antetul instrucţiunii for se pune ; instrucţiunea for va efectua
instrucţiunea vidă până când condiţia din expresia 2 este adevărată având rolul
doar de întârziere a efectuări programului.
Exemplu
Adunarea numerelor naturale de la zero la numarul n citit de la tastatură
s=1+2+3+4+…….+n-1
Rezolvare
Pentru a realiza această sumă se va executa repetat instrucţiunea compusă :
{
s=s+i;
i=i+1;
}
Iniţial s=0 şi i=0, şi se repetă instrucţiunea
{
s=s+i;
i=i+1;
}
până când i<n .
Însumarea se poate executa folosind instrucţiunea for astfel :
s=0; i=0;
for (i=0;i<n; i=i+1) Expresia1 i=0 iniţializează variabila contor i cu
valoarea 0; expresia2 i<n este condiţia de execuţie a
ciclului for; expresia3 i=i+1 este expresia de
reiniţializare cu o unitate a variabilei contor .
s=s+i;

#include <conio.h> includerea fişierelor ce conţin funcţiile de intrare


ieşire
#include <stdio.h>
void main ()
{
int i,n,s; declararea variabilelor i, n, s de tip intreg

puts ("s =1+2+3+4+…..n-1?"); apelarea funcţiei de afişare a şirului de caractere


dispus între ghilimele duble
puts ("dati pe n mai mara decât zero =?");

scanf ("%d",&n); apelarea funcţiei de citire cu format de tip


intreg a unei date de la tastatură şi dispunerea
valorii citite la adresa lui n

if (n<=0) condiţionarea datei de intrare prin folosirea


instrucţiunii if
LIMBAJUL C TEORIE ŞI APLICAŢI I 61

puts ("n a fost dat gresit");instrucţiunea 1 din corpul lui if


else
{ instrucţiunea compusă 2 din corpul
instrucţiunii if

s=0; iniţializarea sumei cu zero

for (i=1;i<n;i=i+1) antetul instrucţiunii for, prin care se


iniţializează variabila de contor cu valoarea 1,
apoi expresia de control a ciclului for i<n şi
expresia de reiniţializare a variabilei de contor
i=i+1

s=s+i; instrucţiunea de atribuire pentru calculul


sumei s=1+2+3+……+n

printf("suma = %d\n",s); apelarea funcţiei de tipărire cu format pentru


afişarea sumei şi salt la rând nou prin folosirea
caracterelor \n

puts ("apasa o tasta"); apelarea funcţiei de afişare a şirului de


caractere

getch (); apelarea funcţiei de citire a unui caracter de la


tastatură
} închiderea corpului funcţiei principale main

La pornirea programului se citeşte de la tastatură numărul de termeni n-1 ai sumei,


valoarea citită este dispusă la adresa lui n. Să considerăm că valoarea citită a lui n este
5. Variabila s este iniţializată cu valoarea zero, se iniţializează variabila de contor i a
lui for cu valoarea 1,
Suma s =0+1=1,
după efectuarea primului ciclu for, se măreşte variabila de contor cu o unitate datorită
expresiei
i=i+1,
se cuntrolează dacă noua valoare a lui
i =2
verifică expresia de condiţionare
i<n.
Valoarea lui i este 2<5 adevărat,
se va continua efectuarea instrucţiunii compuse din interiorul lui for.

s=s+i rezultă
s=1+2
LIMBAJUL C TEORIE ŞI APLICAŢI I 62

rezultă
s=1+2 obţinându-se primi doi termeni ai sumei s.
Se continuă creşterea variabilei de contor cu o unitate
i=3,
se verifică condiţia de continuare a instrucţiunii for
i=3<5 adevărat,
s=s+i rezultă
s=1+2+3 obţinându-se primi trei termeni ai sumei.
Se continuă creşterea variabilei de contor cu o unitate
i=4,
se verifică condiţia de continuare a instrucţiunii for
i=4<5 adevărat,
s=s+t*i rezultă
s=1+2+3+4 obţinându-se primi patru termeni ai sumei.
Se continuă creşterea variabilei de contor cu o unitate
i=5,
se verifică condiţia de continuare a instrucţiunii for
i=5<5 fals,
se părăseşte instrucţiunea for şi se continuă execuţia cu afişarea pe monitor a
sumei celor patru termeni.

Exemplu
Să se realizeze programul ce adună termeni alternanţi pentru s=1-2+3-… n.
Rezolvare
#include <conio.h>
#include <stdio.h>
void main ()
{
int i,n,s,t;
puts (“ se calculeaza suma s=1-2+3-4+5-….n”);
puts ("dati pe n >0=");
scanf ("%d",&n);
if (n<=0) se evaluează expresia n<=0 şi dacă este
adevărată, se afişează mesajul n a fost dat
gresit şi se trece la instrucţiunea de după
corpul instrucşiunii if.

puts ("n a fost dat gresit"); instrucţiunea 1 din corpul lui if


else
{ începutul instrucţiunii compuse 2 a instrucţiunii if

s=0; iniţializarea sumei s cu valoarea zero

t=-1; iniţializarea termenului t=1, folosit pentru


alternarea termenilor din cadrul sumei s
LIMBAJUL C TEORIE ŞI APLICAŢI I 63

for (i=1;i<=n;i=i+1) antetul instrucţiuni for, iniţializarea lui i cu 1,


condiţionare i<=n, reiniţializarea variabilei i
cu o creştere =1 la fiecare ciclu parcurs

{ inceputul corpului instrucţiunii for

t=-t; instrucţiune de atribuire cu scopul alternării


semnului termenului ce se adaugă

s=s+i*t; instrucţiune de atribuire pentru calculul sumei


termenilor cu semn alternant

} sfârşitul corpului instrucţiunii for


printf ("suma = %d\n",s);
} sfârşitul instrucţiunii 2 a instrucţiuni if
puts ("apasa o tasta");
getch ();
}

La pornirea programului se citeşte de la tastatură numărul de termeni ai sumei,


valoarea citită este dispusă la adresa lui n. Să considerăm că valoarea citită este 5.
Variabila s este iniţializată cu valoarea zero, apoi termenul t ia valoarea –1, se
iniţializează variabila de contor i a lui for cu valoarea 1, se realizează schimbarea de
semn a lui t,
t devine egal cu 1.
Suma s =0+1*1=1,
după efectuarea primului ciclu for, se măreşte variabila de contor cu o unitate datorită
expresiei
i=i+1,
se controlează dacă noua valoare a lui
i =2
verifică expresia de condiţionare
i<=n.
Valoarea lui i este 2<=5 adevărat,
se va continua efectuarea instrucţiunii compuse din interiorul lui for.
t=-t
rezultă t=-1,
s=s+t*i rezultă
s=1+(-1)*2
rezultă
s=1-2 obţinându-se primii doi termeni aisumei s.
Se continuă creşterea variabilei de contor cu o unitate
i=3,
se verifică condiţia de continuare a instrucţiunii for
i=3<=5 adevărat,
LIMBAJUL C TEORIE ŞI APLICAŢI I 64

t=-(-1)=1,
s=s+t*i rezultă
s=1-2+3 obţinându-se primii trei termeni ai sumei.
Se continuă creşterea variabilei de contor cu o unitate
i=4,
se verifică condiţia de continuare a instrucţiunii for
i=4<=5 adevărat,
t=-(1)=-1,
s=s+t*i rezultă
s=1-2+3-4 obţinându-se primii patru termeni ai sumei.
Se continuă creşterea variabilei de contor cu o unitate
i=5,
se verifică condiţia de continuare a instrucţiunii for
i=5<=5 adevărat,
t=-(-1)=1,
s=s+t*i rezultă
s=1-2+3-4+5 obţinându-se primii cinci termeni ai sumei.
Se continuă creşterea variabilei de contor cu o unitate
i=6,
se verifică condiţia de continuare a instrucţiunii for
i=6<=5 fals,
se părăseşte instrucţiunea for şi se continuă execuţia cu afişarea pe monitor a
sumei celor cinci termeni.

Exemplu
Să se afişeze valorile funcţiei f(x)=4x2+3x+5 pe intervalul –2 la +2 cu pasul
x=0,1.
Rezolvare
#include <conio.h>
#include <stdio.h>
void main ()
{
float i,x,fx;
puts (“se calculeaza f(x)=4x2+3x+5 pt. x=-2 la 2 cu pasul 0.1”);
for (x=-2;x<=2;x=x+0.1) antetul instrucţiuni for, iniţializarea lui x cu
valoarea -2, indentică cu începutul intervalului
pentru x, condiţionare x<=2, limita din dreapta
a intervalului pentru x, reiniţializarea
variabilei x cu o creştere =0.1 la fiecare ciclu
parcurs

{ începutul instrucţiunii compuse din corpul lui for


fx=-4*x*x+3*x+5; calculul lui fx la fiecare ciclu pentru x
printf ("F(x)=%f\n",fx);
} închiderea corpului instrucţiunii compuse şi
inclusiv închiderea instrucţiunii for
LIMBAJUL C TEORIE ŞI APLICAŢI I 65

puts("apasa o tasta");
getch ();
}

La execuţia programului se va iniţializa variabila de contor din ciclul for cu valoarea –


2, se parcurge instrucţiunea compusă, se determină valoarea lui fx pentru x=-2, se
afişează valoarea calculată pentru fx, se reiniţializează variabila de contoar cu o
creştere egală cu pasul dat de expresia x=x+0.1 şi se verifică dacă noua valoare pentru
x respectă condiţia x<2 din expresia 2 a instrucţiunii for.
La al doi-lea pas
x=-2+0.1=-1.9
-1.9<2 adevărat
se reia execuţia instrucţiunii de atribuire fx, se continuă ciclul for până când x
va avea valoarea 2, limita superioară a intervalului de definire pentru x.
pentru x=2 se calculează fx, se reiniţialitează x cu noua valoare
x=2+0.1=2.1
2.1<2 fals
ciclul for se închide şi se continuă programul cu instrucţiunea de după
instrucţiunea for.

Exemplu
Să se calculeze n! =1∙2∙3∙ … ∙n, unde n se citeşte de la tastatură, n >0.
Rezolvare
#include <conio.h>
#include <stdio.h>
void main ()
{
int n,i; declararea a două variabile simple de tip îtreg

float p; declararea unei singure variabile simple de tip


real simplă precizie ( float)

puts ("dati numarul n=?"); afişarea şirului de caractere dintre “dati numarul
n=? ”

scanf ("%d",&n); citirea unei date de tip întreg de la tastatură

if (n<=0) instrucţiunea if de condiţionare


puts ("n este gresit"); instrucţiunea 1 a instrucţiunii if
else
{ începutul instrucţiuni 2 a instrucţiuni if
p=1; iniţializarea produsului cu valoarea 1
for (i=1;i<=n;i=i+1)
p=p*i; calculul produsului p=1∙2∙3∙ … ∙n
printf("N!=%g\n",p); afişarea factorialului, folosind reprezentarea
ca
valoare simplă precizie sau sub forma valoare
LIMBAJUL C TEORIE ŞI APLICAŢI I 66

reprezentată cu exponent pentru a utiliza optim


spaţiul ocupat pentru afişare %g

printf("N!=%.1f\n",p); afişarea factorialului cu parte întreagă şi o singură


zecimală prin controlul formatului de afişare
%.1f
} închiderea instrucţiunii 2 a instrucţiunii if
puts("apasa o tasta");
getch ();
}

Exemplu
Să se citească termenii unui vector şi să se înmulţească vectorul cu un scalar,
mărimea vectorului, termenii vectorului cât şi scalarul se citesc de la tastatură.
Rezolvare
#include <conio.h>
#include <stdio.h>
void main ()
{
int n,i,k; declararea a trei variabile simple de tip întreg

float a[10],b[10]; declararea variabilelor indexate de tip vector cu


mărimea =10
puts ("dati marimea vectorului n=?");
scanf ("%d",&n); citirea mărimii vectorului

for (i=1;i<=n;i=i+1) instrucţiunea for folosită pentru citirea termenilor


vectorului
{
printf("dati a[%d]=",i); afişarea numărului termenului ce se citeşte

scanf ("%f",&a[i]); citirea termenului [i] al vectorului a

} încheierea operaţiei de citire a termenilor


vectorului
puts("dati marimea scalarului k=");
scanf ("%d",&k); citirea scalarului de tip întreg

for (i=1;i<=n;i=i+1) calculul produsului vectorului a cu scalarul k


b[i]=a[i]*k;
for (i=1;i<=n;i=i+1) afişarea celor doi vectori a[] şi b[]
{
printf ("a[%d]=%f\t",i,a[i]);
printf("b[%d]=%f\t",i,b[i]);
}
puts("apasa o tasta");
getch ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 67

}
Un vector a[] se caracterizează prin numărul de termeni şi valoarea fiecărui
termen . Pentru a citi valoarea ce se atribuie fiecărui termen, este nevoie să se
realizeze un grup de instrucţiuni, care să permită afişarea numărului termenului şi
citirea valorii termenului.
Acest grup de instrucţiuni trebui reluat pentru fiecare termen, reluarea grupului se
va realiza prin intermediul instrucţiunii ciclice for. Prima instrucţiune
for (i=1;i<=n;i=i+1) va realiza prin intermediul instrucţiunii compuse :
afişarea numărului termenului vectorului
citirea valorii termenului vectorului
Pentru orice operaţie asupra termenilor unui vector este necesar apelarea
instrucţiunii for prin care s-ă se parcurgă operaţia dorită asupra termenilor
vectorului. Astfel instrucţiunea a doua for are ca scop înmulţirea termenilor
vectorului cu un scalar. Instrucţiunea a treia for are ca scop afişarea termenilor
vectorului a cât şi a vectorului b.
Exemplu
Să se citească termenii unui vector şi să se caute dacă o valoare citită de la
tastatură aparţine vectorului, marimea vectorului, termenii vectorului cât şi
valoarea căutată, se citesc de la tastatură.
Rezolvare

#include <stdio.h>
#include <conio.h>
void main ()
{
float t,a[10];
int i,n;
puts ("se determina daca o valoare citita apartine vectorului");
puts ( "dati marimea vectorului ");
scanf ("%d",&n);
for (i=1;i<=n;i++) instrucţiunea for pentru citirea termenilor
vectorului
{
printf ("dati termenul %d= ",i);
scanf ("%f",&a[i]);
}
puts ("dati valoarea care se cauta daca apartine vectorului");
scanf ("%f",&t);
for (i=1;i<=n;i++) instrucţiunea for pentru parcurgerea tuturor
termenilor vectorului şi compararea fiecărui
termen cu valoarea căutată

if (t==a[i]) instrucţiunea de decizie


puts ("valoarea cautata apartine vectorului");
else
;
puts ("apasa o tasta ");
LIMBAJUL C TEORIE ŞI APLICAŢI I 68

getch ();
}

Probleme propuse
1. Să se determine valoarea lui sin (x) dată de relaţia:
sin (x)= x-x3/3!+x5/5!-x7/7!…..+(-1)n.x2n+1/(2n+1)
Date de intrare : valoare numerică reală a lui x exprimată în radiani
Date de ieşire : valoarea lui sin (x)
2. Să se determine valoarea lui cos (x) dată de relaţia:
cos (x)=1-x2/2!+x4/4!-x6/6!….+(-1n).x2n/(2n)
Date de intrare : valoare numerică reală a lui x exprimată în radiani
Date de ieşire : valoarea lui cos (x)
4. Să se afişeze viteza=v şi spaţiul s1= parcurs în fiecare secundă a unui corp în
cădere liberă de la înălţimea =h.
Date de intrare: inălţimea h.
Date de ieşire v, s1.
Timpul total de cădere =t= 2h / g v=g.t s1=g(t2i+1-t2i)
Constantă g=9.81 m/s2.
5. Să se determine valoarea maximă a termenului unui vector .
Date de intrare: mărimea şi termenii vectorului
Date de ieşire: valoarea maximă a termenului .
6. Să se calculeze C=A.a1+B.b1
A, B vectori cu aceeaşi mărime
a1, b1 doi scalari
Date de intrare: n=mărimea vectorilor
Termenii celor doi vectori
Valoarea celor doi scalari
Date de ieşire: vectorul C.
7. Să se afişeze valorile funcţiei f(x)=g.x2/2 pentru x a,b iar pasul de creştere a
lui x este p.
Date de intrare a, b, p.
Date de ieşire valoarea lui f(x) .
8. Să se determine suma s=1-22+32-42….n2
Date de intrare: mărimea n.
Date de ieşire: valoarea sumei s.
9. Să se determine valoarea lui e =1+1/1!+1/21+1/31+…1/n! cu precizia cerută
de utilizator prin epsilon.
LIMBAJUL C TEORIE ŞI APLICAŢI I 69

Date de intrare: numărul de termeni, epsilon.


Date de ieşire valoarea lui e.
10. Să se determine media aritmetică şi geometrică a n numere pozitive citite de
la tastatură.
Ma=(n1+n2+n3+…nn)/n
Mg= n n1.n2.n3...nn
Date de intrare numărul de numere şi valoarea acestora.
Date de ieşire Ma şi Mg.

3.5.5. Instrucţiunea while.


Instrucţiunea while este folosită pentru realizarea unei structuri ciclice
condiţionate anterior şi are sintaxa :
while (expresie de conditionare)
Instructiune simpla sau compusa;
Se evaluează expresia dintre paranteze şi dacă aceasta este adevărată se
efectuează instrucţiunea din corpul lui while, după care se trece
la instrucţiunea următoare.
Dacă expresia are valoare falsă, nu se va executa instrucţiunea din corpul lui
while şi se trece direct la instrucţiunea următoare, astfel instrucţiunea din
corpul lui while poate să nu se execute niciodată. În corpul instrucţiunii while
poate exista o nouă instrucţiune while, în acest caz, se numesc instrucţiuni
while imbricate.
Instrucţiunea while se poate considera ca o instrucţiune ciclică condiţionată
Anterior, definind o structură repetitivă.
Exemplu
Să se afişeze valorile funcţiei f(x)=4x2+3x+5 x –2 la +2 cu pasul =0.1 pt. x.
#include <conio.h>
#include <stdio.h>
void main ()
{
float i,x,fx;
puts (“se calculeaza f(x)=4x2+3x+5 pt. x=-2 la 2 cu pasul 0.1”);
x=-2; iniţializarea lui x cu valoarea de începuta
intervalului
while ( x<=2) instrucţiunea while condiţionează execuţia cât
timp x<=2
{ începutul corpului instrucţiunii while
fx=-4*x*x+3*x+5;
printf ("x=%f F(x)=%f\n",x,fx);
x=x+0.1; modificarea variabilei de condiţionare, pentru a se
parcurge domeniul lui x
LIMBAJUL C TEORIE ŞI APLICAŢI I 70

} sfârşitul corpului lui while


puts("apasa o tasta");
getch ();
}
Observaţie
Dacă variabila x ce intră în expresia de condiţionare a lui while nu se modifică
în interiorul corpului instrucţiunii while, va rezulta un ciclu infinit.
În cazul de faţă, înainte de execuţia instrucţiunii while, x are valoarea –2 ce
este mai mică decât 2, astfel expresia x<=2 este adevărată şi se începe
execuţia instrucţiunii compuse din corpul lui while astfel :
Se calculează fx=-4*x*x+3*x+5; pentru x=-2
Se afişează valoarea lui x şi f(x) cu instrucţiunea
printf ("x=%f F(x)=%f\n",x,fx);
x=x+0.1; se modifică valoarea lui x cu 0.1. x devine –1.9 şi
se verifică dacă noua valoare a lui x respectă
condiţionarea din expresia lui while şi se continuă
până când valoarea lui x devine mai mare decât 2.
Exemplu
Să se afişeze valorile funcţiei trigonometrice sin (x) pentru domeniul 0 la 359
de grade sexagesimale, din grad în grad, cu vizualizarea pagină cu pagină a
valorilor.
Rezolvare
Pentru calculul funcţiei sin (x) se va apela funcţia de bibliotecă
sin(parametru) din fişierul math.h cu observaţia că parametrul funcţiei
sin(par) trebuie exprimat în radiani. Astfel, se va converti unghiul x din grade
sexagesimale în radiani par=x*PI/180
Pentru a afişa pagină cu pagină, se va condiţiona ca dupa fiecare valoare a lui
x=modul de 23 să se citească un caracter de la tastatură, cu scopul de a opri
temporar execuţia programului în ecranul utilizatorului, pentru citirea valorilor
din pagina curentă.
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define PI 3.14159265 definirea constantei PI
void main ()
{
int x;
double sx,x1;
x1=PI/180.0;
x=0;
while (x<=359) condiţionarea execuţiei instrucţiunii while
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 71

sx=sin (x*x1); calculul lui sx ca sin( x), x este transformat în


radiani pentru a apela corect funcţia matematică
double sin (valoare double)
printf ("sin [%d]=%.10lf\n",x,sx);
x=x+1; modificarea valorii lui x pentru a parcurge
domeniul 0 … 359 grade
if ((x+1)%23==0) condiţionarea afişării mesajului şi aşteptarea
apasării unei taste după 23 de linii afişate (dacă
restul împărţirii lui x la 23 este zero, adică x
modulo 23)
{
puts ("Apasati o tasta pentru a afisa pagina urmatoare");
getch ();
}
} închiderea corpului instrucţiunii while
puts("apasa o tasta pentru terminarea programului ");
getch ();
}

Exemplu
Să se citească mai multe valori reale separate prin spaţiu alb sau Enter şi să
se determine suma acestor valori. Terminarea şirului de valori se relizează
prin apăsarea unei taste literă sau caracterul virgulă.
Rezolvare

Datorită faptului că nu se cunosc numărul de valori ce se vor citi, nu se poate


aplica instrucţiunea ciclică for, se va pune o condiţie care să detecteze când
valoarea ce se citeşte nu mai este o valoare reală.
Funcţia scanf (%f..) returnează valoarea 1, pentru o citire efectuată sub
controlul de format şi valoarea 0 pentru cazul că nu s-a efectuat citirea.
Instrucţiunea while verifică condiţia ca citirea să aibă loc (valoarea returnată
de funcţia scanf s-ă fie ==1).

#include <stdio.h>
#include <conio.h>
void main ()
{
float t,s;
puts ("Se citesc valori reale separate prin spatiu si se afiseaza
suma lor ");
puts ( "inchiderea sirului cu caracterul virgula
dati valorile ");
s=0;
while (scanf ("%f",&t)==1) instrucţiunea while condiţionează execuţia
instrucţiunii s=s+t, dacă funcţia scanf ()
LIMBAJUL C TEORIE ŞI APLICAŢI I 72

returnează valoarea 1. corespunzătoare citiri unei


date reale urmată de spaţiu liber sau Enter. Dacă
data citită este un caracter alfa sau virgulă,
condiţia lui while nu mai este adevărată, fincă
funcţia scanf va returna valoarea 0 (nu s-a citit
valoarea), se părăseşte while.

s=s+t; instrucţiunea din corpul lui while , care realizează


suma valorilor introduse de la tastatură.

printf ("suma valorilor introduse =%.3f \n",s); %.3f permite afişarea valorilor
reale cu 3 zecimale
puts ("apasa o tasta ");
getch ();
}

Exemplu
Să se citească termenii a doi vectori de tip real simplă precizie, să se
determine produsul scalar ai celor doi vectori.
Rezolvare
Se consideră că termenii primului vector sunt în a, iar termenii celui de-al doilea
vector sunt în b. Datorită faptului că nu se cere păstrarea termenilor citiţi şi
doar produsul scalar, nu este necesar declararea de tablouri de tip vectori.
Dacă vectorul a are termenii a1, a2, a3, …an iar vectorul b are termenii b1, b2,
b3, …bn , produsul scalar a vectorilor a şi b este dat de suma
a1*b1+a2*b2+a3*b3….an*bn.
Se vor citi perechi de valori ce reprezintă termenul ai, bi, iar închiderea şirului
de perechi de valori se realizează ca şi în exemplul anterior, prin a tasta un
caracter literă sau caracterul virgulă.

#include <stdio.h>
#include <conio.h>
void main ()
{
float a,b,p;
int i; declararea variabilei i de tip intreg pentru ase afişa
numărul termenului care se citeşte,sau se poate
folosi la indicarea numărului final de termeni ai
vectoruluia sau vectorului b
puts ("Se citesc valori reale perechi a termenilor a doi vectori ");
puts ( " Inchiderea sirului cu caracterul virgula sau caracter litera");
p=0.0;
i=1;
printf ("Dati valoari pentru a[%d] si b[%d]",i,i);
LIMBAJUL C TEORIE ŞI APLICAŢI I 73

while (scanf ("%f %f",&a,&b)==2) condiţia de continuare a instrucţiunii


compuse din corpul lui while
{
p=p+a*b;
i=i+1;
printf ("Dati valori pentru a[%d] si b[%d]",i,i);
}
printf ("Produsul scalar a termenilor celor 2 vectori =%.3f \n",p);
puts ("Apasa o tasta ");
getch ();
}

Probleme propuse
2
1. Să se realizeze un program care să calculeze Fx 3x 4 , x>0
condiţionat de o parolă de intrare formate din 2-3 cifre.
Dată de intrare: parolă şi x
Dată de ieşire Fx
2. Să se determine n! pentru n<100 n!=1*2*3*..*n
Dată de intrare: n
Dată de ieşire n!
3. Să se citească termeni unui vector şi să se determine valoarea minimă a
termenului vectorului.
Dată de intrare: termeni vectorului.
Dată de ieşire minimul din termeni vectorului.
3.5.6. Instrucţiunea do while.
Instrucţiunea do while este utilizată pentru realizarea structurilor ciclice
condiţionate posterior şi are sintaxa :
do
Instructiune simpla sau compusa;
while (expresie);
Instrucţiunea se execută astfel :
1. Se execută instrucţiunea simplă sau compusă de dupo do,
2. Se evaluează expresia dintre parantezele de după while şi dacă aceasta este
adevărată, se reia execuţia instrucţiunii de după do, dacă valoarea expresiei
este falsă se încheie instrucţiunea do-while şi se continuă programul cu
următoarea instrucţiune.
Observaţie
Indiferent de valoarea expresiei dintre parantezele de după while, instrucţiunea din
corpul do-while se execută cel puţin odată, de unde apare şi denumirea de
structură condiţionată posterior.

Exemplu
Să se afişeze valorile funcţiei f(x)=4x2+3x+5 pentu x intervalul de la k la
+2, x are pasul de creştere =0.1, dacă k >2 se va calcula şi afişa pentru acest
LIMBAJUL C TEORIE ŞI APLICAŢI I 74

k valoarea funcţiei f(x), dacă k<2 se va determina f(x) de la k, la limita


superioară a intervalului (2) .
Rezolvare
#include <conio.h>
#include <stdio.h>
void main ()
{
float i,x,fx;
puts (“se calculeaza f(x)=4x2+3x+5 pt. x k la 2, daca k <2, cu pasul 0.1”);
puts (“Dati valoarea de inceput a lui x= k”);
scanf (“ %f”,&x);
do
{ începutul corpului instrucţiunii do-while
fx=-4*x*x+3*x+5;
printf ("x=%f F(x)=%f\n",x,fx);
x=x+0.1; modificarea variabilei condiţionată de while
pentru a se termina domeniul pt. x
} sfârşitul corpului lui do-while
while (x<=2) instrucţiunea while condiţionează continuarea
execuţiei instrucţiunii compuse din corpul lui do-
while cât timp x<=2
puts("apasa o tasta");
getch ( );
}

Cazul I. Presupunem că s-a dat pentru x=k valoarea 3, în acest caz se va


calcula f(x) pentru această valoare, se va afişa valoarea lui x şi f(x), după care
se majorează valoarea lui x cu 0.1 şi se evaluează expresia x<=2 , 3.1 nu este
mai mic decât 2, expresia este falsă, se părăseşte ciclul do while.
Cazul II. Presupunem că s-a citit pentru x valoarea 0, în acest caz se va
calcula f(x) pentru această valoare, se va afişa valoarea lui x şi f(x), după care
se majorează valoarea lui x cu 0.1 x=0+0.1=0.1 şi se evaluează expresia
x<=2 , este mai mic decât 2, expresia este adevărată, se reia calculul lui f(x) şi
calculul pentru noua valoare a lui x=0.1+0.1=0.2…până când x are valoarea 2,
se efectuează ultimul calcul şi se părăseşte ciclul do while.
Exemplu
Să se determine numărul minim de monede şi bacnote cu care se poate plăti o
sumă număr intreg pozitiv, monedele folosite sunt : 100, 500, 1000, iar
bacnotele sunt : 2000, 10000, 50000, 100000.
Rezolvare
Calculul începe prin a determina numărul întreg de bacnote cu valoarea
maximă 100000 din care este realizată suma v.
Pentru a apela valorile diferite ale monedelor sau bacnotelor s-a folosit
LIMBAJUL C TEORIE ŞI APLICAŢI I 75

vectorul moneda cu 7 termeni, a căror valoare reprezintă valorile impuse în


enunţul problemei.
Pentru aceasta se împarte suma v la valoarea bacnotei maxime,
I=7
n=v/moneda [i];
n = partea întreagă a împărţiri la 100000 care va indica numărul de bacnote de
100000.
Pentru a determina restul împărţiri la 100000 se va aplica expresia :
v=v%moneda [i]
astfel noua valoare a lui v conţine multipli ai monedelor sau bacnotelor cu
valori mai mici de 100000.
Se repetă procedeul de mai sus, prin modificarea termenului la care se va
împărţii noua sumă (restul de la împărţirea cu 100000), find necesar
decrementarea lui i cu 1 :
i=i-1; rezultă i=6
n=v/moneda [6]; rezultă numărul de bacnote cu valoarea de 50000
v=v%moneda [5] rezultă restul împărţiri la 50000
Aceşti paşi se repetă până când valoarea restului este zero, valoarea sumei
trebuie să fie multiplu de 100 (valoarea minimă a monedei impusă în enunţul
problemei).

#include <stdio.h>
#include <conio.h>
void main ()
{
long v,n; declararaţii a tipului intreg long pentru a se putea
efectua operaţii pe intregi cu valori mai mari de
32647
long i;
long moneda [8];
puts ("Se calculeaza numarul de bagnote si monede pt. o valoare data ");
puts ( "Dati valoarea intreaga multiplu de 100");
scanf("%ld",&v); citirea unei date de tip intreg long %ld
moneda [1]=100; atribuirea valorilor termenilor vectorului moneda
moneda [2]=500;
moneda [3]=1000;
moneda [4]=2000;
moneda [5]=10000;
moneda [6]=50000;
moneda [7]=100000;
LIMBAJUL C TEORIE ŞI APLICAŢI I 76

i=7; iniţializarea lui i cu valoarea max corespunzătoare


numărului termenului maxim al vectorului
moneda
do începerea ciclului do while
{
n=v/moneda [i];
if (n) dacă valoarea sumei s este mai mică de 100 sau
nu este multiplu de 100, va rezulta n=0 şi nu se va
afişa numărul bacnotelor sau monedelor, datorită
faptului că suma nu poate fi reprezentată de nici o
manodă
if (i<5)
if (n==1)
if (i==1)
puts ("O moneda de 100 lei");
else
printf ("o moneda a %ld lei\n",moneda [i]);
else
if (i==1)

printf ("%ld monede de 100lei\n",n);


else
printf ("%ld monede %ld lei\n",n,moneda [i]);
else
if (n==1)
printf ("O bacnota a %ld lei \n",moneda [i]);
else
printf ("%ld bacnote a %ld lei",n,moneda [i]);
}
while (v=v%moneda [i--]); expresia de condiţionare a ciclului do while este
ca restul împărţirii să fie diferit de zero şi
suplimentar se face decrementarea cu 1 a valorii
lui i
puts ("Apasa o tasta ");
getch ();
}

Probleme propuse
1. Să se realizeze un program care să afişeze Fx 4x 2 3 indiferent de
valoarea lui x iar dacă x 0 4 să afişeze valorile lui Fx pe acest interval cu
pasul de creştere a lui x 0,5
Dată de intrare: x
Dată de ieşire: Fx
2. Să se citească tasta apăsată şi dacă aceasta nu este cifră atunci se efectuează
programul de calcul a lui Fx pentru o valoare x 1 iar dacă tasta apăsată este
1 să se afişeze Fx pe intervalul x 0 10 cu pasul 1.
LIMBAJUL C TEORIE ŞI APLICAŢI I 77

Fx 4x 2 2x 1 .
Dată de intrare: valoarea introdusă
Dată de ieşire: Fx
3.5.7. Instrucţiunea break.
Instrucţiunea break este folosită în cadrul corpului unui ciclu al instrucţiunilor
for, do-while, while, switch şi la întâlnirea acestei instrucţiuni se termină
execuţia ciclului. Execuţia se continuă cu instrucţiunea de după ciclul în care s-a
întâlnit instrucţiunea break. Sintaxa instrucţiunii break este :
break;
Exemplu
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main ()
{
int i,s;
float n,j,x,fx;
do
{
puts ("dati valoarea lui x");

if (scanf("%f",&x) == 1) dacă data citită este de tip real, funcţia scanf va


returna valoarea 1
break; instrucţiunea break forţează ieşirea din ciclul do
while
puts ("nu s-a citit un numar");
puts ("se reia citirea ");
fflush (stdin); funcţia fflush are rolul de a goli registrul asociat
tastaturii pentru reluarea citirii
}
while (1);
for (j=x;j<=x+5;j++)
{
fx=4*j;
printf ("functia fx=%g \n",fx);
}
puts ("Apasa o tasta");
getch ();
}

3.5.8. Instrucţiunea continue.


Instrucţiunea continue se utilizează în corpul ciclului do while, while sau for şi
permite abandonarea iteraţiei.
Instrucţiunea continue în cadrul instrucţiunilor while şi do while forţează
oprirea iteraţiei curente, se evaluează expresia care stabileşte continuarea sau
terminarea ciclului.
LIMBAJUL C TEORIE ŞI APLICAŢI I 78

În cadrul instrucţiunii for, instrucţiunea continue forţează abandonarea iteraţiei


curente şi se execută pasul de reiniţializare.
Instrucţiunea continue este folosită în cadrul instrucţiunilor if imbricate din
cadrul unui ciclu for, do while, while.

3.5.9. Funcţia exit.


Funcţia exit are prototipul :
Void exit (int cod)
Parametrul de tip intreg defineşte starea programului la momentul apelării funcţiei exit.
Valoarea 0 a parametrului indică o terminare normală a execuţiei programului.
Valoarea diferită de 0 a parametrului indică o terminare anormală a programului.
La apelul funcţiei exit, se videază bufferele fişierelor deschise în citire, se închid toate
fişierele deschise şi se întrerupe programul.
Prototipul funcţiei exit este în stdlib.h şi process.h.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <process.h>
void main ()
{
float a,b,p;
puts ("Se citesc valori reale perechi ");
printf ("Dati valoari pentru a si b separate prin spatiu\t");
if (scanf ("%f %f",&a,&b)!=2)
{
puts ("una sau ambele valori diferite de valori reale");
exit (1); apelarea funcţiei exit cu parametrul 1 pentru o
terminare anormală ( eroare de citire a uneia sau
ambele valori)
}
else
p=a*b;
printf ("Produsul scalar a*b= %.3f \n",p);
puts ("Apasa o tasta ");
getch ();
exit (0); apelarea funcţiei exit cu parametrul 0 pentru o
terminare normală
}

3.5.10. Instrucţiunea switch.


Instrucţiunea switch este folosită la realizarea structurilor selective, în locul
instrucţiunilor if imbricate. Instrucţiunea switch poate fi utilizată la realizarea
meniurilor, alegerea de opţiuni, şi are forma :
switch (expresie)
{
case c1:
LIMBAJUL C TEORIE ŞI APLICAŢI I 79

instructiuni 1
break;
case c2:
instructiuni 2
break;
case c3:
instructiuni 3
break;
case cn:
instructiuni n
break;

case default:
instructiuni
break;
}
unde c1, c2, c3, …, cn sunt constante; instructiuni1, instructiuni2, …,
instructiuni n sunt grupuri de instrucţiuni.
Execuţia instrucţiunii switch se face astfel :
Se evaluează expresia dintre paranteze şi se compară valoarea expresiei cu
valorile constantelor c1, c2, …, cn.
Se execută grupul de instructiuni de după constanta ci a cărei valoare este
egală cu valoarea expresiei, apoi se iese din instrucţiunea switch.
Dacă valoarea expresiei nu este egală cu nici o constantă c1, c2, …, cn se va
executa grupul de instructiuni de dupa eticheta default. Dacă eticheta default
şi instrucţiunile de după ea lipsesc şi valoarea expresiei este diferită de oricare
dintre constante, se iese din instrucţiunea switch.
Observaţie
Din instrucţiunea switch poate lipsi eticheta default şi instrucţiunea ataşată lui
default, dar trebuie să existe minim o constantă ci.
Instrucţiunea break este utilizată după fiecare grup de instrucţiuni ataşate
constantelor cu rolul de ieşire din instrucţiunea switch.
Exemplu
Să se creeze un program C care prin alegerea unei opţiuni dintr-un meniu să
execute diferite operaţii asupra datelor de intrare a, b şi să tipărească valorile
calculelor efectuate. Opţiunile se indică prin valori numerice.

Rezolvare
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main ()
{
int n;
float a,b,c,d,e,f;
puts ("------------ MENIU--------- ");
LIMBAJUL C TEORIE ŞI APLICAŢI I 80

puts ("----ADUNARE====1 ----");


puts ("----SCADERE====2 ----");
puts ("----INMULTIRE==3 ----");
puts ("----IMPARTIRE==4 ----");
puts ("----RADICAL====5 ----");
puts ("----IESIRE=====6 ----");
puts ("====dati valoarea optiunii===== ");
scanf ("%d",&n); se citeşte opţiunea aleasă de utilizator
if (n!=6) dacă opţiunea este mai mică de 6 se execută
programul
{
puts ("dati doua numere");
scanf ("%f %f",&a,&b); se citesc două valori de tip real (float)
switch (n) se evaluează expresia dintre ( ) şi valoarea acestei
expresii transferă execuţia la constanta ce are
valoarea egală cu valoarea expresiei , de exemplu
dacă n=2 se transferă execuţia la case 2
{
case 1: dacă valoarea lui n=1 transferul execuţiei se face
la case 1
c=a+b; instrucţiunea 1 din grupul de instrucţiuni ale lui
case 1
printf("Suma=%f",c); instrucţiunea 2 din grupul de instrucţiuni ale lui
case 1
break; forţează ieşirea din instrucţiunea switch
case 2: dacă valoarea lui n=2 transferul execuţiei se face
la case 2
c=a-b;
printf ("Diferenta=%f",c);
break;
case 3: dacă valoarea lui n=3 transferul execuţiei se face
la case 3
c=a*b;
printf ("Produs=%f",c);
break;
case 4: dacă valoarea lui n=4 transferul execuţiei se face
la case 4
c=a/b;
printf ("Impartire=%f",c);
break;
case 5: dacă valoarea lui n=5 transferul execuţiei se face
la case 5
c=sqrt(a*b);
printf ("Radical=%f",c);
break;
}
}
else
puts ("programul sa terminat");
LIMBAJUL C TEORIE ŞI APLICAŢI I 81

puts ("apasati o tasta pentru iesirea din program");


getch ();
}

Probleme propuse
1. Să se afişeze zilele săptămânii în română şi engleză în funcţie de valoarea
numerică din domeniul 1 la 7.
Dată de intrare:o valoarea numerică
Dată de ieşire: numele zilei
2. Să se realizeze un program cu opţiuni numerice care permite:
1. citirea unui vector şi afişarea acestuia
2. citirea unui vector şi înmulţirea cu un scalar a acestui vector
3. citirea a doi vectori şi adunarea acestora
4. citirea a doi vectori şi scăderea acestora
5. ieşire.
3.5.11. Instrucţiunea goto.
Instrucţiunea goto se utilizează pentru a indica ieşirea din mai multe instrucţiuni
if imbricate sau din mai multe instrucţiuni for şi transferul execuţiei la
instrucţiunea de după eticheta indicată de instrucţiunea goto.
Eticheta este un nume urmat de caracterul : (două puncte), numele reprezintă
chiar denumirea etichetei. Etichetele se folosesc în interiorul corpului funcţiei în
care este apelată instrucţiunea goto . Sintaxa instrucţiunii goto este :
goto nume;

nume:

Instrucţiunea goto poate face salt numai la o etichetă urmată de o instrucţiune ce
se află în corpul funcţiei din care face parte şi ea.
Exemplu
Să se calculeze funcţia f(x) =4x/(x-2), pentru 5 valori crescătoare ale lui x cu 1,
valoarea lui x este citită de la tastatură, dacă valoarea expresiei x-2=0, se va ieşi
din ciclul for şi se va afişa mesajul divizare prin zero.
Rezolvare
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main ()
{
int i,s;
float n,j,x,fx;
puts ("se determina f(x)=(4x)/(x-2) daca x-2 nu este egal cu zero");
puts ("dati valoarea de inceput a lui x ");
scanf ("%f",&x);
for (j=x;j<=x+5;j++)
{
if (j-2 == 0)
LIMBAJUL C TEORIE ŞI APLICAŢI I 82

goto eroare; salt la instrucţiunea de după eticheta eroare


else
fx=(4*j)/(j-2);
printf ("x= %f functia fx=%g \n",x,fx);
}
goto sfirsit; salt la instrucţiunea de după eticheta sfirsit
eroare: eticheta eroare
puts ("divizare prin zero");
sfirsit: eticheta sfirsit
puts ("Apasa o tasta");
getch ();
}

3.6. Apelul prin valoare şi apelul prin referinţă al unei funcţii.


O funcţie are următoarea structură :
Tip_de_data Nume(Lista declaratiilor parametrilor formali)
{
Declaratii;
Instructiuni;
}
La apelul unei funcţii, fiecărui parametru formal i se atribuie valoarea
parametrului efectiv corespunzător şi în acest caz se consideră că apelul funcţiei
se face prin valoare.
Funcţia în acest caz nu va modifica valoarea parametrului efectiv.
Dacă se doreşte ca funcţia apelată să modifice valoarea parametrului efectiv se va
folosi apelul prin referinţă ce se realizează prin folosirea ca parametru efectiv
numele unui tablou iar dacă parametrul efectiv este o variabilă simplă se vor
folosi pointeri. De exemplu:
int n, j, a[10];

Functia1 (n, j, a);

La apelarea funcţiei Functia1 parametri efectivi n şi j sunt de tipul parametri
apelaţi prin valoare, Functia1 nu poate modifica valoarea acestora, dar
parametrul a este de tip tablou şi în acest caz apelul parametrului se face prin
referinţă, ce permite funcţiei Functia1 să modifice valoarea termenilor tabloului
a[10].

3.7. Operaţii asupra vectorilor.


În majoritatea problemelor tehnice de prelucrare a datelor de intrare, ieşire
(presiune, temperatură, debit, viteze, mase, caracteristici geometrice, etc.) este
necesar dispunerea lor în tablouri cu una sau două dimensiuni.
Pentru citirea, prelucrarea, afişarea acestor tablouri se vor realiza funcţii specifice
operaţiei dorite de tip :

 Citirea unui vector.


LIMBAJUL C TEORIE ŞI APLICAŢI I 83

 Operaţii asupra unuia sau mai multor vectori.


 Afişarea unui vector.
 Citirea unui tablou cu două dimensiuni (matrice).
 Operaţii asupra unuia sau mai multor tablouri cu două dimensiuni.
 Afişarea unui tablou cu două dimensiuni.
Pentru înţelegerea algoritmului se vor folosi două variante astfel : Prima va folosi
toate instrucţiunile necesare într-un singur fişier sursă, a doua va folosi funcţii
specifice scrise în fişiere separate de fişierul sursă.
Exemplu
Să se scrie un program care citeşte termenii unui vector, afişează termenii
vectorului. Citirea mărimii vectorului cât şi a termenilor vectorului se efectuează
de la tastatură.
Rezolvare
#include <conio.h>
#include <stdio.h>
#include <math.h>
main( )
{
int n,i; variabila n pentru mărimea vectorului, variabila i
pentru contor
double a[10]; variabila indexată a unui tablou cu o dimensiune
maximă de 10 termeni [10]
puts ("dati marimea vectorului n=?");

scanf ("%d",&n); citirea mărimii vectorului


Pentru a citi termenii unui vector se va folosi un ciclu for cu variabila de contor i de la
1 la n cu pasul 1, la fiecare pas se va afişa denumirea termenului ce se citeşte şi apoi se
citeşte data de intrare a cărei valoare este depozitată la adresa variabilei indexate a[i]
for (i=1;i<=n;i=i+1) ciclul for de citire al vectorului a[i]
{ inceputul instrucţiunii compuse
printf("dati a[%d]=",i); mesaj de indicare a termenului ce se citeşte
scanf ("%lf",&a[i]); citirea datei de intrare de tip real (double )
care se atribuie termenului [i]
} sfârşitul instrucţiunii compuse şi a ciclului
for
for (i=1;i<=n;i=i+1) ciclul for de afişare a vectorului a[i]
printf ("a[%d]=%lf\t",i,a[i]); apelarea funcţiei de afişare cu format a
variabilelor i, a[i] şi la fiecare apelare a
funcţiei de afişare se deplasează poziţia
cursorului cu un tabulator (spaţiu de 8
caractere) \t
puts("apasa o tasta");
getch ();
}
Pentru rezolvarea aceleaşi probleme se pot folosi două funcţii citv şi tipv, care au
avantajul că pot fi utilizate în toate fişierele care necesită operaţii de citire sau de
LIMBAJUL C TEORIE ŞI APLICAŢI I 84

afişare a unui vector. Funcţia citv are doi parametrii formali : n de tip variabilă
simplă şi a[10] de tip variabilă indexată, astfel, apelul parametrului n se face prin
valoare iar apelul parametrului a[10] se face prin referinţă.
Fisier: citv.c
citv (int n, double a[30]) antetul funcţiei citv, ce conţine tipul funcţiei prin
lipsă întreg, denumirea funcţiei citv, parametrii formali ai funcţiei n de tip întreg
şi a[10] (tabloul) de tip double
{ începutul corpului funcţiei citv
int i; variabilă locală de tip întreg folosită în cadrul
funcţiei citv
double t; variabilă locală de tip double folosită în cadrul
funcţiei citv
for (i=1;i<=n;i++) ciclul for pentru citirea datelor de la tastatură şi
transferarea acestora în tabloul a[10]
{
printf ("Dati elementul %d =",i);
scanf ("%lf",&t);
a[i]=t;
} închiderea ciclului for
puts ("S-a citit vectorul");
} închiderea corpului funcţiei citv

Pentru afişarea elementelor unui vector s-a realizat funcţia tipv astfel:
Fisier tipv.c

tipv (int n, double a[30]) antetul funcţiei tipv, ce conţine tipul de dată al
funcţiei prin lipsă întreg, denumirea funcţiei
tipv, parametri formali ai funcţiei : n de tip
întreg şi a[10] tablou de tip double
{ începutul corpului funcţiei tipv
int i; variabilă locală de tip întreg folosită în cadrul funcţiei tipv
for (i=1;i<=n;i++) ciclul for pentru afişarea vectorului a[i]
printf (" %lf\t ",a[i]);
puts ("\n");
} închiderea corpului funcţiei tipv

În fişierul de mai jos se prezintă folosirea funcţiilor citv şi tipv salvate în două fişiere
citv.c şi tipv.c.

#include <conio.h>
#include <stdio.h>
#include <math.h>
#include “citv.c” includerea fişierului citv.c care conţine funcţia
citv creată anterior de către utilizator
#include “tipv.c” includerea fişierului tipv.c care conţine funcţia
tipv creată anterior de către utilizator
LIMBAJUL C TEORIE ŞI APLICAŢI I 85

void main ()
{
int n;
double b[10]; variabila indexată a unui tablou cu dimensiunea
maximă de 10 termeni [10]
puts ("dati marimea vectorului n=?");
scanf ("%d",&n); citirea mărimii vectorului
citv (n, b); apelarea funcţiei de citire a unui vector, parametrii
efectivi sunt n şi b, ce sunt transferaţi funcţiei, la
revenirea din funcţia citv în parametrul b de tip
tablou prin referinţă se găsesc termenii citiţi ai
vectorului a în funcţia citv.
tipv (n,b); apelarea funcţiei de afişare a unui vector,
parametrii efectivi sunt n şi vectorul b.
puts("apasa o tasta");
getch ();
}
Observaţie
Fişierul sursă este mult mai scurt decât fişierul ce efectuează operaţiile de citire,
afişare, în interiorul fişierului. În plus, funcţiile apelate pot fi utilizate de toţi
utilizatorii care includ fişierele ce conţin funcţiile dorite. În exemplele ce urmează
se vor folosi funcţii specifice operaţiilor dorite, astfel programele vor conţine cât
mai multe apelări de funcţii.
Exemplu
Să se adune termenii unui vector şi să se afişeze vectorul precum şi suma
termenilor. Mărimea vectorului, termenii vectorului se citesc de la tastatură.
Rezolvare
Se va crea o funcţie sumv care adună termenii unui vector. Funcţia sumv va fi
salvată în fişierul sumv.c. Pentru citirea termenilor vectorului şi afişarea vectorului
se vor folosi funcţiile citv, tipv.
Fişierul sumv.c ce conţine funcţia sumv este
float sumv (int n, double a[10]) antetul funcţiei sumv, ce conţine tipul
float al funcţiei, denumirea funcţiei
sumv, parametrii formali ai funcţiei : n
de tip întreg şi a[10] tablou de tip
double
{ începutul corpului funcţiei sumv
int i; variabilă locală de tip întreg
double s; variabilă locală de tip double folosită în
cadrul funcţiei sumv
s=0; iniţializarea sumei cu valoarea zero
for (i=1;i<=n;i++) ciclul for pentru calculul sumei
termenilor vectorului
s=s+a[i];
LIMBAJUL C TEORIE ŞI APLICAŢI I 86

return (s); instrucţiunea de returnare a valorii lui s


în funcţia din care a fost apelată funcţia
sumv
} închiderea corpului funcţiei sumv
Fişierul sursă al programului principal va fi
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include “citv.c” includerea fişierului citv.c care conţine funcţia
citv
#include “tipv.c” includerea fişierului tipv.c care conţine funcţia
tipv
#include “sumv.c” includerea fişierului sumv.c care conţine funcţia
sumv
void main ()
{
int n;
double b[10], s; variabila indexată a unui tablou cu dimensiunea
maximă de 10 termeni [10] şi variabila simplă s
în care se va depozita valoarea sumei termenilor
vectorului
puts ("dati marimea vectorului n=?");
scanf ("%d",&n);
citv (n,b) ; apelarea funcţiei de citire a unui vector

s= sumv (n,b); apelarea funcţiei sumv care returnează o valoare de


tip float, pe care o atribuie variabilei s

tipv (n,b); apelarea funcţiei de afişare a unui vector


printf (“suma termenilor vectorului =%lf \n”,s);
puts("apasa o tasta");
getch ();
}
Exemplu
Să se determine numărul de zile cu temperaturile sub zero, numărul de zile cu
temperatura de zero grade şi numărul de zile cu temperatura peste zero grade.
Temperaturile zilelor sunt citite pe un interval de maxim 30 zile, introducerea
datelor făcându-se de la tastatură.
Rezolvare
Fişierul sursă al programului principal
#include <conio.h>
#include <stdio.h>
#include “citv.c” includerea fişierului citv.c care conţine funcţia
citv
void main ()
{
int n, i;
double b[30];
LIMBAJUL C TEORIE ŞI APLICAŢI I 87

int poz, neg, nul;


puts ("dati numarul de zile pt. care s-a citit temperatura n=?");
scanf ("%d",&n);
poz=0;
nul=0;
neg=0;
puts ("dati temperatura zilelor \n");
citv (n,b) ; apelarea funcţiei de citire a unui vector citv
for (i=1;i<=n;i++)
if (b[i][j]<0)
neg=neg+1;
else
if(b[i][j]==0)
nul=nul+1;
else
poz=poz+1;
printf ("zile cu temperaturi pozitive= %d\n",poz);
printf ("zile cu temperaturi negative= %d\n",neg);
printf ("zile cu temperatura de zero = %d\n",nul);
puts ("\n apasa o tasta");
getch ();
}
Pentru problema anterioară se poate efectua o funcţie generală care poate
determina numărul de termeni negativi, nuli şi pozitivi dintr-un vector citit.
Având în vedere că o funcţie poate returna o singură valoare iar în acest caz este
necesară returnarea a 3 valori, se va folosi un tablou c[3] cu 3 termeni. Funcţia care
face acest lucru este numtermv şi va fi salvată în fişierul numtermv.c.
numtermv ( int n, double a[30], double c[3])
{
int poz,neg,nul, i; declarare de variabile locale utilizate de funcţie
poz=0; iniţializarea cu valoarea 0 a variabilelor folosite ca
şi contor
nul=0;
neg=0;
for (i=1;i<=n;i++) ciclul for de parcurgere a tuturor termenilor
vectorului
if (a[i][j]<0) determinarea termenilor negativi
neg=neg+1; adăugarea unei unităţi la contorul neg
else
if(a[i][j]==0) determinarea termenilor nuli
nul=nul+1; adăugarea unei unităţi la contorul nul
else
poz=poz+1; adăugarea unei unităţi la contorul poz
c[0]=poz; transferul valorilor contoarelor în vectorul c
c[1]=nul;
c[2]=neg;
} închiderea corpului funcţiei
Fişierul sursă ce include funcţia numtermv va fi.
#include <conio.h>
LIMBAJUL C TEORIE ŞI APLICAŢI I 88

#include <stdio.h>
#include “citv.c” includerea fişierului citv.c care conţine funcţia
citv
#include “numtermv.c” includerea fişierului numtermv.c care conţine
funcţia numtermv ce determină termenii pozitivi,
nuli, negativi dintr-un vector
void main ()
{
int n, i,c[3];
double b[30];
puts ("dati numarul de zile pt. care s-a citit temperatura n=? ");
scanf ("%d",&n);
puts ("dati temperatura zilelor \n");
citv (n,b) ; apelarea funcţiei de citire a unui vector
numtermv (n,b,c); apelarea funcţiei de determinare a termenilor poz,
nuli, neg.
printf ("zile cu temperaturi pozitive= %d\n",c[0] );
printf ("zile cu temperaturi negative= %d\n",c[2] );
printf ("zile cu temperatura de zero = %d\n",c[1] );
puts ("\n apasa o tasta");
getch ();
}

Exemplu
Să se determine valoarea minimă a presiunii apei în circuitul de alimentare cu apă
al oraşului. Valoarea presiunii este dată din oră în oră pe durata a 24 ore.
Pentru a determina valoarea minimă a presiunii, se vor citi în cele 24 de ore, 24 de
valori într-un vector b şi apoi se va apela funcţia minv, care va returna valoarea
minimă a presiunii apei din circuitul oraşului. Dacă valorile presiunii sunt
transferate automat printr-un sistem de achiziţii de date intr-un fişier, datele vor fi
citite cu o funcţie specială din fişier, apoi se va aplica funcţia minv asupra acestor
date.
Rezolvare
Algoritmul funcţiei minv consă în a alege o variabilă locală min, care iniţial este
egală cu primul termen a vectorului ce se prelucrează, apoi se compară această
variabilă min pe rând cu termenii vectorului. Dacă min este mai mic decât
termenul analizat, valoarea variabilei min rămâne nemodificată, dacă valoarea
variabilei min este mai mare decât termenul analizat, variabilei min i se atribuie
valoarea acelui termen. Parcurgând toţi termenii vectorului, în final variabila min
va conţine valoarea celui mai mic termen al vectorului. Funcţia minv va fi salvată
în fişierul minv.c.
double minv(int n, double a[30]) antetul funcţiei minv ce are ca parametrii
formali: n =numărul de termeni ai vectorului
LIMBAJUL C TEORIE ŞI APLICAŢI I 89

şi a[30] vectorul ce preia termenii vectorului


citit în cadrul programului principal (transfer
prin referinţă). Funcţia returnează spre
funcţia apelantă o valoare de tip double.
{ începutul corpului funcţiei minv,
int i; variabilă locală pentru ciclul for,
double min; variabilă locală folosită la prelucrarea termenilor
vectorului
min=a[1]; iniţializarea lui min cu valoarea primului termen
al vectorului
for (i=1;i<=n;i=i+1) ciclul de comparare a lui min cu toti termeni
vectorului
if (min<=a[i]) condiţia de control a valorii lui min.
; dacă min este mai mic sau egal cu termenul
curent, valoarea lui min nu se modifică
else
min=a[i]; atribuirea lui min a valorii termenului mai mic
decât min
return (min); returnarea valorii lui min spre funcţia apelantă
} închiderea corpului funcţiei minv

Programul principal ce apelează funcţia minv.


#include <conio.h>
#include <stdio.h>
#include “citv.c” includerea fişierului citv.c care conţine funcţia
citv
#include “minv.c” includerea fişierului minv.c care conţine funcţia
minv ce determină valoarea minimă a termenilor
unui vector
void main ()
{
int n, b[30];
double min;
puts ("dati numarul de ore pt. care s-a citit presiunea n=?");
scanf ("%d",&n);
puts ("dati presiunea la ora indicata prin numarul elementului\n");
citv (n,b) ; apelarea funcţiei de citire a unui vector
min=minv (n,b); apelarea funcţiei de determinare a valorii minime
a termenilor.
printf ("presiunea minima în 24 ore= %lf\n", min);
puts ("\n apasa o tasta ");
getch ();
}
Exemplu
Să se determine numărul de apariţii ale unui număr din intervalul 1 la 45 la
tragerile loto din minim 2 extrageri. Numărul de numere asupra cărora se face
studiul este maxim 100 şi aceste numere sunt introduse de la tastatură. Numărul a
LIMBAJUL C TEORIE ŞI APLICAŢI I 90

cărui apariţie se doreşte, este cerut de funcţia static1, iar citirea numerelor
extrase se face cu funcţia citvint pentru numere întregi. Funcţia static1 va fi
salvată în fişierul static1.c.
int static1(int n, int b[100]) funcţia de tip intreg cu doi parametrii de tip int
{ începutul corpului funcţiei
int i,k, sta;
puts ("dati numarul cautat pt determinarea aparitiilor");
scanf ("%d",&sta);
k=0;
for (i=1;i<=n;i=i+1)
if (sta == b[i])
k=k+1;
else
;
return (k); funcţia va returna valoarea întreagă a numărului
de apariţii ale numărului căutat
}

Funcţia citvint va fi salvată în fişierul citvint.c.


citvint (int n, int a[100])
{
int i;
for (i=1;i<=n;i++)
{
printf ("Dati elementul %d =",i);
scanf ("%d",&a[i]);
}
puts ("S-a citit vectorul");
}
Funcţia sfirsit va fi salvată în fişierul sfirsit.c.
void sfirsit () funcţia nu returnează valoare şi nu are parametrii.
{
puts ("\n Apasa o taasta");
getch ();
}
Programul principal statisc1 va fi salvat în fişierul statisc1.c care va apela
funcţiile de citire ale unui vector cu termeni întregi, apoi va apela funcţia de
determinare a apariţiilor unei valori în cadrul vectorului, iar închiderea
programului se face prin apelarea funcţiei sfirsit.
#include <conio.h>
#include <stdio.h>
#include "citvint.c"
#include "static1.c"
#include "sfirsit.c"
void main ()
{
int n,k, a[100];
puts ("dati marimea vectorului ( numarul de valori ) n=?");
scanf ("%d",&n);
LIMBAJUL C TEORIE ŞI APLICAŢI I 91

citvint (n,a); apelarea funcţiei de citire a unui vector cu valori


intregi
k=static1 (n,a ); apelarea funcţiei de căutare a numărului de
apariţii ale unei valori
printf ("numarul de aparitii este =%d\n",k);
sfirsit (); apelarea funcţiei sfirsit
}
Probleme propuse
Observaţie: la rezolvarea problemelor propuse se vor folosi funcţiile deduse la
capitolele anterioare sau se vor realiza noi funcţii de uz general.
1. Să se citească un vector cu termenii de tip intreg şi se determine dacă acest
vector conţine un numar dat şi ce poziţie ocupă acest număr.
Date intrare: n=mărimea vectorului
Ai =termenii vectorului K=numărul căutat
Date ieşire : poziţia ocupată de numărul K
2. Să se citească un vector cu termenii de tip intreg şi să se ordoneze în sens
crescător termenii vectorului.
Date de intrare : n, ai
Date de ieşire : bi vectorul cu termenii ordonaţi.
3. Să se citească doi vectori cu mărimea n cu termenii de tip întreg şi să se
determine vectorul ci care conţine termeni vectorului ai şi termenii necomuni
dintre ai şi bi.
Date de intrare: n=mărimea celor doi vectori ai, bi =termeni vectorilor ai, bi
Date de ieşire : vectorul ci.
4. Să se determine termenul cu valoare maximă dintr-un vector citit de la tastatură.
Date de intrare : n, ai
Date de ieşire : max (ai).
5. Să se calculeze C=A1∙a1+A2∙a2+… Am∙am .
Date de intrare : a1, a2, a3, …, am valori ale unor scalari citiţi de la tastatură
A1, A2, … , An vectori de tip double de mărime n citiţi de la tastatură
Valoarea m =numărul de vectori
m
Date de ieşire : C = Ai ai
i 1

6. Să se compare valorile temperaturii de livrare a apei calde pe o perioadă de 24


ore, (citirile temperaturii s-au făcut în fiecare oră) şi să se compare aceste
temperaturi cu o valoare limită inferioară dată de la tastatură. Dacă valorile
temperaturilor citite sunt sub valoarea de temperatură limită, să se afişeze aceste
valori şi numărul lor.
Date de intrare : valorile temperaturii în 24 ore, valoarea temperaturii limită
LIMBAJUL C TEORIE ŞI APLICAŢI I 92

Date de ieşire : numărul de valori sub temperatura limită, şi aceste valori.


7. Să se citească într-un vector frecvenţa curentului trifazic din oră în oră şi să se
determine dacă această frecvenţă este în afara domeniului de funcţionare normală
dată de intervalul 49.9Hz la 50.1Hz.
Date de intrare : valoarea frecvenţei şi numărul de citiri.
Date de ieşire : numărul de citiri din afara domeniului de funcţionare normală.
8. Să se compare doi vectori de mărimea n, de tip float şi să se deducă vectorul c
care conţine termenii egali din cei doi vectori.
Date de intrare : n, ai, bi
Date de ieşire : ci.

3.8. Operaţii asupra tablourilor cu două dimensiuni.


Să se realizeze funcţii pentru citirea unui tablou cu două dimensiuni şi afişarea
unui tablou cu două dimensiuni. Valorile din tabloul citit sau afişat sunt de tip
double. Un tablou cu două dimensiuni are termenii indexaţi cu doi coeficienţi i şi
j.
a11 a12 a13
a 21 a 22 a 23
a31 a32 a33
Pentru a accesa un termen al tabloului cu două dimensiuni este necesară indicarea
liniei şi coloanei termenului dorit, ceea ce implică folosirea a două cicluri for care
să modifice valoarea independentă a celor doi indici.
Funcţia citm, care efectuează citirea unui tablou bidimensional foloseşte două
cicluri imbricate, ciclul exterior având variabila contor i, care parcurge rândurile
tabloului bidimensional, ciclul interior având variabila contor j, parcurge pentru
fiecare rând, toate coloanele tabloului. Să urmărim modul de incrementare al celor
doi contori. La început, variabila contor a ciclului exterior i va avea valoarea 1 şi
se intră în ciclul interior, adică
i=1, j=1 se va citi termenul de pe primul rând, prima coloană a11
În continuare, se continuă ciclul interior,
i=const =1, j creşte cu o unitate j=j+1=2 se citeşte al doilea termen de pe prima
linie a12

i=1, j=m se citeşte ultimul termen de pe prima linie a1m
Se încheie ciclul interior j şi se creşte cu o unitate variabila contor i. Se reia ciclul
interior, variabila contor j pornind de la 1, pentru a citi termenii de pe linia 2.
i=2, j=1 se citeşte a21
i=2, j=2 se citeşte a22

LIMBAJUL C TEORIE ŞI APLICAŢI I 93

i=2, j=m se citeşte a2m


Se reia ciclul exterior până când se citesc toate elementele tabloului.
Pe acelaşi principiu se efectuează tipărirea elementelor unui tablou cu două
dimensiuni. Pentru a putea fi reutilizată, funcţia citm va fi salvată în fişierul
citm.c
citm (int n, int m,double a[10][10]) funcţia citm cu parametrii n, m, a
{ începutul corpului funcţiei
int i,j; declararea variabilelor locale contor
double t; variabilă necesară citiri valori de tip double
for (i=1;i<=n;i++) primul for ce parcurge liniile tabloului
for (j=1;j<=m;j++) al doilea for ce parcurge coloanele
{
printf ("Dati elementul %d %d=",i,j);
scanf ("%lf",&t);
a[i][j]=t;
}
puts ("S-a citit matricea");
}
Funcţia tipm, care tipăreşte elementele tabloului, este salvată în fişierul tipm.c.
tipm (int n, int m, double a[][10])
{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
printf (" %lf\t ",a[i][j]);
puts ("\n");
}
Programul principal, care apelează funcţiile de citire şi de tipărire a termenilor
unui tablou cu două dimensiuni va fi
#include <conio.h>
#include <stdio.h>
#include "citm.c"
#include "sfirsit.c"
#include "tipm.c"
void main ()
{
int n,m
double a[10][10];
puts ("dati nr de linii n si nr de coloane m numere intregi");
scanf ("%d,%d",&n,&m);
citm (n,m,a); apelarea funcţiei pt citirea unui tablou cu două
dimensiuni
tipm (n,m,a); apelarea funcţiei pt afişarea unui tablou cu două
dimensiuni
sfirsit (); apelarea funcţiei pt terminarea programului
}
Exemplu
LIMBAJUL C TEORIE ŞI APLICAŢI I 94

Să se realizeze programul care adună două matrici şi apoi să se transforme


programul pentru a aduna mai multe matrici, fiecare matrice fiind înmulţită cu un
scalar. Adică,
C=A+B etapa I
C=a1∙A1+a2∙A2+ … an∙An etapa II
unde a1, a2, a3, …..an sunt scalari, respectiv A1, A2, …An sunt tablouri cu două
dimensiuni.

Funcţia summ pentru adunarea a două matrici va fi salvată în fişierul summ.c.


void summ (int l, int o, double d[10][10], double e[10][10],double f[10][10])
{
int i,j;
/*suma a doua matrici */
for (i=1;i<=l;i++)
for (j=1;j<=o;j++)
f[i][j]=d[i][j]+e[i][j]; termenul curent al matricei f este suma
termenilor celor două matrici d şi e
}
Programul principal pentru adunarea a două matrici C=A+B va fi
#include <conio.h>
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "summ.c"
void main ()
{
int i,j,n,m;
double a[10][10],b[10][10],c[10][10];
puts ("dati marimea lui n =? si m = ? numere intregi");
scanf ("%d %d",&n,&m);
citm (n,m,a); apelarea funcţiei de citire a unui tablou cu două
dimensiuni. În cazul tablourilor, variabila tablou a
este transmisă prin referinţă
puts ("S-a citit tabloul a");
citm (n,m,b); apelarea funcţiei de citire a unui tablou cu două
dimensiuni. În cazul tablourilor, variabila tablou b
este transmisă prin referinţă
puts ("\t S-a citit tabloul b\n");
summ(n,m,a,b,c); efectuarea adunării celor două tablouri. Rezultatul
se va găsi în tabloul c.
tipm (n,m,c); afişarea tabloului rezultat prin suma celor două
tablouri
sfirsit ( );
}
Pentru a rezolva etapa a II-a, programul care calculează expresia matriceală
C=a1∙A1+a2∙A2+ … an∙An, vom defini o funcţie care înmulţeşte un tablou cu un
scalar.
LIMBAJUL C TEORIE ŞI APLICAŢI I 95

Funcţia scalarm, înmulţeşte un tablou cu două dimensiuni cu valoarea unui scalar


citit dintr-un vector ; n, m sunt parametrii transferaţi prin valoare ce indică
mărimea tabloului, k parametru ce indică numărul termenului vectorului cu care
se înmulţeşte matricea. Tablourile v[], a[][], b[][] sunt parametrii transferaţi
prin referinţă. Tabloul b[][] va conţine elementele tabloului a[][] înmulţite cu
scalar.
scalarm (int n, int m, int k, double v[10], double a[10][10],double b[10][10])
{
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
b[i][j]=a[i][j]*v[k]; operaţia de înmulţire cu un scalar a termenilor
unui tablou
}
Rezolvarea propriu zisă a expresiei matriceale este făcută în programul principal, salvat
în fişierul matmul2.c.
#include <conio.h>
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "citv.c"
#include "summ.c"
#include "scalarm.c"
#include "sfirsit.c"
void main ()
{
int i,j,n,m, k;
double a[10][10],b[10][10],c[10][10], v[10];
puts ("dati marimea lui n =? si m = ? numere intregi");
scanf ("%d %d",&n,&m);
puts ("dati numarul de matrici ce se aduna k = ? ");
scanf ("%d",&k);
puts ("dati scalari a1, a2...an");
citv (k,v); citirea vectorului ce conţine scalarii a1, a2, an
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
c[i][j]=0; iniţializarea matricii c cu valoarea zero
for (i=1;i<=k;i++) la fiecare ciclu se efectuează citirea,
înmulţirea matricii Ak cu un scalar şi suma
matricilor
{
printf ("dati termenii matricei %d \n",i);
citm (n,m,a); citirea matricii Ak
scalarm (n, m, i, v, a, b); înmulţirea matricii Ak cu scalarul ak
summ(n,m,c,b,c); adunarea matricii Ak∙ak la matricea sumă C
}
tipm (n,m,c); afişarea matricii C
sfirsit ( );
}
Exemplu
LIMBAJUL C TEORIE ŞI APLICAŢI I 96

Să se scrie programul C, ce înmulţeşte două matrici C=A∙B. Înmulţirea a două matrici


are loc dacă numărul de linii ale primei matrici este egal cu numărul de coloane ale
celei de-a doua matrici.
b11 b12
a11 a12 a13 c11 c12
De exemplu, C=A∙B= ∙ b21 b22 = .
a21 a22 a23 c21 c22
b31 b32
Termenul de pe rândul 1, coloana 2 a matricii C se obţine, însumând produsele
elementelor de pe rândul 1 al matricii A cu
elementele din coloana 2 a matricii B. Adica,
n
c12= a11∙b12+a12∙b22+ … +a1i∙bi2+… +a1n∙bn2= a1i bi 2 . Un termen oarecare al
i 1
matricii C, se va obţine volosind expresia
n
cij = aik bkj ,
k 1

unde n reprezintă numărul de coloane ale matricii A, sau linii ale matricii B.
Pentru calculul propriu zis al sumei în C, vom avea nevoie de trei cicluri ; un ciclu
exterior care parcurge numărul de rânduri ale matricii C, un ciclu interior care
parcurge coloanele matricii C, respectiv un ciclu care efectuează suma produselor
folosind relaţia de mai sus.
Funcţia prodmat care calculează produsul a două matrici este salvată în fişierul
prodmat.c. Dacă matricea din stânga, A, are dimensiunea m n, matricea din
dreapta B, n p, matricea rezultată C, va avea dimensiunea m p.
prodmat(int m, int n, int p, int a[10][10], int b[10][10], int c[10][10])
{
int i,j,k;
for (i=1; i<=m; i++)
for (j=1; j<=p; j++)
{
c[i][j]=0; iniţializarea termenilor matricii rezultate cu
valoarea 0
for (k=1; k<=n; k++) ciclul necesar pentru calculul sumei
produselor aik∙bkj
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
} închiderea corpului funcţiei prodmat
Programul principal, care apelează funcţia prodmat, este salvată în fişierul
prodmat1.c
#include <conio.h>
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "prodmat.c"
void main ()
LIMBAJUL C TEORIE ŞI APLICAŢI I 97

{
int i,j,n,m,p;
double a[10][10],b[10][10],c[10][10];
puts ("dati marimea lui m, n si p numere intregi");
scanf ("%d %d %d", &m, &n, &p);
citm (m,n,a); se citeşte matricea A de dimensiune m n
puts ("S-a citit tabloul a\n");
citm (n,p,b); se citeşte matricea B de dimensiune n p
puts ("S-a citit tabloul b\n");
prodmat(m,n,p,a,b,c); se calculează matricea C=A∙B
tipm (m,p,c); se tipăreşte matricea C de dimensiune m p
sfirsit ( );
}
Exemplu
Să se realizeze un program care să adune termenii de deasupra diagonalei
principale şi de pe diagonala principală, a unui tablou cu două dimensiuni.
Rezolvare
Pentru a parcurge doar termenii de deasupra diagonalei principale, ciclul exterior
va parcurge toate rândurile matricii, începând cu rândul 1, pe când ciclul interior
va parcurge coloanele matricii începând de la coloana j=i. Funcţia care adună
termenii de deasupra diagonalei principale, inclusiv diagonala principală are
numele sumsup şi va fi salvată în fişierul sumsup.c. Putem vorbi de diagonală
principală doar în cazul matricilor pătratice, adică de dimensiune n n.
double sumsup (int n, double a[10][10])
{
int i, j;
double s;
s=0; iniţializarea sumei cu 0
/*se aduna termenii de deasupra si diagonala principala*/
for (i=1; i<=n; i++)
for (j=i; j<=n; j++) ciclul care parcurge coloanele matricii a
s=s+a[i][j]; calcului sumei termenilor
return (s); returnarea sumei spre funcţia apelantă
}
Pentru a se verifica dacă algoritmul folosit este corect, se vor afişa termenii de pe
diagonala principală şi de deasupra diagonalei
principale, folosind funcţia tipsupm. Funcţia
tipsupm va fi salvată în fişierul tipsupm.c.
tipsupm (int n, double a[10][10])
{
int i,j;
/*se afiseaza termenii de deasupra si de pe diagonala principala*/
for (i=1; i<=n; i++)
{
puts ("\n");
for (j=i; j<=n; j++)
printf ("%lf\t",a[i][j]);
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 98

}
Exemplu
Să se scrie o funcţie care afişează termenii de sub diagonala principală a unei
matrici pătratice.
Rezolvare
Algoritmul folosit se bazează pe observaţia prezentată în exemplul precedent ; un
ciclu exterior care parcurge rândurile matricii, respectiv un ciclu interior care
parcurge coloanele matricii începând cu prima coloană, până la coloana de pe
diagonala principală, adică j=i. Funcţia care afişează termenii de sub diagonala
principală a unei matrici pătratice se numeşte tipinfm şi va fi salvată în fişierul
tipinfm.c.
tipinfm(int n, double a[10][10])
{
int i, j;
/*se afiseaza termeni de sub diagonala principala*/
for (i=1; i<=n; i++)
{
puts("\n");
for(j=1; j<=i; j++) ciclul care parcurge coloanele matricii a
printf("%lf\t",a[i][j]);
}
}
Exemplu
Vom încerca să punem toate funcţiile prezentate mai sus într-un program
principal. Programul va calcula suma termenilor unei matrici pătratice, situaţi
deasupra diagonalei principale, inclusiv elementele de pe diagonală, afişarea
termenilor care se adună, precum şi termenii de sub diagonala principală. Citirea
mărimii matricii, valoarea termenilor ei se va face de la tastatură, pentru citirea
termenilor se va apela funcţia citm.
Rezolvare
#include <conio.h>
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "sumsup.c"
#include "tipsupm.c"
#include "tipinfm.c"
#include "sfirsit.c"
void main ()
{
int i,j,n;
double a[10][10], s;
puts ("dati marimea matricii patratice n =? numar intreg");
scanf("%d",&n);
/*citirea matricii [a]*/
citm (n,n,a);
puts ("S-a citit matricea [a]");
s=sumsup(n,a);
tipsupm (n,a);
LIMBAJUL C TEORIE ŞI APLICAŢI I 99

printf (“suma termenilor deasupra diagonalei principale =%lf ”,s);


tipinfm (n,a);
tipm (n,n,a);
sfirsit ( );
}
Probleme propuse
1. Să se adune termenii de pe linia k a unei matrici A de dimensiune n m.
Date de intrare : dimensiunea matricii n, m , termenii matricii şi numărul liniei k.
m
Date de ieşire : s= akj
j 1

2. Să se adune termenii de pe coloana k a unei matrici A de dimensiune n m.


Date de intrare : dimensiunea matricii n, m , termenii matricii şi numărul coloanei
k.
n
Date de ieşire : s= aik
i 1

3. Să se compare două matrici de dimensiune n m şi să se deducă vectorul c care


conţine termenii cu valoare egală din cele două matrici .
Date de intrare : n, m, aij, bij
Date de ieşire : ci
4. Să se citească o matrice A de dimensiune n n şi să se evalueze următoarea
expresie matriceală B=A+I, unde I este matricea unitate.
Date de intrare : n, A.
Date de ieşire : B
5. Să se adune termenii pozitivi de sub diagonala secundară a matricii A de
dimensiune n n.
Date de intrare : n, A
Date ieşire : s=suma termenilor de sub diagonala secundară.
6. Să se determine numărul termenilor pozitivi, negativi, nuli şi să se calculeze
sumele acestor termeni, din matricea A citită de la tastatură.
Date de intrare : n, m dimensiunea matricii; A
Date de ieşire : numărul termenilor pozitivi, negativi, nuli, suma termenilor
pozitivi, suma termenilor negativi.

3.9. Funcţii de bibliotecă.


Limbajul C a fost realizat ca un limbaj cu un set relativ redus de comenzi, pentru a
avea o viteză de execuţie şi flexibilitate mare. Astfel limbajul C nu are încorporat
facilităţi de prelocrare şi citire directă a şirurilor de caractere, mulţimilor,
tablourilor. Pentru prelucrarea datelor de tip şir de caractere se folosesc tablouri
de caractere sau pointeri la caracter. Limbajul C nu are instrucţiuni de citire,
tipărire (operaţii de intrare ieşire) a datelor, nu are instrucţiuni de acces la fişiere.
LIMBAJUL C TEORIE ŞI APLICAŢI I 100

Pentru aceste operaţii limbajul C oferă o colecţie de funcţii standard de bibliotecă.


În continuare se vor prezenta funcţiile de bibliotecă cele mai folosite în cadrul
programelor.

3.9.1. Funcţii de intrare ieşire.


Aceste funcţii sunt :
getch , gets, scanf pentru citirea datelor
putch, puts, printf pentru tipărirea datelor.
Funcţiile de intrare/ieşire au prototipul în fişierele antet stdio.h şi conio.h., şi au
fost detaliate în capitolul 5.5.

3.9.2. Funcţii matematice.


Funcţiile matematice au prototipul în fişierul antet math.h. În tabelul de mai jos
este prezentată o listă exhaustivă a funcţiilor matematice ; prototipul lor precum şi
efectul fiecărei funcţii în parte.
Prototipul funcţiei Efectul funcţiei
double acos (double x) arccosinus de x
double asin (double x) arcsinus de x
double atan (double x) arctangenta de x
double atan2(double y, double x) arctangenta de y/x
double ceil (double x) cel mai mic întreg mai mare sau egal cu x
double cos (double x) cosinus de x (x exprimat în radiani )
double exp (double x) valoarea lui ex
double fabs (double x) valoarea absolută a lui x
double floor (double x) cel mai mare întreg mai mic sau egal cu x
double log (double x) ln de x
double log10 (double x) lg de x
double pow (double x, double y) x la puterea y
double sin (double x) sinus de x (x exprimat în radiani )
double sqrt (double x) Radicalul de ordinul 2 a lui x
double tan (double x) tangenta lui x (x exprimat în radiani )
double sinh (double x) sh x
double coshn (double x) ch x
double tanh (double x) th x
double fmod (double x, double y) Returnează restul operaţiei x/y
double modf (double n,double *i) Descompune n în parte intreagă şi
fracţionară, returnează partea fracţională, iar
partea întreagă în i
double frexp (double n, int*exp) Descompune n în mantisă 0,5 la 1 şi
exponentul lui 2, astfel n=mantisa*2^exp
double ldexp (double n, int exp) Returnează valoarea lui n*2^exp
Tot în fişierul math.h sunt următoarele funcţii :
LIMBAJUL C TEORIE ŞI APLICAŢI I 101

double cabs (struct complex z); returnează modulul numărului complex z


double poly (double x, int n, double c[]); returnează valoarea polinomului în x
de grad n, coeficienţii sunt situaţi în tabelul c în următoarea ordine :
c[0] = coeficientul termenului liber
1
c[1] = coeficientul lui x
n
c[n] = coeficientul lui x
În fişierul stdlib.h sunt declarate următoarele funcţii :
int abs(int x) returnează valoarea absolută a lui x de tip întreg
long labs(long x) returnează valoarea absolută a lui x de tip long
int rand(void) returnează un număr natural aleator mai mic de 32768
int random(int n) returnează un număr natural aleator mai mic decât n.
3.9.3. Funcţii de uz general.
void clrscr(void) şterge tot ecranul (clear screen)
int kbhit(void) returnează o valoare diferită de zero dacă există un caracter
disponibil de la tastatură, sau returnează valoarea zero în caz contrar.
În fişierul dos.h sunt declarate funcţiile pentru oprirea execuţiei programului pe o
durată stabilită, respectiv funcţii de producere de sunete cu frecvenţa dorită.
void delay(unsigned i) suspendă execuţia programulu pentru o durată de i
milisecunde
void sleep(unsigned n) suspendă execuţia programulu pentru o durată de n
secunde
void sound(unsigned h) trimite spre difuzorul calculatorului un sunet cu
frecvenţa =h
void nosound(void) opreşte sunetul trimis de sound la difuzor.
char *ctime (const time_t *t) funcţia returnează un pointer către şirul ce
cuprinde zi, luna, data, ora, minute, secunde, anul.
time_t time (time_t *timp) funcţia time returnează ora curentă a sistemului, dacă
sistemul nu poate returna ora curentă, funcţia va returna valoarea –1
struct tm *localtime (const time_t*timp) funcţia localtime returnează un
pointer către variabila timp de forma unei structuri de tip tm
char *asctime (const struct tm *p) funcţia asctime converteşte informaţia din
structura indicată de pointerul p intr-un şir de forma: zi, luna, data, ora, minute,
secunde, anul şi returnează un pointer către şirul convertit.
Double diftime (time_t t2, time_t1) funcţia diftime returnează diferenţa de
timp dintre t2 şi t1 exprimată în secunde.
Funcţiile pentru gestionarea timpului sunt disponibile în time.h.
Exemplu.
Sî se determine timpul în secunde necesar pentru a parcurge ciclul for şi să se
afişeze timpul loca şi timpul universal.

#include <stdio.h>
#include <conio.h>
#include <time.h>
void main ()
LIMBAJUL C TEORIE ŞI APLICAŢI I 102

{
struct tm *local,*g; declarare de structuri de tip tm ce memorează data
şi ora descompuse în elementele lor constitutive :
secunde, minute, ore, ziua, luna, an.
double dt,i;
time_t t,t1,t2; declararea de dată de tip long integer pentru dată
calendaristică
t=time (NULL); returnarea orei curente calendaristice a sistemului
local =localtime (&t); returnează către pointerul local în forma unei
structuri de tip tm a timpului local generat de
apelul funcţiei time
t1=time (NULL);
for (i=0;i<=30000;i++)
t2=time (NULL);
dt=difftime (t2, t1); funcţia difftime calculează diferenţa de timp
dintre t2 şi t1 exprimat în secunde
printf ("Data si ora este %s\n",asctime (local)); convertirea datei din
structura local într-un şir de caractere de forma zi,
luna, data, ora, minute, secunde,an, pentru a putea
fi afişat
g=gmtime (&t); funcţia gmtime returnează la pointerul g a
timpului reprezentat ca timp cordonat universal
printf ("Data si ora universal %s\n",asctime (g));
printf ("durata ciclului for in secunde =%lf\n",dt);
puts ("\n Apasa o tasta ");
getch ();
}

div_t div (int numarator, int numitor) funcţia div returnează câtul şi restul
împărţirii numărător/numitor într-o structură de
tipul div_t, structura div_t conţine două valori de
tip întreg cu denumirile :
qout= câtul , rem =restul.

ldiv_t ldiv (long numarator, long numitor) funcţia div returnează câtul
şi restul împărţirii numărător/numitor într-o
structură de tipul ldiv_t, structura ldiv_t conţine
două valori de tip long cu denumirile :
qout= câtul , rem =restul.

void srand (unsigned i) funcţia srand stabileşte punctul de început = i


pentru secvenţa generată de rand (), ca valoare a
lui i se poate folosi valoarea returnată de funcţia
time (NULL), care este continu modificată de
ceasul sistemului.
LIMBAJUL C TEORIE ŞI APLICAŢI I 103

int system (const char *sir) funcţia system () transferă conţinutul şirului sir ca
instrucţiune de tip comandă pentru sistemul de
operare.

#include <stdlib.h>
void main ()
{
system (“dir c:\tempc”); are ca efect afişarea conţinutului directorului
TEMPC de pe discul C.
}

Pentru apelarea funcţiilor div (), ldiv (), srand () şi system () se va include
fişierul stdlib.h.
Exemplu.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void main ()
{
div_t n;
double dt,i;
int tt,tt1;
long t,t1,t2;
t=time (NULL);
for (i=0;i<30000;i++);
t1=time (NULL);
system ("dir /p c:\\tempc"); apelarea comenzi dir din sistemul de operare cu
parametri indicaţi de şirul dintre “”

tt=(unsigned) t/2; conversia datei t de tip long in dată de tip int fără
semn

tt1=23400;
n=div (tt1,tt); detrminarea câtului şi restului dintre tt1/tt

printf ("%d %d citul=%d restul=%d \n",tt1, tt,n.quot, n.rem);


afişarea celor două numere şi apoi câtul şi restul
ca valori ale structuri n de tip div_t

srand (tt); funcţia srand va livra o valoare pentru secvenţa de


numere aleatoare date de funcţia rand ()

printf ("punct de inceput =%d numele aleator rezultat= %d\n",tt,rand ());


puts ("\n Apasa o tasta ");
getch ();
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 104

3.9.4. Funcţii de conversie.

Funcţia atoi converteşte intregul zecimal definit de şirul de caractere sir şi


returnează valoarea acestui întreg.
Prototipul funcţiei atoi este :

int atoi (const char *sir);

Exemplu.

#include <stdio.h>
#include <conio.h>
void main ()
{
char st [10] ;
int i ;
gets (st) ;
i= atoi (st) ;
printf (“s-a convertit sirul de caractere numerice in valoarea de tip
intreg %d ”,i);
}

Dacă se tastează şirul de caractere 123 în urma conversiei se va afişa întregul cu


valoarea 123.

Funcţia atol converteşte în întreg zecimal de tip long int, şirul de caractere sir
şi returnează valoarea acestui întreg.
Prototipul funcţiei atol este :

int atol (const char *sir);

Exemplu.

#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{
char sir1 [15] , sir2 [15];
long int a ;
puts ("Se converteste sirul de caractere format din cifre in int long");
puts ("dati primul sir de caractere format din cifre");
scanf ("%s",sir1);
puts ("dati al doilea sir de caractere format din cifre");
scanf ("%s",sir2);
a=atol (sir1)+ atol (sir2) ;
printf ("suma celor doua siruri convertite = %ld", a);
LIMBAJUL C TEORIE ŞI APLICAŢI I 105

puts ("\n Apasa o tasta ");


getch ();
}

Funcţia itoa converteşte valoarea binară de tip întreg în întreg cu baza de


numeraţie definită de baza şi păstrează rezultatul conversiei sub formă de şir de
caractere.
Prototipul funcţiei itoa este :

char* itoa (int valoare, char *şir, int baza) ;

valoare = este valoarea binară de tip intreg ce se converteşte


şir = este pointerul spre zona în care se păstrează rezultatul
conversiei
baza =baza de numeraţie pentru întregul rezultat în urma convertiri.
Exemplu.

Să se convertească o valoare întreagă < 26000 într-un şir de caractere, folosind ca


bază de conversie sistemul octal (8) .
Valoarea întregului se introduce de la tastatură.

#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{
char sir [15]; şirul de caractere în care se va păstra rezultatul
conversiei
int a ;
puts ("dati un numar in baza 10");
scanf ("%d",&a);
puts ("se converteste intregul in sir de caractere echivalent in baza 8
");
itoa (a,sir,8) ; apelarea funcţiei de conversie itoa, care
converteşte valoarea întreagă a in valoare octală
(8) şi depozitează valoare convertită în şirul de
caractere sir

printf ("sirul rezultat in urma conversiei = %s", sir);


puts ("\n Apasa o tasta ");
getch ();
}

Exemplu.
LIMBAJUL C TEORIE ŞI APLICAŢI I 106

Să se convertească o valoare întreagă < 26000 într-un şir de caractere, folosind ca


bază de conversie o valoare întreagă între 2 şi 16.
Valoarea întregului ce se converteşte, cât şi valoarea bazei de conversie se
introduc de la tastatură.
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{
char sir [15];
int a,b ;
puts ("dati un numar in baza 10");
scanf ("%d",&a);
puts ("dati valoarea bazei de conversie 2,3,4,5,6,7,8,16");
scanf ("%d",&b);
printf ("se converteste intregul in sir de caractere echivalent in baza %d
",b);
itoa (a,sir,b) ;
printf ("sirul rezultat in urma conversiei = %s", sir);
puts ("\n Apasa o tasta ");
getch ();
}

Funcţia ltoa converteşte valoarea binară de tip long int în întreg cu baza de
numeraţie definită de baza şi păstrează rezultatul conversiei sub formă de şir de
caractere.
Prototipul funcţiei ltoa este :

char* ltoa (long int valoare, char *şir, int baza) ;

valoare = este valoarea binară de tip long întreg ce se converteşte


şir = este pointerul spre zona în care se păstrează rezultatul
conversiei
baza =baza de numeraţie pentru întregul rezultat în urma convertiri.
Exemplu.

Să se convertească o valoare întreagă de tip long într-un şir de caractere, folosind


ca bază de conversie o valoare întreagă între 2 şi 16.
Valoarea întregului ce se converteşte cât şi valoarea bazei de conversie se
introduc de la tastatură.

#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 107

char sir [15];


long int a ;
int b ;
puts ("dati un numar in baza 10 de tip long int");
scanf ("%ld",&a);
puts ("dati valoarea bazei de conversie 2,3,4,5,6,7,8,16");
scanf ("%d",&b);
printf ("se converteste intregul in sir de caractere echivalent in baza %d
",b);
ltoa (a,sir,b) ;
printf ("sirul rezultat in urma conversiei = %s", sir);
puts ("\n Apasa o tasta ");
getch ();
}

3.10. Pointeri.
Pointerii sunt un tip de variabile particulare. O variabilă de tip pointer poate reţine
adresa unei variabile. Pointerii sunt asociaţi pentru fiecare tip de dată a limbajului
C. Declararea unei variabile pointer se face:
tip de data *nume_variabila_pointer;
Pentru a declara o variabilă pointer trebuie folosit operatorul de indirectare *.
Operatorul indirectare * este folosit pentru a accesa valoarea pe care variabila
pointer o indică.
#include <stdio.h>
void main ()
{
int *pa;
printf("\nVariabila pa are valoarea %p", pa);
printf("\nValoarea stocata in locatia %p este %d", pa, *pa);
*pa=3;
printf("\nVariabila pa are valoarea %p", pa);
printf("\nValoarea stocata in locatia %p este %d", pa, *pa);
}
Programul va afişa pe ecran:
Variabila pa are valoarea 06CB
Valoarea stocata în locatia 06CB este 28256
Variabila pa are valoarea 06CB
Valoarea stocata în locatia 06CB este 3
Să disecăm programul prezentat mai sus. In zona de declarare a variabilelor am
declarat o variabilă de tip pointer cu numele pa (atenţie la operatorul de
indirectare în faţa numelui variabilei). Prima instrucţiune printf() tipăreşte
valoarea variabilei pointer pa. Specificatorul de format pentru variabilele de tip
pointer este %p. Observăm că valoarea varibilei pointer este afişată în format
hexazecimal. (Valoarea acestei variabile este arbitrară, în cazul nostru este 06CB,
dar pe alte calculatoare poate avea o altă valoare). Valoarea 06CB reprezintă o
locaţie de memorie. Următoarea instrucţiune printf() tipăreşte valoarea de tip
LIMBAJUL C TEORIE ŞI APLICAŢI I 108

întreg care este stocată la adresa 06CB. Valoarea care este tipărită 28256 este
arbitară, pentru că nu am influenţat cu nimic această locaţie de memorie.
Următoarea instrucţiune este o instrucţiune de atribuire *pa=3;. Această
instrucţiune modifică valoarea care este stocată în locaţia de memorie 06CB la 3.
Ne putem convinge de asta prin următoarele două instrucţiuni printf(). Valoarea
pointerului nu s-a modificat, dar s-a modificat valoarea întreagă care este stocată
la adresa 06CB.
Atunci când a fost prezentată instrucţiunea scanf(), am amintit de operatorul
adresă &. Operatorul adresă permite determinarea adresei unei variabile (locaţia
de memorie în care variabila respectivă este stocată).
#include <stdio.h>
void main ()
{
int a=2;
int *pa;
printf("\nVariabila pointer pa are valoarea %p", pa);
printf("\nPointerul pa este stocat la adresa %p", &pa);
printf("\nVariabila a are valoarea %d", a);
printf("\nIntregul a este stocat la adresa %p", &a);
pa=&a;
printf("\nVariabila pointer pa are valoarea %p", pa);
printf("\nPointerul pa este stocat la adresa %p", &pa);
printf("\nVariabila a are valoarea %d", a);
printf("\nIntregul a este stocat la adresa %p", &a);
}
Să disecăm acest program. În partea de declarare a variabilelor, am declaarat o
variabilă de tip întreg şi am iniţializat-o cu 2, respectiv o variabilă pointer de tip
întreg pa. Primele patru instrucţiuni printf() care urmează vor afişa pe ecran:
Variabila pointer pa are valoarea 006B
Pointerul pa este stocat la adresa FFD8
Variabila a are valoarea 2
Intregul a este stocat la adresa FFD6
Reţineţi că pentru afişarea adresei unei variabile am folosit tot specificatorul de
format %p. Instrucţiunea de atribuire pa=&pa; va atribui pointerului valoarea
adresei variabilei a. După această instrucţiune, programul va afişa din nou patru
rânduri folosind instrucţiunea printf():
Variabila pointer pa are valoarea FFD6
Pointerul pa este stocat la adresa FFD8
Variabila a are valoarea 2
Intregul a este stocat la adresa FFD6
Observăm că variabila pointer este nemodificată. Ea conţine de data aceasta
valoarea adresei variabilei a. Celelalte valori sunt nemodificate: adresa
pointerului, valoarea variabilei a şi adresa variabilei a.
Să încercăm să punem cei doi operatori împreună. Să ne imaginăm următorul
program:
#include <stdio.h>
void main ()
LIMBAJUL C TEORIE ŞI APLICAŢI I 109

{
int a=2;
int *pa;
pa=&a;
*pa=3;
printf("\nVariabila a are valoarea %d", a);
}
Dacă rulăm programul de mai sus, pe ecran va fi afişat mesajul:
Variabila a are valoarea 3
Când s-a întâmplat asta? Nu am modificat de loc valoarea variabilei a printr-o
atribuire şi totuşi valoarea ei este 3 în loc de 2. De fapt, prima instrucţiune de
atribuire pa=&a; atribuie variabilei pointer pa adresa variabilei a (deci variabila
pointer indică către locaţia de memorie în care este păstrată variabila a.
A doua instrucţiune de atribuire *pa=3; atribuie locaţiei indicate de pointer
valoarea 3. Dar locaţia indicată de pointer este locaţia unde este păstrată variabila
a, deci de fapt am modificat valoarea variabilei a..
De fapt, pointerii sunt folosiţii pentru a putea returna mai multe valori din funcţii.
Am văzut în paragraful referitor la funcţii, că transmiterea parametrilor se face
prin valoare. Să ne imaginăm următoarea problemă:
Exemplu
Să se scrie un program C, care calculează soluţiile ecuaţiei de gradul II într-o
funcţie. Citirea datelor de intrare şi tipărirea datelor de ieşire să fie făcută în
funcţia void main ().
Rezolvare
Ştim de la funcţii, că o funcţie în C nu poate returna decât o singură valoare
folosind instrucţiunea return(). Să încercăm să scriem programul sub această
formă:
#include <stdio.h>
#include <math.h>
int ec2(float, float, float, float, float);

void main ()
{
int rez;
float a, b, c, x1, x2;
printf("\nProgram care rezolva ecuatia de gradul II ax^2+bx+c=0");
printf("\nIntroduceti coeficientii a, b si c");
scanf("%f %f %f", &a, &b, &c);
rez=ec2(a, b, c, x1, x2);
if (rez == 1)
printf ("Solutiile ecuatiei sunt x1=%f si x2=%f", x1, x2);
else
printf ("Ecuatia are solutii imaginare");
}

int ec2(float a, float b, float c, float x1, float x2)


{
float d;
LIMBAJUL C TEORIE ŞI APLICAŢI I 110

d=b*b-4*a*c;
if (d < 0)
return (0);
else
{
x1=(-b-sqrt(d))/2/a;
x2=(-b+sqrt(d))/2/a;
return (1);
}
}
Dacă vom introduce pentru coeficienţi valorile 1, -3 şi 2 pentru care soluţia
ecuaţiei este 1 şi 2, programul va afişa:
Solutiile ecuatiei sunt x1=0.000000 si x2=0.000000
De ce? Pentru că la apelul funcţiei ec2() din funcţia void main (), nu se transmit
variabilele x1 şi x2 (sau mai corect spus adresele variabilelor) ci valorile lor. In
funcţia ec2() variabilele x1 şi x2 care apar în lista parametrilor formali, sunt două
variabile locale care nu sunt aceleaşi cu variabilele x1 şi x2 declarate în funcţia
void main (). La revenirea din funcţia ec2() variabilele x1 şi x2 (din funcţia void
main ()) sunt nemodificate.
Rezolvarea problemei se face apelând funcţia ec2() cu adresele variabilelor x1 şi
x2. In funcţia ec2() vom atribui noile valori direct în adresa variabilei x1 şi x2 din
funcţia void main (). Fişierul sursă corect este prezentat în continuare:
#include <stdio.h>
#include <math.h>
int ec2(float, float, float, float *, float *);

void main ()
{
int rez;
float a, b, c, x1, x2;
printf("\nProgram care rezolva ecuatia de gradul II ax^2+bx+c=0");
printf("\nIntroduceti coeficientii a, b si c");
scanf("%f %f %f", &a, &b, &c);
rez=ec2(a, b, c, &x1, &x2);
if (rez == 1)
printf ("Solutiile ecuatiei sunt x1=%f si x2=%f", x1, x2);
else
printf ("Ecuatia are solutii imaginare");
}

int ec2(float a, float b, float c, float *x1, float *x2)


{
float d;
d=b*b-4*a*c;
if (d < 0)
return (0);
else
{
*x1=(-b-sqrt(d))/2/a;
*x2=(-b+sqrt(d))/2/a;
return (1);
LIMBAJUL C TEORIE ŞI APLICAŢI I 111

}
}
Lista parametrilor formali ai funcţiei ec2() este float a, float b, float c, float *x1,
float *x2, deci 3 variabile de tip float şi două variabile de tip pointer la float. In
interiorul funcţiei ec2() operaţiile de atribuire sunt *x1=… şi *x2=…, adică se
depun noile valori calculate în adresele indicate de pointerul x1 şi pointerul x2.
Apelul funcţiei ec2() din funcţia void main (), se face sub forma ec2(a, b, c, &x1,
&x2); adică se transmit valorile variabilelor a, b şi c, precum şi adresa variabilei
x1, respectiv a variabilei x2.

3.11. Structuri şi tipuri definite de utilizator.


Datele prelucrate de programe pot fi singulare sau grupate, cele singulare au fost
prezentate în capitolele anterioare.
Datele grupate sunt mulţimi de elemente care pot fi prelucrate atât element cu element
cât şi global. Un tip de date grupate sunt tablourile, dar ele implică că toate elementele
tabloului sunt de aceleaş tip.
Sunt situaţii când se doresc gruparea de date de diferite tipuri exemplu :
Data calendaristică formată din 3 elemente zi, lună, an, unde :
zi este de tip numeric
lună este de tip şir de caractere
an este de tip numeric
Această grupare de date poartă numele de structură.
Referirea la elementele structuri se face prin construcţii de felul numelui.
Structurile sunt date care se pot aloca :
Global
Automatic
Static
Structura se consideră globală dacă a fost declarată în afara corpului oricărei funcţii, se
consideră automatică, dacă a fost declarată în corpul unei funcţii, se consideră statică
dacă declaraţia ei are prefixul cuvintul static.
Elementele care sunt componente ale structurii pot fi iniţializate astfel, după declararea
structurii se scrie caracterul = , urmat de construcţiile prin care se iniţializează
componentele elementare ale structurii, valorile sunt cuprinse între paranteze acolade.
Valorile sunt separate prin virgulă intre ele astfel :
Se consideră o structură pentru păstrarea numerelor complexe ce au două
componente :
Partea reală
Partea imaginară

Se consideră structura nume_complex cu două elemente :

struct nume_complex
{
float real ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 112

float imaginar ;
} ;

Se consideră că variabila x este o structură de tipul nume_complex prin declaraţia de


mai jos :
struct nume_complex x ;

Dacă se doreşte iniţializarea elementelor ce compun variabila x de tip complex, se


foloseşte declaraţia de forma :

struct nume_complex x = {2.3, 4.0} ;

Astfel variabila x de tip nume complex va avea iniţializate elementele, real cu valoarea
2.3 iar imaginar cu valoarea 4.0.
3.11.1. Declaraţie de structură.
Declararea unei structuri se poate face prin două moduri, cuvântul de început pentru o
structură este struct .
Modul 1

struct numele structuri


{
lista de declaratii
}
numele structurii1, numele structurii2….numele structuriin ;

numele structuri, numele structurii1, numele structurii2.. sunt nume date


variabilelor de aceleaş fel şi obligatoriu unul din aceste nume trebuie să fie prezent.
Dacă numele structuri este prezent , el defineşte o structură nouă, iar numele
structurii1, numele structurii2 definesc variabile de tipul nume structură .
Exemplu.

struct complex
{
float real ;
float imaginar ;
}
x,y,z ;
Astfel compex este numele noi structuri ce are două elemente de tip float, iar x,y,z
sunt variabile structură de tip complex.

struct data_calendar
{
int zi ;
char luna [15];
int an ;
}
data_nasterii, data_inscrierii ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 113

Structura data_calendar are trei elemente de tip intreg,caracter şi intreg.


Data_ nasterii şi data_inscrierii sunt variabile de tip structură ca structura
data_calendar.
Dacă se doreşte realizarea a două variabile de tip structură asemănătoare cu
structura data_calendar dar nu se doreşte tipul data_calendar se foloseşte forma :

struct
{
int zi ;
char luna [15];
int an ;
}
data_nasterii, data_inscrierii ;

Modul 2
struct nume nume de structura ;
nume este o structură declarată anterior prin modul 1, iar nume de structura reprezintă
o nouă structură asemănătoare cu structura nume.
Definirea unei structuri noi cu numele complex.
struct complex
{
float real ;
float imaginar ;
};
Definirea a 3 variabile x,z,y, (structuri) de tipul complex.

struct complex x,y,z ;


definirea a două tablouri a [10], b[2][2], de tipul complex.
struct complex a[10],b [2][2] ;
În cadrul unei structuri la declararea elementelor ce formează structura se poate folosi
şi element de tip structură, cu obligativitatea ca structura folosită la declararea
elementului să fie deja realizată.
Se declară structura date_personale care conţine ca element şi structura data_calendar.

struct data_personal
{
char nume ;
char prenume ;
struct data_calendar
data_nasteri ;
char adresa ;
char localitatea ;
} ;

Astfel elementul data_nasteri este la rândul său o structură definită anterior cu 3


elemente.
LIMBAJUL C TEORIE ŞI APLICAŢI I 114

3.11.2. Accesul la elementele unei structuri.


Referirea la componentele unei structurise face utilizând două informaţii, una este
numele structurii şi a două este numele componentei structurii. Pentru aceasta se
foloseşte construcţia de forma :
Nume structură.numele elementului structurii
Separatorul între numele structuri şi numele elementului este caracterul punct .
Exemplu.
Se consideră structura complex cu 2 elemente componente şi se doreşte atribuirea
elementului reale a valori 2.1 iar a elementului imaginar valoarea 3.11.

struct complex
{
float real ;
float imaginar ;
}
x,a[3] ;

atribuirea valorilor pentru x se face astfel :


x.real=2.1;
x.imaginar=3.11;

iar pentru elementele variabilei a [2] se face astfel :

a[2].real=2.1;
a[2].imaginar=3.11;
Dacă în cadrul structurii sunt elemente ce la rândul lor sunt structură, atribuirea de
valori la elemente se realizează prin indicarea succesivă a elementelor astfel :

struct data_calendar
{
int zi ;
char luna [15];
int an ;
};

struct data_personal
{
char nume ;
char prenume ;
struct data_calendar
data_nasteri ;
char adresa ;
char localitatea ;
}angajat ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 115

variabila angajat este o structură de tip data_personal ce include elementul


data_nasteri ca ostructură de tipul data_calendar.
Pentru a apela elementul zi din cadrul variabilei angajat se va scrie :

angajat.data_nasteri.zi =12 ;

Pentru a apela elementul nume din variabila angajat se va scrie :

strcpy (angajat.nume, “Popescu”) ;

sau folosind funcţia gets () astfel :


printf (“introduceti numele ”);
gets (angajat.nume) ;

se tastează numele Popescu .

Pentru a apela elementul an din substructura data_calendar a variabilei angajat se


va scrie :

angajat.data_nasteri.an =1949 ;

Dacă se foloseşte tastatura pentru a introduce datele se scrie :

printf (“introduceti data nasteri ”);


gets (b);
angajat.data_nasteri.an= atoi (b); se va tasta 1949

Pentru a afişa valorile elementelor unei structuri, se va folosi adresarea numelui de


structură cât şi numele elementului astfel :

Printf (“anul nasteri =%d \n”,angajat.data_nasteri.nume);


Printf (“luna =%s \n”,angajat.data_nasteri.luna);
Printf (“ziua =%d \n”,angajat.data_nasteri.zi);

Pentru a apela elementul luna din sustructura data_calendar a variabilei angajat se


va scrie :

strcpy (angajat.data_nasteri.luna, “IANUARIE”) ;

Exemplu.

Să se realizeze o structură cu denumirea punct ce conţine elementele :


x=număr linie intreg
y=număr coloană intreg
c=culoarea liniei caracter
şi variabilele a, b[4] de tip structura punct.
LIMBAJUL C TEORIE ŞI APLICAŢI I 116

Să se citească de la tastatură valori pentru elementele dorite şi să se afişeze


valorile scrise în aceste elemente.

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

{
struct punct declararea structurii punct
{
int x; declararea elementului x al structurii punct şi
tipul elementului intreg

int y ; declararea elementului y al structurii punct şi


tipul elementului intreg

char c [10] ; declararea elementului c al structurii punct şi


tipul elementului şir de caractere
}a,b[4] ; declararea variabilelor a şi b[4] de tip structură
punct
puts ("dati numarul liniei si numarul coloanei");
scanf ("%d,%d",&a.x,&a.y); citirea a două date de tip intreg şi atribuirea
acestor date elementelor x şi y ale variabilei a de
tip structură punct
puts ("dati culoarea liniei");
scanf ("%s", a.c); citirea unui şir de caractere şi atribuirea acestui şir
elementului c al variabilei a de tip structură

scanf ("%s",b[1].c); citirea unui şir de caractere şi atribuirea acestui şir


elementului c al variabilei tablou b[1] de tip
structură
printf ("datele citite sunt x=%d y=%d \n",a.x,a.y); afişarea valorilor
elementelor x şi y ale variabilei a de tip structura
printf ("culoarea este =%s \n",a.c); afişarea valorilor elementului c al
variabilei a de tip structura

printf ("culoarea lui b[1]=%s",b[1].c); afişarea valorilor elementului c al


variabilei tablou b[1] de tip structura
puts ("\n Apasa o tasta ");
getch ();
}

Transferarea unei structuri în cadrul unei funcţiise face prin pointeri spre structură.
Dacă se consideră o funcţie f1 care prelucrează structura punct, funcţia va avea antetul
:
LIMBAJUL C TEORIE ŞI APLICAŢI I 117

Tip f1 (struct punct *p)


Declaraţia lui p specifică că el are ca valoare adresa de început a zonei de memorie
unde este tipul punct.
Pentru a accesa elementele din structură, se va folosi :
(*p).x;
(*p).y;
această formă se poate simplifica prin înlocuirea lui (*p). cu p->

p->x ;
p->y ;
operatorul săgeată -> se consideră de prioritate maximă prin asociere de la
stânga la dreapta.

3.11.3. Asignări de nume pentru tipuri de date.


Tipurile predefinite de limbaj (int, char, float, double, long…) se indentifică prin
cuvântul cheie asociat lor. În cazul că utilizatorul doreşte să realizeze tipuri de date
propri, va folosi o construcţie de structură astfel :
struct nume {
declaraţii;
};
sau se poate folosi forma :
typedef tip nume ;
typedef =cuvânt cheie
tip =tipul datei predefinit sau tipul creat de utilizator anterior
nume = numele ce se atribuie tipului definit de tip.
După declararea numelui unui tip se poate folosi pentru a declara date de tipul creat de
utilizator astfel :

typdef float real ;

astfel cuvântul real se poate utiliza pentru a defini date de tip float :

real x;
indentic cu
float x;
typedef struct punct {
int x;
int y;
} PT ;
s-a definit un tip cu numele PT care are caracteristicile unei structuri punct.
Declaraţia de forma :
PT puncte, puncte1;
Indică că datele puncte şi puncte1 sunt date de tip structură asemenea cu structura
punct.
LIMBAJUL C TEORIE ŞI APLICAŢI I 118

typedef struct {
float real;
float imaginar ;
} complex ;
Utilizarea declaraţiilor de mai jos :

complex a,b,c;

Are ca efect declararea a 3 variabile (a, b, c) ca numere complexe.


Exemplu.

Să se scrie o funcţie care determină modulul unui număr complex şi să se apeleze


funcţia într-un program ce citeşte o valoare de tip număr complex.
Numărul complex este de forma :
x+yi
iar modulul este :
sqrt (x.x+y.y)
Funcţia modul_complex este realizată în fişierul erton13.c.

Fişierul erton13.c

float modul_complex (complex *c)


{
puts ("returneaza modulul numarului complex");
return sqrt (c->x*c->x+c->y*c->y) ;
}

Programul principal.
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
typedef struct {
float x;
float y;
} complex;
#include "erton13.c"
void main ()
{
complex a ;
puts ("dati partea reala a numarului complex");
scanf ("%f",&a.x);
puts ("dati partea imaginara a numarului complex");
scanf ("%f",&a.y);
printf ("a+ai= %.2f+%.2f*i\n",a.x,a.y);
printf ("modulul =%f\n",modul_complex (&a));
puts ("\n Apasa o tasta ");
getch ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 119

3.12. Prelucrarea şirurilor de caractere.


În practica de programare sunt dese situaţi când este necesar să se efectueze operaţii cu
şiruri de caractere astfel :
Citirea unui şir de caractere.
Compararea a două şiruri de caractere.
Determinarea lungimii şirului de caractere.
Concatenarea a două şiruri de caractere.
Copierea unui şir de caractere.
Operaţiile enumerate mai sus sunt necesare în realizarea de fişiere de comandă, pentru
realizarea de transfer de date de pe dischetă pe calculator sau invers, sub controlul unor
parametri impuşi de cel care livrează fişierele cum ar fi :
Indicarea şi alegerea discului pe care se va copia fişierele.
Indicarea căi de directoare, subdirectoare.
Indicarea numelui fişierului ce se copiază sau mută.
Funcţiile pentru prelucrarea şirurilor de caractere au prototipul în fişierul string.h,
conţinut în biblioteca standard.
Şirurile de caractere sunt păstrate în memorie sub forma unui tablou cu o singură
dimensiune de tip char, iar fiecare caracter al şirului este păstrat pe un octet în codul
ASCII.
La terminarea şirului de caractere se poziţionează caracterul NUL, care nu este
considerat ca şi caracter la determinarea lungimii şirului de caractere. Prezenţa acestui
caracter este necesară pentru a indica terminarea şirului de caractere.
Operaţiile asupra şirului de caractere se realizează prin utilizarea numelui tabloului în
care se păstrează şirul de caractere, astfel primul termen al tabloului păstrează valoarea
codului primului caracter, al doile-a termen al tabloului păstrează valoarea codului
celui deal doile-a caracter şi aşa mai departe.
S-ă considerăm că în tabloul sir1 se va păstra şirul de caractere TEST PENTRU
SIRURI .
Char sir1 [20] =” TEST PENTRU SIRURI “ ;
Astfel sir1 [0] va conţine adresa caracterului T.
Astfel sir1 [1] va conţine adresa caracterului E.
Astfel sir1 [0] va conţine adresa caracterului S.
Astfel sir1 [0] va conţine adresa caracterului T.
Astfel sir1 [0] va conţine adresa caracterului spaţiu.
Etc.
Astfel sir1 [18] va conţine adresa ultimului caracter al şirului I.
Pentru a se deosebi mai uşor funcţiile ce prelucrează şiruri de caractere, s-a pus la
fiecare funcţie prefixul str de la cuvântul string din engleză.
LIMBAJUL C TEORIE ŞI APLICAŢI I 120

3.12.1. Funcţia strlen,lungimea şirului de caractere.


Funcţia strlen determină lungimea şirului de caractere, prin numărarea caracterelor care
formează şirul. La numărarea numărului de caractere a şirului nu se adaugă caracterul
de sfârşit NUL a şirului, rolul lui este de a opri numărarea caracterelor până la el.
Prototipul funcţiei strlen este :

unsigned strlen (const char *sir1);

Funcţia returnează o valoare pozitivă întreagă ce reprezintă numărul de


caractere din sirul de caractere sir1.
Parametrul formal al funcţiei strlen este un pointer spre o dată constantă.

char sir1 [50];


int lun ;
scanf (“%s”,sir1);
lun= strlen (sir1);

S-au declarat variabila sir1 de tip caracter în care se va păstra şirul de caractere citite şi
variabila lun la care se va atribui valoarea returnată de funcţia strlen.
Dacă se doreşte determinarea lungimii unui şir de caractere apelat chiar de funcţia
strlen, secvenţa de program este :

int lun ;
lun= strlen (“test pentru siruri”);

astfel valoarea lui lun este chiar numărul de caractere al şirului test pentru
siruri , în cazul de faţă valoarea lui lun este 18, şi spaţiile libere din şirul de caractere
este numărat.

printf (“lungimea sirului este %d ”, strlen (“test pentru sir”));

La apelarea funcţiei printf se va afişa valoarea 15 ce reprezintă numărul de caractere


din şirul test pentru sir .

3.12.2. Funcţia strcpy, copierea unui şir de caractere.


Funcţia strcpy permite copierea unui şir de caractere de la o adresă de memorie la altă
adresă de memorie.
Prototipul funcţiei strcpy este :

Char * strcpy (char*la destinaţia, const char*de la sursa);

Funcţia strcpy copiază şirul de caractere, inclusiv terminatorul şirului NUL de la sursa
la destinaţia indicată prin parametri formali ai funcţiei. Marimea zonei în care se face
copierea (destinaţia) trebuie să fie egală sau mai mare decât lungimea şirului +1, în caz
contrar caracterele surplus pot fi modificate necontrolat de program. Se recomandă ca
LIMBAJUL C TEORIE ŞI APLICAŢI I 121

înaintea apelării funcţiei strcpy să se determine lungimea şirului ce se copiază şi să se


compare această lungime +1 cu mărimea zonei destinaţie.
Funcţia strcpy returnează adresa de început a zonei în care s- a copiat şirul, pointer spre
destinaţie char*.
Funcţia strcpy modifică conţinutul destinaţiei dar nu poate modifica conţinutul sursei
datorită modificatorului const pentru pointerul sursă.
Exemple de folosire :

char sirsursa [30] ,sirdestinatie [30] ;


scanf (“%s”,sirsursa);
strcpy (sirdestinatia, sirsursa);

Şirul de caractere citit cu funcţia scanf (“%s”,sirsursa); este alocat în tabloul sirsura,
iar prin apelul funcţiei strcpy şirul de caractere din tabloul sirsursa este copiat în
tabloul sirdestinatie.

char sirsursa [30] ,sirdestinatie [30] ;


strcpy (sirdestinatia,”inceput de drum”);

Textul inceput de drum este copiat în tabloul sirdestinatie.

char sirsursa [30] ,sirdestinatie [30] ;


char *surs = “o noua varianta ”;
char *t1;
t1=strcpy (sirdestinatia,surs);

Şirul o noua varianta păstrat în zona spe care pointează *surs se copiază în zona spre
care pointează sirdestinatia şi apoi i se atribuie lui t1 valoarea adresei tabloului
sirdestinatia.

3.12.3. Funcţia strncpy, copierea a cel mult n caractere ale unui şir de
caractere.
Funcţia strncpy permite copierea a cel mult n caractere ale şirului sursă în şirul
destinaţie.
Dacă valoarea lui n este mai mare decât lungimea şirului sursă, atunci toate caracterele
şirului sursă sunt transferate în şirul destinaţie.
Dacă valoarea lui n este mai mic decât lungimea şirului sursă, atunci se va transfera
numai n caractere din şirul sursă în şirul destinaţie.
Prototipul funcţiei este :

char * strncpy (char * destinatie, const char* sursa , unsigned n);


Exemplu de apelare a funcţiei strncpy :

char sirsursa [30] ,sirdestinatie [10] ;


char *sirsursa = “o noua varianta ”;
strncpy (sirdestinatia,sirsursa,6);
LIMBAJUL C TEORIE ŞI APLICAŢI I 122

După executarea liniilor de cod de mai sus, din şirul de caractere o noua varianta se
vor copia în tabloul sirdestinatie numai primele 6 caractere
o noua .

3.12.4. Funcţia strcat, concatenarea şirurilor de caractere.


Funcţia strcat permite concatenarea (adăugarea) unui şir de caractere, numit sursă, la
sfârşitul altui şir de caractere numit destinaţie.
Lungimea tabloului destinaţie trebuie să fie mai mare sau egal cu lungimea şirului de
caractere existente în şirul destinaţie înaintea apelări funcşiei strcat + lungimea şirului
sursa +1 pentru caracterul de terminare NUL a noului şir.
Funcţia strcat returnează valoarea şirului destinaţie.
Funcţia strcat are prototipul :

char * strcat (char * destinatie, const char* sursa);

Exemplu de folosire :

char sirsursa [30] ,sirdestinatie [50] ;


scanf (“%s”,sirsursa);
char *sirdestinatie = “inceput de drum ”;
strcat (sirdestinatia, sirsursa);
Dacă la apelarea funcţiei de citire a unui şir de caractere se tastează pentru
concatenare şi dacă se va afişa conţinutul tabloului sirdestinatie, va rezulta şirul de
caractere inceput de drum pentru concatenare
3.12.5. Funcţia strncat, concatenarea şirurilor de caractere cu
lungimea impusă.
Funcţia strncat permite concatenarea a două şiruri de caractere cu observaţia că al
doilea şir ce se adaugă este limitat de n caractere indicate de parametrul n al funcţiei.
Observaţiile indicate la funcţia strcat sunt recomandate şi la funcţia strncat.
Prototipul funcţiei strncat este :

char * strncat (char * destinatie, const char* sursa, unsigned n);

Exemplu de folosire :

char sirsursa [30] ,sirdestinatie [50] ;


scanf (“%s”,sirsursa);
char *sirdestinatie = “inceput de drum ”;
strncat (sirdestinatia, sirsursa,6);
printf (“%s”, sirdestinatie);

Dacă la apelarea funcţiei de citire a unui şir de caractere se tastează pentru


concatenare se va afişa conţinutul tabloului sirdestinatie, va rezulta şirul de caractere
inceput de drum pentru
Şirul de caractere concatenare nu mai este adăugat la şirul sirdestinaţie.
LIMBAJUL C TEORIE ŞI APLICAŢI I 123

3.12.6. Funcţia strcmp, compararea a două şiruri de caractere.


Funcţia strcmp compară două şiruri de caractere care au aceiaş lungime, şi returnează o
valoare intreagă funcţie de rezultatul comparări astfel :
Returnează valoarea -1 dacă sirul1 < sirul2.
Returnează valoarea 0 dacă sirul1 =sirul2.
Returnează valoarea 1 dacă sirul1 > sirul2
Şirul 1 se consideră mai mic decât şirul 2 dacă există măcar un termen
sir1[i]<sir2[i] indiferent de valoarea lui i iar restul
termenilor sunt egali .
Şirul 1 se consideră egal dacă pentru orice valoare a lui i este valabilă relaţia :
sir1[i]=sir2[i] iar restul termenilor sunt egali.
Şirul 1 se consideră mai mare decât şirul 2 dacă există măcar un termen pentru
care relaţia
sir1[i]<sir2[i] este valabilă indiferent de valoarea lui i iar restul
termenilor sunt egali.
Prototipul funcţiei strcmp are prototipul :

int strcmp (const char * sir1, const char* sir2);

Exemplu de apelare :

char *sir1 = “inceput de drum ”;


char *sir2 = “inceput de drum ”;
int i;
i=strcmp (sir1, sir2);
if (i==0)
printf(“siruri egale”);
if (i<0)
printf (“sirul1 mai mic decit sirul2”);
else
printf (“sirul1 mai mare decit sirul2”)

Dacă se rulează această secvenţă de cod, se va afişa siruri egale.


Dacă pentru şirul doi se introduce inceput de druM , se va afişa sirul1 mai mare
decit sirul2 deoarece litera m are o valoare mai mare decât litera M.
Dacă pentru şirul1 se introduce inceput De drum iar pentru şirul2 se introduce inceput
de drum , se va afişa sirul1 mai mic decit sirul2 .

3.12.7. Funcţia stricmp, compararea a două şiruri fără a se face


distincţia între litere mari sau mici.
Funcţia stricmp lucrează ca şi funcţia strcmp cu deosebirea că nu face distincţie între
caracterele majuscule şi minuscule.
Prototipul funcţiei este :

int stricmp (const char * sir1, const char* sir2);

Dacă cele două şiruri conţin textul :


LIMBAJUL C TEORIE ŞI APLICAŢI I 124

Sir1 mic
Sir2 MIC

char *sir1 = “mic ”;


char *sir2 = “MIC ”;
int i;
i=strcimp (sir1, sir2);
if (i==0)
printf(“siruri egale”);
if (i<0)
printf (“sirul1 mai mic decit sirul2”);
else
printf (“sirul1 mai mare decit sirul2”)

La apelarea funcţiei stricmp asupra celor două şiruri valoarea returnată este 0, şiruri
egale.
3.12.8. Funcţia strincmp.
Funcţia strincmp compară două şiruri de caractere, de la primul caracter până la cel
mult n caractere şi se ignoră diferenţa dintre caracterele majuscule şi caracterele
minuscule.
Prototipul funcţiei este :
int strincmp (const char * sir1, const char* sir2, usigned n);

Dacă cele două şiruri conţin textul :


Sir1 micut
Sir2 MIC

char *sir1 = “micut ”;


char *sir2 = “MIC ”;
int i;
i=strcinmp (sir1, sir2,3);
if (i==0)
printf(“siruri egale”);
if (i<0)
printf (“sirul1 mai mic decit sirul2”);
else
printf (“sirul1 mai mare decit sirul2”)

La apelarea funcţiei stricmp asupra celor două şiruri valoarea returnată este 0, şiruri
egale, datorită faptului că s-au comparat numai primele 3 caractere ale şirurilor.
Exemplu.
Să se citească de la tastatură 3 şiruri de caractere, să se compare lungimea primelor
două şiruri, să se realizeze o frază cu cele trei şiruri, să se copieze şirul 1în şirul2.
Să se afişeze la fiecare etapă efectul operaţiei.

#include <stdio.h>
#include <conio.h>
LIMBAJUL C TEORIE ŞI APLICAŢI I 125

#include <string.h>
void main ()
{
char sir1[30], sir2 [40], sir4 [30];declarare şiruri de tip caracter
char sir3 []=" "; declararea şirului 3 ce conţine spţiu liber
int i,j;
puts ("Se calculeaza lungimea sirurilor citite ");
puts ( "Dati sirul1");
scanf("%s",sir1); citirea unui şir de caractere fără spaţiu liber înte
caractere
puts ("dati sirul2");
scanf ("%s",sir2);
puts ("dati sirul4");
scanf ("%s",sir4);
i=strlen (sir1); determinarea lungimii sirului (numărul de
caractere)
j=strlen (sir2);
if (i>j)
puts ("sirul1 mai lung decit sirul2");
else
if (i==j)
puts ("siruri cu lungimi egale");
else
puts ("sirul2 mai lung decit sirul1");
printf ("sir1 =%d caractere \t sirul2=%d caractere \n",i,j);
strcat (sir1,sir3); concatenarea la sfârşitul şirului1 a şirului 3 pentru
a introduce spaţiu liber între cuvinte

strcat (sir1,sir2); concatenarea la sfârşitul noului şir1 a şirului2


printf ("%s\n",sir1); afişarea primei fraze realizată din sirul1 pauză de
un caracter şi apoi şirul2

strcat (sir1,sir3); concatenarea şir3 la noul şir1


strcat (sir1,sir4); concatenarea ultimului şir4
printf ("%s\n",sir1); afişarea frazei formată din 3 cuvinte şi două spaţii
între cuvinte

strcpy (sir2,sir4); copierea şirului4 în şirul2


printf ("%s\n",sir2);
puts ("\n Apasa o tasta ");
getch ();
}
Dacă la rularea programului se va tasta pentru şirul1 ERTON, pentru şirul2 ESTE, iar
pentru şirul4 SPORTIV, în urma rulării vor fi afişate :
Sirul1 mai lung decit sirul2
ERTON ESTE
ERTON ESTE SPORTIV
SPORTIV
LIMBAJUL C TEORIE ŞI APLICAŢI I 126

Apasa o tasta

3.13. Prelucrarea fişierelor.


Operaţiile de intrare, ieşire asupra unui fişier se realizează prin intermediul
funcţiilor din biblioteca standard a limbajului C. Operaţiile de intrare/ieşire se
realizează de la tastatură, monitor dar sunt situaţii multiple când aceste operaţii se
efectuează dintr-un fişier. Prelucrarea fişierelor se efectuează prin operaţii
specifice cum sunt :
 Deschiderea fişierului
 Citirea datelor din fişierul deschis
 Actualizarea fişierului
 Adăugarea datelor în fişier
 Poziţionarea în cadrul fiţierului, închiderea fişierului
 Crearea unui fişier
 Ştergerea unui fişier
Funcţiile necesare operării cu fişiere au prototipul în fişierul stdio.h. Prelucrarea
fişierelor se poate face la două nivele :
 Nivel inferior ce apelează direct sistemul de operare.
 Nivelul superior ce apelează structuri speciale de tip FILE
3.13.1.1 Nivelul superior de prelucrare a fişierelor.
Deschiderea unui fişier
Deschiderea unui fişier se realizează prin funcţia fopen ce returnează un pointer
spre tipul FILE, sau pointer nul în cazul că fişierul indicat nu există sau nu poate fi
deschis. Prototipul funcţiei fopen este :
FILE fopen (const char calea, const char *mod);
unde calea este pointerul spre un şir de caractere care indică calea spre fişierul ce
se deschide,
mod este pointerul spre şirul de caractere care indică modul de prelucrare a
fişierului astfel :
"r" = deschidere în citire
"w" = deschidere în scriere
"a" = deschidere pentru adăugare de înregistrări în fişier
"r+" = deschidere pentru modificare scriere,citire
"rb" = deschidere în citire binară
"wb" = scriere binară
"r+b" = citire sau scriere binară.
Dacă fişierul ce urmează a se deschide nu este, se va apela opţiunea w sau a care
va crea acest fişier, dacă se deschide un fişier existent prin opţiunea w, se vor
şterge toate datele existente din fişier considerându-se în modul creare. Dacă se
deschide cu opţiunea a un fişier existent noile date vor fi adăugate după ultima
dată din fişier.
LIMBAJUL C TEORIE ŞI APLICAŢI I 127

Închiderea unui fişier


Închiderea unui fişier se realizează cu funcţia fclose a cărui prototip este :
int fclose (FILE*p):
unde p este pointerul spretipul FILE definit prin funcţia fopen.
Funcţia returnează o valoare de tip întreg astfel :
0 la închidere normală
–1 la eroare
3.13.2. Intrări ieşiri cu format.
Funcţiile folosite pentru citire sau scriere cu format din fişier sunt :
fscanf pentru citire din fişier.
fprintf pentru scrierea cu format în fişier.
Prototipul funcţiei fscanf este:
int fscanf (FILE*p, const char*format..);
unde p este pointer spre tipul FILE a cărui valoare a fost definită de apelul funcţiei
de deschidere a fişierului fopen,
const char*format.. sunt parametrii ce indică formatele de citire ca şi la funcţia
scanf.
Funcţia fscanf returnează numărul câmpurilor citite corect iar la întâlnirea
sfârşitului de fişier va returna valoarea EOF.
Prototipul funcţiei fprintf este:
int fprintf (FILE*p, const char*format..);
unde p este pointer spre tipul FILE a cărui valoare a fost definită de apelul funcţiei
de deschidere a fişierului fopen,
const char*format.. sunt parametrii ce indică formatele de citire ca şi la funcţia
printf.
Funcţia fprintf returnează numărul caracterelor scrise în fişier în caz de succes,
sau returnează valoarea –1 în caz de eroare.

3.13.3. Poziţionarea în fişier.


Operaţiile de citire, scriere se efectuează secvenţial, astfel la fiecare apel de citire
scriere se citeşte înregistrarea curentă, respectiv se scrie o nouă înregistrare la
poziţia curentă.
În majoritatea cazurilor se doreşte o poziţionare în interiorul fişierului, astfel
operaţiile de citire, scriere au loc aleator.
Pentru o poziţionare în fişier se foloseşte funcţia fseek cu prototipul:
int fseek (FILE*p, long deplasare, int origine);
unde p pointer spre tipul FILE a cărui valoare a fost definită de apelul funcţiei de
deschidere a fişierului fopen,
deplasare este numărul de octeţi peste care se va deplasa capul de citire/scriere,
origine indică de unde se consideră că este originea deplasării:
LIMBAJUL C TEORIE ŞI APLICAŢI I 128

0 = deplasarea se consideră de la începutul fişierului.


1 = deplasarea se consideră de la poziţia curentă.
2 = deplasarea se consideră de la sfârşitul fişierului.
Funcţia fseek returnează valoarea 0 la o poziţionare corectă şi o valoare diferită
de 0 în caz de eroare.
Exemplu
Să se scrie un program C pentru scrierea într-un fişier a datelor citite de la
tastatură. Datele citite de la tastatură sunt scrise în fişierul având numele costi1.c
secvenţial (înregistrare după înregistrare) folosind un ciclu for cu un număr de 5
paşi.
Rezolvare
Structura de tip FILE pointează la fl, iar funcţia fopen pointează la acelaş fl.
Numele fişierului cât şi calea la fişier sunt delimitate de dublu apostrof. Modul de
deschidere a fişierului este indicat prin caracterul "w" (mod de scriere secvenţială).
#include<stdio.h>
#include<conio.h>
#include<io.h>
#include<fcntl.h>
void main ()
{
FILE *f1; fl este pointerul de tip structură FILE (fişier)
int a,b,c;
char d[10];
f1=fopen("COSTI1.C","w"); apelarea funcţiei de deschidere a fişierului in
mod scriere
for (a=1; a<=5; a=a+1) ciclul de citire de la tastatură şi scriere în fişier
{
scanf ("%s",&d); citirea unei date de tip şir de caractere de la
tastatură
fprintf (f1,"%s \n",d); scrierea cu format a unei date in fişierul
deschis spe pointerul fl
printf ("s-a scris %s",d); afişarea pe monitor a datei citite şi scrise în
fişier
}
puts ("Apasa o tasta");
getch ();
fclose (fl); închiderea fişierului deschis de fopen ce
pointează la fl
}
Exemplu
Să se scrie un program C care adaugă 5 şiruri de caractere, citite de la tastatură în
fişierul creat în exemplul precedent.
Rezolvare
În cazul în care se doreşte adăugarea de date într-un fişier existent, la apelarea
funcţiei fopen se va alege opţiunea a (append).
LIMBAJUL C TEORIE ŞI APLICAŢI I 129

#include<stdio.h>
#include<conio.h>
#include<io.h>
#include<fcntl.h>
void main ()
{
FILE *f1; fl este pointerul de tip strutură FILE (fişier)
int a,b,c;
char d[10];
f1=fopen("COSTI1.C","a"); deschiderea fişierului existent costi1.c in modul
adăugare
/* se scrie in adaugare in fisierul costi1.c */
for (a=1; a<=5; a=a+1)
{
scanf ("%s",&d); se citesc 5 şiruri de caractere de la tastatură
fprintf (f1,"%s \n",d);
printf ("s-a scris %s",d);
}
puts ("Apasa");
getch ();
fclose (fl); închiderea fişierului deschis de fopen ce
pointează la fl
}
Exemplu
Să se scrie programul C care citeşte un număr de n date de tip număr dintr-un
fişier existent.
Rezolvare
Creaţi fişierul citire1.dat în editorul DOS. Fişierul citire1.dat are organizate
datele separate fie prin spaţiu, fie dispuse pe câte
un rând fiecare. Conţinutul fişierului citire1.dat
este
5 12.4 34 56 trei date dispuse pe aceeaşi linie şi separate prin spaţiu
78 fiecare dată dispusă pe un rând.
23 fiecare dată dispusă pe un rând.
12 fiecare dată dispusă pe un rând.
45
56
Programul sursă C este prezentat în continuare
#include<stdio.h>
#include<conio.h>
#include<io.h>
#include<fcntl.h>
#include <math.h>
void main ()
{
FILE * f1;
int i,j,m,n;
float a[100],b[100],c,xc,yc,nr,beta,xb,yb;
LIMBAJUL C TEORIE ŞI APLICAŢI I 130

f1=fopen("CITIRE1.DAT","r"); funcţia fopen deschide fişierul citire1.dat în


mod citire
puts ("DATI NUMARUL DE PUNCTE MASURATE");
scanf("%d",&n);
c=141.42135;
xb=100;
yb=0;
for (i=1; i<=n; i=i+1)
{
fscanf(f1,"%f",&nr); funcţia fscanf face prima citire din
fişierul deschis
printf("%.2f ",nr);
fscanf(f1,"%f",&a[i]); se citeşte a doua dată din fişier
fscanf(f1,"%f",&b[i]); se citeşte a treia dată din fişier
printf("%f\t%f",a[i],b[i]); se afişează pe monitor datele citite
beta=(a[i]*a[i]+c*c-b[i]*b[i])/(2*a[i]*c);
xc=xb+a[i]*0.7071068;
yc=yb+a[i]*0.7071068;
printf ("nr=%f\t",nr); se afişează prima dată citită din fişier
printf ("xc=%f\tyc=%f\n",xc,yc); se afişează valorile calculate xc, yc
}
puts ("Apasa o tasta pentru terminare");
fclose (f1); se închide fişierul deschis de fopen
getch ();
}
Probleme propuse
1. Să se citească de la tastatură mărimea unui vector şi termenii vectorului, iar
aceste valori să fie scrise într-un fişier de date. Să se citească fişierul de date şi
apoi să se execute următoarele operaţii asupra datelor :
a) afişarea mărimii vectorului
b) afişarea termenilor vectorului
c) suma termenilor vectorului
d) modificarea termenului n al vectorului cu o nouă valoare citită de la tastatură
e) afişarea vectorului modificat.
2. Să se citească de la tastatură mărimea unei matrici pătratice n n, şi termenii
matricei.
a) să se scrie în fişierul mat1.dat mărimea matricei şi termenii matricii
b) să se afişeze valorile scrise în fişier
c) să se adune toţi termenii matricii scrise în fişier
d) să se creeze un nou fişier vect1.dat, care să conţină termenii de pe prima linie
a matricii
e) să se adune termenii vectorului din fişierul vect1.dat.
3. Să se scrie într-un fişier presiune.dat valorile citite ale presiunii apei şi să se
afişeze aceste valori cu citirea din fişier.
LIMBAJUL C TEORIE ŞI APLICAŢI I 131

3.14. Preprocesorul C.
Prerocesorul C execută substituţii de texte, realizând :
Includere de fişiere sursă
Definiţii şi apeluri de macrouri
Compilarea condiţionată.
Preprocesorul recunoaşte construcţii care încep cu caracterul # numite directive.
Directivele recunoscute de preprocesorul C sunt :
#if
#ifdef
#ifndef
#else
#elif
#endif
#include
#define
#undef
#line
#error
#pragma
Fiecare directivă trebuie să ocupe un singur rând în program astfel :

#include < math.h> #include <conio.h> este greşit.

Corect se scriu pe fiecare rând

#include < math.h>


#include <conio.h>
Directiva #include.
Această directivă indică compilatorului că afară de fişierul sursă trebuie să mai citească
şi fişierele declarate după această directivă.
Numele fişierului ce se include se va delimita de apostroafe duble “nume fişier “ sau
paranteze unghiulare < nume fişier >.
Delimitarea cu dublu apostroafe sau paranteze unghiulare indică modul de căutare a
fişierului inclus astfel :
Includerea între < > indică căutarea fişierului în directorul INCLUDE din
pachetul de directoare şi fişiere ale limbajului C.
Includerea între “ “ indică căutarea fişierului în directorul de lucru sau în alt
director la care se indică calea de căutare.
Modul de încadrare între “ “ este folosit pentru a include fişierele create de utilizator
astfel :

#include “ erton1.c” fişierul erton1.c este în directorul de lucru.


LIMBAJUL C TEORIE ŞI APLICAŢI I 132

#include “ c:\tempc\sursa1\erton2.c “ fişierul erton2.c este situat în


directorul sursa1 de pe calea c:\tempc .
directiva #define .
directiva #define defineşte un indentificator prin nume şi un şir de caractere care vor
înlocui indentificatorul la apariţia acestuia în cadrul programului. Standardul ANSII C
numeşte indentificatorul nume ca macrocomandă.

#define nume şir de caractere

#define pi 3.14156
la întâlnirea numelui pi în cadrul programuluisursă se va înlocui acest nume cu
valoarea 3.14156.

#define MAX 100


……
float v [MAX] ;
……
Numele MAX va fi înlocuit în program cu şirul 100 , astfel la declararea mărimi
vectorului v s-a folosit indentificatorul MAX, care va fi înlocuit cu 100, rezultând un
vector cu 100 de elemente.

#include <stdio.h>
#include <conio.h>
#define unu 1 definirea macroului unu ce va fi înlocuit cu
caracterul 1 la întâlnirea acestui macrou
#define doi unu+unu definirea macroului doi realizat prin imbricarea de
două ori a macroului unu
#define ADEVARAT 1 definirea macroului ADEVARAT
#define FALS 0 definirea macroului FALS
#define eroare "textul de eroare la citirea fisierului"
definirea macroului eroare care va fi înlocuit la
apelarea lui cu şirul de caractere delimitat de
dublu apostroafe
void main ()
{
printf (" %d %d ",ADEVARAT, FALS); va afişa 1 0
printf ("primul macrou %d al doilea macrou %d \n",unu,doi);
va afişa 1 2
printf (eroare); va afişa textul de eroare la citirea fisierului
puts ("\n Apasa o tasta ");
getch ();
}
Dacă lungimea şirului de caractere ce va înlocui macroul nume este mai lung de un
rând, se va separa rândul 1 de rândul 2 prin caracterul backslash \ astfel :
LIMBAJUL C TEORIE ŞI APLICAŢI I 133

#define sir_lung “ acest sir de caractere este desfasurat pe doua


rinduri \ primul rind este acesta \ al doilea rind este acestaaaaaaa “

La apelarea acestui macrou prin funcţia printf

printf (sir_lung) ;
Se va afişa :

“ acest sir de caractere este desfasurat pe doua rinduri primul rind


este acesta al doilea rind este acestaaaaaaa

Înlocuirea indentificatorului cu şirul de caractere se face în toate apariţiile


acestuia, exceptând cazurile în care numele indentificatorului este în interiorul unui
comentariu sau intr-un şir de caractere.

#define max1 25
printf (“afiseaza macroul =%d”, max1) ; va afişa valoarea 25 definită de
macroul max1
printf (“max1”) ; va afişa şirul de caractere max1, max1 este în cadrul
unui şir de caractere şi nu este tratat ca şi macroul max1 definit de directiva # define.

Dacă se doreşte ca de la o anumită poziţie în cadrul fişierului sursă să nu se mai aplice


directiva #define se va scrie :

#undef nume

ce acţionează numai asupra indentificatorului ce are definiţia nume .


Din acest punct se poate definiun alt indentificator cu aceleaş nume dar un alt şir de
caractere ce îl definesc folosind directiva #define .
În cadrul directivei #define se poate declara o altă directivă anterior declarată,
numindu-se directive imbricate.
Numărul maxim de imbricare este de opt (8).
Utilizarea macrourilor este indicată în declaraţii de tablouri cu unul sau două
dimensiuni.Prin faptul că dacă se doreşte modificarea dimensiunilor tablourilor în
cadrul programului, se va face doar modificarea şirului de caractere, din directiva
asociată numelui macroului folosit la declararea dimensiunii tablourilor, nefind
necesar modificarea dimensiunii tablourilor în fiecare loc unde apar declaraţii de
tablouri.

#define MAX 25
……
float a[MAX], b [MAX][MAX] , c [MAX][MAX] ;
……
functia matad (floatp [MAX][MAX] );
{
….
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 134

…..

dacă se doreşte ca dimensiunea tablourilor să fie modificată la valoarea de 40 se va


modifica doar şirul de după macroul MAX astfel :

#define MAX 40

care are ca efect modificarea peste tot unde este găsit macroul MAX cu noua valoare
de 40, inclusiv în cadrul funcţiei matad.
Macrourile definite de directiva #define după nume poate avea şi parametrii astfel:

#define nume(par1,par2,..parn) text

par1, par2,..parn sunt parametri formali ai macrourilor şi reprezintă nume.


text este textul de substituţie şi conţine parametrii formali par1,par2 …parn,
În exemplul ce urmează s-a creat un macrou min (x,y) care determină valoarea minimă
dintre parametrul x şi parametrul y .

#include <stdio.h>
#include <conio.h>
#define min(x,y) ((x)<(y)?(x):(y)) definirea macroului min (x,y),
parametrul1formal este x iar parametrul2 formal
este y
void main ()
{
int a,b,minim;
puts ("dati doua numere, se determina minimul dintre ele");
scanf ("%d,%d",&a,&b);
minim =min(a,b); apelarea macroului min (x,y) cu parametri efectivi
a,b
printf ("minimul dintre cele doua numere este =%d",minim);
puts ("\n Apasa o tasta ");
getch ();
}

În exemplul următor macro realizat afişează şiruri de caractere în funcţie de


valoarea parametrilor efectivi de la apelarea macro test.
La apelarea macro test, tot şirul de caractere delimitat de {} ia locul lui macro
test după ce parametri fictivi au fost înlocuiţi cu parametri efectivi de la
apelare macro test.

#include <stdio.h>
#include <conio.h>
#define test(x,y) {float x,y ;if(x==1) puts ("primul numar este=1");else \
puts ("primul numar este diferit de 1");\
if(y<0) puts ("al doilea numar este negativ");else \
puts ("al doilea numar este pozitiv"); }
void main ()
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 135

float a,b;
puts ("dati doua numere, ");
scanf ("%f,%f",&a,&b);
test(a,b);
puts ("\n Apasa o tasta ");
getch ();
}

Substituirea apelului unui macro prin textul de substituţie se numeşte


expandare.
Între numele macro şi paranteza ( din faţa parametrilor fictivi nu se lasă spaţiu,
În caz contrar atât parantezele () de delimitare a parametrilor cât şi restul de text se
consideră un simplu şir de caractere care va înlocui macro în poziţia unde a fost apelat.

Directiva #error.
Directiva #error indică compilatorului să sisteze compilarea la întâlnirea acestei
directive. Forma directivei #error este :
#error mesajul ce va fi afişat pe linia de mesaje a compilatorului
Mesajul ataşat directivei #error nu se introduce între apostroafe sau dublu ghilimele, la
întâlnirea directivei #error se afişează mesajul fără a fi prelucrat de compilator.

#include <stdio.h>
#include <conio.h>
void main ()
{
float a,b;
puts ("dati doua numere, ");
if (scanf ("%f,%f",&a,&b)==2)
{
puts ("\n Apasa o tasta ");
getch ();
}
else
#error s-a tastat caracter nenumeric;directiva error şi mesajul ataşat care va
fi afişat pe linia de mesaje la compilare şi opreşte
la acest nivel compilarea
}

Compilarea condiţionată.
Directivele din acest pachet permit ca la execuţia compilării să se aleagă din codul
sursă porţiunile care să se compileze împreună funcţie de resursele hard ale
calculatorului sau de versiunea compilatorului.
Compilarea condiţionată foloseşte directivele :
#if
#else
#endif
#elif
LIMBAJUL C TEORIE ŞI APLICAŢI I 136

Directiva #if.
Forma generală a directivei #if este :
Mod1
#if expresie constanta
secventa de instructiuni
#endif

sau
Mod2
#if expresie constanta
secventa de instructiuni 1
#else
secventa de instructiuni2
#endif

Dacă expresia constantă are valoarea 1 (adevărat), se supune preprocesării secvenţa de


instrucţiuni de după if, sau în modul2 se va supune preprocesării secvenţa de
instrucţiuni 1. După care se continuă cu secvenţa de program de după directiva #endif.
Dacă expresia constantă are valoarea 0 (fals), se supune preprocesării secvenţa de
instrucţiuni de după #endif, sau în modul2 se va supune preprocesării secvenţa de
instrucţiuni 2 şi apoi se continuă cu secvenţa de după #endif.
Expresia constantă de după #if trebuie să conţină numai constante şi indentificatori
definiţi anterior .
Expresia constantă nu poate conţine variabile.

În programul ce urmează s-a condiţionat preprocesarea funcţie de mărimea constantei


simbolice MIN

#include <stdio.h>
#include <conio.h>
#define MIN 40
void main ()
{
float a,b,c[MIN];
#if MIN <30 directiva #if compară MIN cu valoarea 30, dacă
expresia este adevărată se continuă compilarea cu
secvenţa de după #if
{
printf ("marimea vectorului este sub 30");
exit (0);
}
#else dacă expresia de la directiva #if este falsă de
continuă compilarea cu secvenţa de după #else
{
puts ("dati doua numere, ");
if (scanf ("%f,%f",&a,&b)==2)
{
printf ("%f %f",a,b);
LIMBAJUL C TEORIE ŞI APLICAŢI I 137

puts ("\n Apasa o tasta ");


getch ();
}
else
{
puts ("una sau ambele valori nu sunt numere ");
puts ("stop");
}
}
#endif indiferent că expresia de după #if este adevărată
sau falsă se continuă compilarea cu secvenţa de
după #endif
}

Directiva #elif.
Directiva #elif determină un lanţ de if else if pentru mai multe opţiuni de
compilare.Directiva #elif este în interiorul directivei #if - #else, urmată de o expresie
constantă.
Dacă expresia este adevărată, blocul de cod ataşat directivei #elif este compilat şi se
continuă compilarea cu blocul de cod de după directiva #endif.
Forma generală a directivei #elif este .

#if expresie
blocul de instructiuni
#elif expresia1
bloc de instructiuni
#elif expresia2
bloc de instructiuni
….
#elif expresia n
bloc de instructiuni
#endif

În exemplul următor se va condiţiona compilarea în funcţie de valoarea


constantei simbolice TARA.

#include <stdio.h>
#include <conio.h>
#define ROMANIA 0
#define UNGARIA 1
#define BULGARIA 2
#define RUSIA 3
#define TARA ROMANIA
#if TARA ==ROMANIA
char moneda [] ="leu";
#elif TARA==UNGARIA
char moneda [] ="forint";
#elif TARA==BULGARIA
#elif moneda [] ="leva";
LIMBAJUL C TEORIE ŞI APLICAŢI I 138

#else
char oneda [] ="rubla";
#endif

void main ()
{
float a,b;
scanf ("%f,%f",&a,&b);
printf ("suma monedelor =%f %s\n",a+b,moneda);
puts ("apasa o tasta");
getch ();
}

La rularea programului se va afişa ca unitate monetară lei, dacă se doreşte


modificarea unităţii monetare, se va modifica doar constanta din directiva
#define TARA.

Directivele #ifdef şi ifndef.


Directiva #ifdef (dacă este definit) controlează dacă numele indentificatorului a fost
definit anterior prin directiva #define şi blocul de cod ataşat lui #ifdef va fi compilat,
dacă nu se va continua compilarea cu blocul de cod de după #else dacă este prezentă,
sau cu blocul de cod de după #endif.
Forma directivei #ifdef este :

#ifdef nume macro (indentificator)


secventa instructiuni (bloc)
#else
secventa instructiuni
#endif
secventa instructiuni (bloc)

sau

#ifdef nume macro (indentificator)


secventa instructiuni (bloc)
#endif
secventa instructiuni (bloc)

Directiva #ifndef (dacă nu este definit) controlează dacă numele indentificatorului nu a


fost definit anterior prin directiva #define şi blocul de cod ataşat lui #ifndef va fi
compilat, dacă nu se va continua compilarea cu blocul de cod de după #else dacă este
prezentă, sau cu blocul de cod de după #endif.
Forma directivei #ifndef este :

#ifndef nume macro (indentificator)


secventa instructiuni (bloc)
#else
secventa instructiuni
LIMBAJUL C TEORIE ŞI APLICAŢI I 139

#endif
secventa instructiuni (bloc)

sau

#ifndef nume macro (indentificator)


secventa instructiuni (bloc)
#endif
secventa instructiuni (bloc)

În programul următor se controlează compilarea prin directivele #ifdef şi #ifndef.

#include <stdio.h>
#define MAX 20
#include <conio.h>
void main ()
{
float a, b[MAX];
#ifdef MAX
puts ("marimea maxima a vectorului este definita");
#else
puts ("marimea maxima a vectorului nu este definita");
#endif
#ifndef MIN
puts ("constanta simbolica MIN nu este definita");
#endif
puts ("dati doua valori");
scanf ("%f,%f",&a,&b[1]);
printf ("suma =%f \n",a+b[1]);
puts ("apasa o tasta");
getch ();
}

Diectiva #line.
Directiva #line modifică conţinutul indentificatorilor predefiniţi _LINE_ şi _FILE_ ai
compilatorului.
Indentificatorul _LINE_ conţine numărul liniei compilate, iar indentificatorul _FILE_
conţine numele fişieruluisursă compilat sub forma unui şir de caractere.
Forma generală a directivei #line este :

#line numar “ numefisier”

numar = este orice întreg pozitiv care devine noua valoare a lui _LINE_ .
“numefisier” = este un şir de caractere care poate deveni un nume valid de
fişier ce va înlocui pe _FILE_

#include <stdio.h>
#line 20
void main ()
LIMBAJUL C TEORIE ŞI APLICAŢI I 140

{
printf (“numarul acestei linii compilate este =%d”,_LINE_) ;
puts (“apasati o tasta ”) ;
getch ( ) ;
}
După rularea programului se va afişa valoarea 23 , numărarea liniilor
compilate va începe cu valoarea 20 la compilarea liniei void main ().
Operatori de preprocesare # şi ##.
Aceşti operatori se folosesc cu directiva #define şi realizează următoarele operaţii.
# numit operator de înşiruire , transformă argumentul pe care îl precede într-un
şir de caractere delimitat de dublu apostroafe “ şir “.
#include <stdio.h>
#define text(a) # a
void main ()
{
puts (“functia printf va afisa textul inceput de drum in C \n”) ;
printf (text(inceput de drum in C)) ;
}
După rularea programului se va afişa pe ecran inceput de drum in C ca şi cum acesta ar
fi fost încadrat între “ “ la compilare.
## numit operator de lipire va concatena cele două argumente ale directivei
#define, astfel la apelarea macro va rezulta ca şi cum ar avea un singur argument.

#include <stdio.h>
#define text(a,b) a ##b
void main ()
{
float ab=5 ;
puts (“functia printf va afisa valoarea lui ab=5 \n”) ;
printf (“ %d “text(a,b)) ;
}

4. Grafică în C.
Compilatorul C de sub Dos are două moduri de lucru pentru prezentarea
informaţiei pe ecranul monitorului :
Modul text.
Modul grafic.
Pentru fiecare mod de lucru utilizatorul poate alege diferite rezoluţii.
Diferenţa esenţială între cele două moduri constă în felul în care se adresează cea mai
mică unitate adresabilă pe ecran.
Modul text lucrează cu celula caracter, ce este o matrice de pixeli, aceasta
reprezintă unitatea adresabilă pe ecran. În modul text ecranul este împărţit în linii şi
coloane.
Modul grafic lucrează cu pixel, ce este cel mai mic punct afişabil pe ecran.
Dimensiunile pixelului depind de calităţiile monitorului folosit cât şi de placa grafică
ce pregăteşte datele afişabile.
LIMBAJUL C TEORIE ŞI APLICAŢI I 141

Forma unui pixel este dreptunghilară, care influenţează aspectul informaţiei afişate pe
ecran. Pentru monitoarele de tip VGA sau SVGA nu mai este nevoie să se corecteze
aspectul pixelului, prin indicarea raportului aspectual, care poate fi considerat egal 1.
Biblioteca grafică este portabilă sub sistemul de operare DOS şi conţine :
Constante.
Structuri de date predefinite.
Prototipul funcţiilor grafice.
Codurile funcţiilor.
Driverele pentru monitor şi placa grafică.
Seturi de caractere.
Pentru a se putea lucra în mod grafic, fişierul sursă trebuie să aibe incluse fişierele :
graphics.h graphics.lib *.bgi
4.1. Moduri grafice.
Calculatoarele personale folosesc pentru prezentarea informaţiilor grafice sau text o
placă grafică şi un monitor. Funcţie de combinaţia monitor şi placa grafică se defineşte,
numărul de culori şi rezoluţia de afişare. Adaptorul grafic şi draivărul grafic suportat de
biblioteca grafică se prezintă în tabelul următor.

Adaptor Driver
Color graphics adapter CGA
Multi color graphics adapter MCGA
Enhanced graphics adapter EGA, EGAMONO
Video graphics array VGA
Hercules graphics adapter HERCMONO
AT&T 400line graphics adapter ATT400
3270 PC graphics adapter PC3270
IBM 8514 graphics adapter IBM8541
Fiecare adaptor poate opera în mai multe moduri, utilizatorul este cel care va specifica
modul de lucru. Driverul şi adaptorul grafic trebuie să fie în concordanţă cu sistemul
video existent pe calculator
Pentru a determina corect resursa video a calculatorului, se va folosi funcţia initgraph.
În tabelul următor se prezintă drivere, modurile grafice suportate de compilatorul
Borland.

DRIVER MOD VALOARE DESCRIERE


CGA CGAC0 0 320X200X4COLOR
CGAC1 1 320X200X4COLOR
CGAC2 2 320X200X4COLOR
CGAC3 3 320X200X4COLOR
CGAHI 4 640X200X2COLOR
MCGA MCGAC0 0 320X200X4COLOR
MCGAC1 1 320X200X4COLOR
MCGAC2 2 320X200X4COLOR
LIMBAJUL C TEORIE ŞI APLICAŢI I 142

MCGAC3 3 320X200X4COLOR
MCGAMED 4 640X200X2COLOR
MCGAHI 5 640X480X2COLOR
EGA EGAL0 0 640X200X16COLOR
EGAHI 1 640X350X16COLOR
EGA64 EGA64L0 0 640X200X16COLOR
EGA64HI 1 640X350X16COLOR
EGAMONO EGAMONOHI 3 640X200X2COLOR
VGA VGAL0 0 640X200X16COLOR
VGAMED 1 640X350X16COLOR
VGAHI 2 640X480X16COLOR
ATT400C0 MCGAC0 0 320X200X4COLOR
ATT400C1 1 320X200X4COLOR
ATT400C2 2 320X200X4COLOR
ATT400C3 3 320X200X4COLOR
ATT400MED 4 640X200X2COLOR
ATT400HI 5 640X400X2COLOR
HERC HERCMONO 0 720X348X2COLOR
PC3270 PC3270HI 0 640X350X2COLOR
IBM8514 IBM8514L0 0 640X80X256COLOR
IBM8514HI 1 1024X768X256COLOR

4.2. Sisteme de cordonate.


În modul de lucru grafic ecranul monitorului este considerat o hartă de pixeli,
poziţionarea pe această hartă se efectuează prin indicarea cordonatelor x şi y.
Numărul de pixeli pe orizontală şi verticală este determinat de modul video obţinut prin
funcţia initgraph.
Biblioteca grafică foloseşte două sisteme de cordonate astfel :
Sistemul de cordonate global (fizic ), cu originea sistemului în colţul din
stânga sus aecranului.
Sistemul de cordonate al ferestrei de afişare (local), cu originea sistemului
în colţul din stânga sus al ferestrei.
Axa pozitivă x se desfăşoară de la stânga la dreapta, iar axa pozitivă y de sus în jos,
atât pentru sistemul global cât şi sistemul local.
Sistemul global este folosit pentru poziţionarea ferestrelor, implicit a sistemelor de
cordonate locale. Zona de afişare grafică implicită este tot ecranul şi cele două sisteme
de cordonate sunt identice.Poziţia de lucru este dată de cursorul grafic, ce reprezintă
punctul curent al pixelului, asupra căruia se va aplica noua comandă.
LIMBAJUL C TEORIE ŞI APLICAŢI I 143

Cursorul grafic este folosit ca punct de start în funcţiile grafice, iar poziţia acestuia este
păstrată în cordonatele locale ale ferestrei active.
Poziţia cursorului grafic poate fi modificată prin funcţiile moveto şi moverel, sau
implicit prin acţiunea funcţiilor lineto şi outtext.
4.3. Culori şi palete de culori.
În modul grafic fiecare pixel de pe ecran este caracterizat prin cordonatele x, y,
culoare. Culoarea pixelului este păstrată ca o valoare în paleta de culori curentă.
Paleta de culori poate avea de la 2 la 256 de culori, în funcţie de modurile suportate de
sistemul video al calculatorului. Adaptoarele EGA şi VGA folosesc o paletă de 16
culori prezentată în tabelul următor :
CONSTANTA DE CULOARE VALOARE INDEX DE PALETĂ
EGA_BLACK 0 0
EGA_BLUE 1 1
EGA_GREEN 2 2
EGA_CYAN 3 3
EGA_RED 4 4
EGA_MAGENTA 5 5
EGA_LIGHTGRAY 7 6
EGA_BROWN 20 7
EGA_DARKGRAY 56 8
EGA_LIGHTBLUE 57 9
EGA_LIGHTGREEN 58 10
EGA_LIGHCYAN 59 11
EGA_LIGHTRED 60 12
EGA_LIGHTMAGENTA 61 13
EGA_YELLOW 62 14
EGA_WHITE 63 15

4.4. Moduri de umplere.


Funcţiile bar, bar3d, fillpoly şi floodfill sunt folosite pentru a crea desene pline.
Pentru a crea aceste desene pline, este necesar să se folosească diferite modele de
umplere, cât şi culori de umplere. Culoarea şi modelul de umplere sunt controlate prin
funcţiile setfillpattern şi setfillstyle.
Modelele de umplere sunt prezentate în tabelul următor.

CONSTANTĂ VALOARE SEMNIFICAŢIE


EMPTY_FILL 0 Fără umplere
SOLID_FILL 1 Umplere cu culoare curentă
LINE_FILL 2 Umplere cu linii orizontale
LITSLASH_FILL 3 Umplere cu slash-uri subţiri
SLASH_FILL 4 Umplere cu slash-uri groase
BKSLASH_FILL 5 Umplere cu backslash-uri groase
LIMBAJUL C TEORIE ŞI APLICAŢI I 144

LTBKSLASH_FILL 6 Umplere cu backslash-uri subţiri


HATCH_FILL 7 Umplere cu deschizături mici
XHATCH_FILL 8 Umplere cu deschizături mari
INTERLEAVE_FILL 9 Umplere cu model întreţesut
WIDE_DOT_FILL 10 Umplere cu model punctat rar
CLOSE_DOT_FILL 11 Umplere cu model punctat des
USER_FILL 12 Umplere cu model definit de
utilizator

4.5. Stiluri de linii.


Majoritatea funcţiilor de desenare folosesc diferite modele de linii.
Stilul de linie descrie modelul de linie, grosimea de linie.
Modelul de linie poate fi ales dintre modele din biblioteca sau poate fi definit de
utilizator. În tabelul ce urmează se prezintă modelele predefinite.

CONSTANTĂ VALOARE SEMNIFICAŢIE


SOLID_LINE 0 Linie continuă
DOTTED_LINE 1 Linie punctată
CENTER_LINE 2 Linie punctată centrată
DASHED_LINE 3 Linie intreruptă din linii
USERBIT_LINE 4 Linie definită de utilizator
Grosimea liniei poate avea două valori de 1 pixel sau de 3 pixeli.
În tabelul ce urmează sunt prezentate valorile pentru grosimea liniei.

CONSTANTA VALOAREA SEMNIFICAŢIA


NORM_WIDTH 1 Grosimea de 1 pixel
THICK_WIDTH 3 Grosimea de 3 pixeli

4.6. Afişarea textului în mod grafic.


Funcţiile de afişare printf, sprintf şi cprintf folosite în mod text, nu pot fi folosite în
modul grafic. Pentru prezentarea în modul grafic a textului se folosesc funcţii
specificecum ar fi :
Gettextseting.
Outtext.
Outtextxy.
Settextjustify.
Settextstyle.
Textheight.
Pentru a lucra cu aceste comenzi, s-a prevăzut o hartă de 8x8 biţi şi 4 fonturi vectoriale
folosite la afişarea textului.
În tabelul se prezintă fonturile folosite :
LIMBAJUL C TEORIE ŞI APLICAŢI I 145

CONSTANTĂ VALOARE SEMNIFICAŢIE


DEFAULT_FONT 0 Hartăde 8x8 biţi
TRIPLEX_FONT 1 Font vectorial triplex
SMALL_FONT 2 Font vectorial mic
SANS_SERIF_FONT 3 Font vectorial san_serif
GOTHIC_FONT 4 Font vectorial gotic

Dacă compilatorul folosit acceptă versiunea Borland 3.1, la lista de fonturi prezentată
în tabelul se mai adaugă un număr de 6 fonturi.

CONSTANTĂ SEMNIFICAŢIE
BOLD_FONT font vectorial aldin
COMPLEX_FONT font vectorial complex
EUROPEAN_FONT font vectorial european
SCRIPT_FONT font vectorial de mână
SIMPLEX_FONT font vectorial simplex
TRIPLEX_SCRIPT_FONT font vectorial triplex de mână

Scrierea textului se poate efectua de la stânga la dreapta sau de jos în sus, apelând două
constante HORIZ_DIR şi VERT_DIR.
Valorile acestor constante sunt 0 şi respectiv 1.
Aşezarea textului în raport cu poziţia cursorului grafic se realizează cu funcţia
settextjustify ce foloseşte următoarele constante :
Pentru aliniere orizontală se prezintă în tabelul constantele şi semnificaţia lor.
CONSTANTĂ VALOARE SEMNIFICAŢIE
LEFT_TEXT 0 Aliniat la stinga
CENTER_TEXT 1 Aliniat centrat
RIGHT_TEXT 2 Aliniat la dreapta

Pentru aliniere verticală se prezintă în tabelul constantele şi semnificaţia lor.

CONSTANTĂ VALOARE SEMNIFICAŢIE


BOTTOM_TEXT 0 Aliniat jos
CENTER_TEXT 1 Aliniat centrat
TOP_TEXT 2 Aliniat sus

4.7. Tipuri de date folosite în funcţiile grafice.


Pentru utilizarea funcţiilor grafice sunt necesare un anumit tip de date, care pot
fi : structuri, constante, întregi.
arccoordstype
LIMBAJUL C TEORIE ŞI APLICAŢI I 146

Transmiterea argumentelor funcţiei getarccoords se efectuează printr-o dată de tip


structură numită arccoordstype astfel :

struct
{
int x,y ;
int xstar,ystar ;
int xend, yend ;
};

Unde x,y sunt coordoatele centrului cercului din care face parte arcul.
Xstar, ystar sunt coordonatele punctului de unde începe arcul .
Xend , yend sunt coordonatele punctului de sfârşit a arcului.
Datele din structură pot fi folosite pentru a creea alte entităţi legate de punctele
specifice ale arcului.
fillsettingstype
Tip de dată structură folosit la transmiterea argumentului funcţiei getfillsetting ce
conţine setările pentru umplerea suprafeţelor.
Structura lui fillsettingstype este :

struct fillsettingstype
{
int pattern ;
int color :
};

Unde pattern este o valoare întreagă ce indică modelul de umplere conform


tabelului .
Color este o valoare de tip întreg ce indică culoarea de umplere
conform tabelului .

Graphics_errors
Este o constantă de tip enumerare ce conţine codurile de eroare rezultate la
apelarea funcţiei graphresult, folosită pentru depanarea programelor de grafică cu erori.
În tabelul seprezintă codul de eroare, constanta şi mesajul de eroare.

COD DE CONSTANTĂ MESAJ DE EROARE


EROARE
0 grOK Nici o eroare
-1 grNoInitGraph Driverul grafic BGI neinstalat
-2 GrNotDetectd Placa grafică negăsită
-3 GrFileNotFound Fişierul pentru driverul grafic negăsit
-4 GrInvalidDriver Fişierul invalid pentru driver grafic
-5 GrNoLoadMem Memorie insuficientă pentru driver grafic
LIMBAJUL C TEORIE ŞI APLICAŢI I 147

-6 GrNoScamMem Memorie insuficientă pentru fillpoly


-7 GrNoFloodMem Memoria insuficientă pentru floodfill
-8 GrFontNotFound Fişier de font negăsit
-9 GrNoFontMem Memorie insuficientă pentru fonturi
-10 GrInvalidMode Mod grafic nepermis pentru driver grafic
-11 GrError Eroare grafică
-12 GrIError Eroare grafică de intrare-ieşire
-13 GrInvalidFont Fişier de font invalid
-14 GrInvalidFontNum Număr de font invalid
-15 GrInvalidDeviceNum Număr de driver invalid
-18 grInvalidVersion Număr de versiune invalid

Linesettingstype
Dată de tip structură folosită pentru transmiterea argumentelor funcţiilor
getlinesetting şi setlinestyle prin care se stabileşte modelul şi grosimea linilor.

Struct linesettingstype
{
int linestyle ;
unsigned upattern
int thicknes
}
linestyle determină cu ce model de linie vor fi desenate liniile de la acest
moment până la o nouă modificare a modelului.
Upattern determină modelul de umplere ce a fost în prealabil definit de
utilizator, această dată se foloseşte dacă linestyle are valoarea USSERBIT_LINE.
Thicknes determină grosimea liniilor.

Palettetype

Dată de tip structură predefinită prin care se transmit argumentele funcţiei


getpalette, setpalette, setallpalette, prin indicarea numărului de culori din paletă şi
culoarea.
Struct palettetype
{
unsigned char size ;
signed char colors [MAXCOLORS +1] ;
}

size conţine numărul de culori ale paletei curente,


colors este un tablou de tip vector, a cărui mărime este egală cu size octeţi şi
conţine valoarea numerică pentru fiecare culoare din paletă.
LIMBAJUL C TEORIE ŞI APLICAŢI I 148

MAXCOLORS
MAXCOLORS este o constantă ce conţine numărul maxim de intrări în
paleta de culori a structurii palettetype. Valoarea acestei constante depinde de driverul
şi modul grafic setat în cadrul sistemului.

Pointttype
Pointtype este o dată de tip structură care este folosită pentru reprezentarea unui punct.
Structura conţine cele două cordonate x,y ale punctului.

struct pointtype
{
int x;
int y;
}

textsettingstype
Dată de tip structură folosită de funcţia gettextsettings pentru transmiterea
parametrilor. Funcţia gettextsettings citeşte setările curente pentru textul în mod
grafic.
Struct textsettingstype
{
int font ;
int direction ;
int charsize ;
int horiz ;
int vert ;
}
font reprezintă fontul folosit la afişarea textului,
direction o valoare numerică 0 sau 1 ce indică direcţia de scriere a textului,
charsize indică mărimea caracterelor folosite la scrierea şi afişarea textului,
horiz reprezintă o valoare numerică 0,1,2 ce indică modul de aliniere pe
direcţia orizontală a textului,
vert reprezintă o valoare numerică 0,1,2 ce indică modul de aliniere pe direcţia
verticală a textului.

Viewporttype
Dată de tip structură folosită pentru transmiterea argumentelor funcţiei getviewsetting,
ce conţine setările curente ale ferestrei de afişare.

Struct viewporttype
{
int left ;
int top ;
int right ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 149

int bottom ;
int clip ;
}

left reprezintă coordonata fizică a marginii din stânga a ferestrei curente,


top reprezintă coordonata fizică a marginii superioare a ferestrei curente,
right reprezintă coordonata fizică a marginii din dreapta a ferestrei curente,
bottom reprezintă coordonata fizică a marginii inferioare a ferestrei curente,
clip reprezintă atributul de decupare, care indică dacă elementele desenate pot
fi reprezentate şi în afara ferestrei curente, în caz contrar entităţiile sunt tăiate în afara
ferestrei curente.
4.8. FUNCŢII DE DESENARE.

4.8.1. ARC.
Funcţia arc permite desenarea unui arc de cerc, la care utilizatorul va indica pe rând:
Centrul cercului din care face parte arcul prin coordonatele x şi y.
Unghiul de unde începe desenarea arcului.
Unghiul unde se termină desenarea arcului.
Raza cercului din care face parte arcul.
Desenarea arcului se face de la unghiul de început şi se continuă în sens trigonometric
până la unghiul de terminare.
Valoarea 0 a unghiului este considerat quadrantul din dreapta centrului cercului.
Trasarea arcului se execută ţinând cont de grosimea liniei de desenare, dar nu permite
trasarea decât cu linie continuă.
Prototipul funcţiei arc este :

Void far arc (int x,int y, int startangle, int endangle, int radius);

Funcţia nu returnează nici o valoare.


Valorile pentru x şi y trebuie să fie pozitive şi mai mici decât valorile maxime ale
ecranului de desenare, mărimea unghiurilor de start şi de sfârşit se indică în grade
sexazecimale, iar raza în unităţi folosite la dimensionarea ecranului.

Exemplu.

# include <stdio.h>
# include <conio.h>
# include <graphics.h>
# include <stdlib.h>
void main ()
{ Acest pachet de instrucţiuni şi definirea
variabilelor până la apelarea funcţiei setfillstyle
este comun majorităţii programelor ce folosesc
LIMBAJUL C TEORIE ŞI APLICAŢI I 150

funcţiile grafice, care vor fi descrise în capitolele


următoare.
int gdriver = DETECT,gmode,errorcode;
unsigned long s;
int xmax,ymax;
puts ("desenarea arcului de cerc");
getch ();
clrscr ();
xmax=getmaxx();ymax=getmaxy();
initgraph(&gdriver,&gmode," "); iniţializarea modului grafic
setviewport(0,0,getmaxx(),getmaxy(),0); definirea zonei curente de desenare,
errorcode=graphresult();
if(errorcode!=grOk)
printf("Eroare grafica: %s\n",grapherrormsg(errorcode));
cleardevice(); ştergerea conţinutului ecranului grafic,
setcolor (RED); setarea culorii de desenare pe culoarea roşu
setfillstyle (SOLID_FILL,RED);setarea tipului de umplere şi culoarea

arc (50,50,0,180,25); desenarea arcului cu centru cercului la


coordonatele x=50, y=50, unghiul de start =0,
unghiul de sfârşit =180 grade şi raza =25 unităţi
culoarea de desenare este roşu.
arc (100,50,90,270,25); desenarea arcului cu centru cercului la
coordonatele x=100, y=50, unghiul de start =90,
unghiul de sfârşit =270 grade şi raza =25 unităţi
culoarea de desenare este roşu.

arc (150,50,0,-90,25); desenarea arcului cu centru cercului la


coordonatele x=150, y=50, unghiul de start =0,
unghiul de sfârşit =-90 grade şi raza =25 unităţi
culoarea de desenare este roşu.

setcolor (BLUE); setarea culorii de desenare pe culoarea albastru


(BLUE)
arc (150,100,0,270,50); desenarea arcului cu centru cercului la coordonatele
x=150, y=100, unghiul de start =0, unghiul de
sfârşit =270 grade şi raza =50 unităţi culoarea de
desenare este albastru.
getch ();
}

4.8.2. Bar
Funcţia bar desenează o bară dreptunghiulară plină, culoarea de umplere este inpusă de
funcţia setfillstyle. Conturul barei nu este scos în evidenţă, de aceia se recomandă
LIMBAJUL C TEORIE ŞI APLICAŢI I 151

culoarea de umplere să fie diferită de culoarea de fond a ferestrei curente pentru


desenare. Prototipul funcţiei bar este -.

void far bar (int left, int top, int right, int bottom);

int left colţul din stânga,


int top colţul de sus,
int right colţul din dreapta,
int bottom colţul de jos,
Exemplu.

# include <stdio.h>
# include <conio.h>
# include <graphics.h>
void main ()
{
int gdriver = DETECT,gmode,errorcode;
int xmax,ymax;
clrscr (); ştergerea ecranului în mod text,
initgraph(&gdriver,&gmode," ");iniţializarea modului grafic
xmax=getmaxx();ymax=getmaxy();detectarea valorilor coordonatelor x, y ale
colţului dreapta jos pentru driverul detectat,
setviewport(0,0,xmax,ymax,0);definirea zonei curente de desenare,
printf ("x max=%d y max=%d",xmax,ymax); xmax=639, ymax=479 şi reprezintă
coordonatele maxime ale colţului din dreapta jos,
pentru driverul şi modul grafic detectat automat
de gdriver, funcţie de resursele hard ale
calculatorului,
errorcode=graphresult();
if(errorcode!=grOk)
printf("Eroare grafica: %s\n",grapherrormsg(errorcode));
getch ();
cleardevice(); ştergerea conţinutului ecranului grafic,
setfillstyle (SOLID_FILL,RED);se setează culoarea de umplere roşu şi modelul
de umplere linie solidă plină
bar (100,100,300,479); se desenează o bară plină cu culoarea roşie , colţul
din stânga sus de coordonate 100, 100 şi colţul din
dreapta jos de coordonate 300,479,
setfillstyle (SOLID_FILL,BLUE); se setează culoarea de umplere albastru şi
modelul de umplere linie solidă plină

bar (300,240,638,450); se desenează o bară plină cu culoarea albastră,


colţul din stânga sus de coordonate 300, 240 şi
colţul din dreapta jos de coordonate 638,450.
puts ("apasa o tasta");
getch ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 152

4.8.3. Bar3d
Funcţia bar3d desenează o prismă dreaptă cu baza un dreptunghi, la care utilizatorul va
indica punctele caracteristice. Spre deosebire de funcţia bar, funcţia bar3d desenează
muchiile prismei cu culoarea de desenare setată, iar faţa 1 (frontală) este umplută cu
culoarea şi modelul date de funcţia setfillstyle . Prin parametrul topflag funcţia bar3d
va contura sau nu faţa superioară a prismei.
Prototipul funcţiei bar3d este :

Void far bar3d (int left, int top, int right, int bottom, int depth, int topflag);

int left colţul din stânga,


int top colţul de sus,
int right colţul din dreapta,
int bottom colţul de jos,
int drepth adâncimea prizmei dreptunghiulare, reprezentată prin unităţi de
pixeli
int topflag are valoarea 0 sau pozitivă, dacă valoarea este 0 nu se desenează
faţa superioară, dacă valoarea este pozitivă se va desena faţa superioară a
prismei.

Exemplu.
În cadrul acestui exemplu se indică doar liniile de cod specifice utilizării funcţiei
bar3d, pentru a realiza întregul fişier se va adăuga pachetul de linii de cod de început
prezentat în fişierul anterior.

cleardevice();
setfillstyle (SOLID_FILL,RED); se setează culoarea de umplere roşu şi modelul
de umplere linie solidă plină

bar3d (100,100,300,479,30,1); se desenează o bară 3d plină cu culoarea roşie ,


colţul din stânga sus de coordonate 100, 100 şi
colţul din dreapta jos de coordonate 300,479,
adâncimea de 30 pixeli, faţa superioară a barei
este reprezentată.
Muchiile prizmei sunt desenate cu culoarea
implicită, în cazul de faţă albă.

setfillstyle (SOLID_FILL,BLUE); se setează culoarea de umplere albastru şi


modelul de umplere linie solidă plină

setcolor (RED); se setează culoarea de desenare roşu care va fi


culoarea de desenare a muchiilor barei3d,
LIMBAJUL C TEORIE ŞI APLICAŢI I 153

bar3d (300,240,538,400,10,0); se desenează o bară plină cu culoarea albastră,


colţul din stânga sus de coordonate 300, 240 şi
colţul din dreapta jos de coordonate 538,400,
adâncimea de 10 pixeli, faţa superioară a barei
este nereprezentată (topflag=0).
Muchiile prismei sunt desenate cu culoarea setată,
în cazul de faţă roşu.
.
puts ("apasa o tasta");
getch ();
}

4.8.4. Circle
Funcţia circle desenează un cerc la care utilizatorul indică cordonatele x,y ale centrului
cercului şi raza. Culoarea de desenare este culoarea curentă, setată prin setcolor. Linia
de desenare a cercului poate avea grosime, dar tipul de linie este continuă indiferent de
modelul de linie setat.
Prototipul funcţiei circle este ;

Void far circle (int x, int y, int radius);

int x coordonata x a centrului cercului,


int y coordonata y a centrului cercului,
int radius raza cercului exprimată în pixeli.

Exemplu.

cleardevice();
setfillstyle (SOLID_FILL,RED);
circle (50,50,25); desenează un cerc cu centru de coordonate x=50,
y=50 şi raza =25, culoarea de desenare albă,
culoare setată implicit.
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
circle (100,200,50); desenează un cerc cu centru de coordonate x=100,
y=200 şi raza =50, culoarea de desenare roşie,
culoare setată prin funcţia setcolor.

puts ("apasa o tasta");


getch ();
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 154

4.8.5. Rectangle
Funcţia rectangle desenează un dreptunghi, la care utilizatorul va preciza colţul
dinstânga sus şi colţul din dreapta jos. Culoarea de desenare a dreptunghiului cât şi
modelul , stilul liniei de desenare sunt cele curente. Spre deosebire de funcţia bar
conturul dreptunghiului este desenat cu culoarea curentă şi poate fi umplut cu o
anumită culoare sau model prin funcţia floodfill.
Prototipul funcţiei rectangle este :

Void far rectangle (int left, int top, int right, int bottom) ;

int left colţul din stânga,


int top colţul de sus,
int right colţul din dreapta,
int bottom colţul de jos,

Exemplu

cleardevice();
setfillstyle (SOLID_FILL,RED);
rectangle (50,50,450,60); desenează un dreptunghi cu colţul stânga sus de
coordonate x=50, y=50, iar colţul dreapta jos de
coordonate x=450, y=60, dreptunghi dezvoltat pe
orizontală de culoare albă.
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
rectangle (150,200,160,400); desenează un dreptunghi cu colţul stânga sus
de coordonate x=150, y=200, iar colţul dreapta jos
de coordonate x=160, y=400, dreptunghi
dezvoltat pe verticală de culoare roşu,
puts ("apasa o tasta");
getch ();
}

4.8.6. Line
Funcţia line desenează o linie (un segment de dreaptă) între două puncte specificate de
utilizator, cu culoarea, tipul de linie setat anterior apelări funcţiei line. Poziţia
cursorului grafic nu este modificată de funcţia line.
Prototipul funcţiei line este :
Void far line (int x1, int y1, int x2, int y2) ;

int x1 coordonata x a primului punct ce delimitează linia,


int y1coordonata y a primului punct ce delimitează linia ,
int x2 coordonata x a celui de-al doilea punct ce delimitează linia,
int y2 coordonata y a celui de-al doilea punct ce delimitează linia,
LIMBAJUL C TEORIE ŞI APLICAŢI I 155

Exemplu.

cleardevice();
setfillstyle (SOLID_FILL,RED);
line (50,50,450,50); desenează o linie orizontală între punctele de
coordonate x=50, y=50 şi x=450, y=50, culoarea
şi stilul liniei setat anterior,
line (60,70,60,200); desenează o linie verticală între punctele de
coordonate x=60, y=70 şi x=60, y=200, culoarea
şi stilul liniei setat anterior,
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
line (150,200,360,300); desenează o linie înclinată între punctele de
coordonate x=150, y=200 şi x=360, y=300,
culoarea roşie şi stilul liniei setat anterior,
puts ("apasa o tasta");
getch ();
}

4.8.7. Moveto
Funcţia moveto plasează cursorul grafic în punctul de coordonate x, y
specificate de utilizator prin argumentele funcţiei.
Deplasarea cursorului grafic într-un punct este necesar înaintea apelării funcţiilor
linerel, lineto, outtext, moverel.
Prototipul funcţiei move este :

Void far move (int x,int y) ;

int x coordonata x a punctului de poziţionare pentru cursorul grafic,


int y coordonata y a punctului de poziţionare pentru cursorul grafic,

4.8.8. linerel
funcţia linerel desenează un segment de dreaptă din poziţia curentă a
cursorului grafic, la punctul situat relativ faţă de poziţia cursorului grafic prin
deplasările dx, dy . Deplasările relative dx şi dy pot avea valori pozitive, nule sau
negative. Linia desenată respectă culoarea, stilul şi modelul setate anterior apelării
funcţiei linerel. Se recomandă ca anterior apelării funcţiei linerel să se apeleze funcţia
move pentru poziţionarea cursorului grafic în poziţia dorită.
Prototipul funcţiei linerel este :

Void far linerel (int dx, int dy) ;


LIMBAJUL C TEORIE ŞI APLICAŢI I 156

int dx deplasarea relativă a capătului segmentului de dreaptă pe direcţia axei x


în raport cu poziţia cursorului grafic,

int dy deplasarea relativă a capătului segmentului de dreaptă pe direcţia axei y


în raport cu poziţia cursorului grafic.

Exemplu

cleardevice();
setfillstyle (SOLID_FILL,RED);
moveto (50,50); poziţionarea cursorului grafic în punctul de
coordonate x=50, y=50, necesar pentru trasarea
segmentului de dreaptă din acest punct,
linerel (400,0); desenarea segmentului de dreaptă din poziţia
cursorului grafic, apelat prin funcţiia anterioară
moveto, la noul punct declarat prin coordonatele
relative dx=400, dy=0, rezultă o dreaptă
orizontală indentică cu dreapta obţinută prin
apelarea funcţiei line (50,50,450,50);din
exemplul anterior.Folosirea acestui mod de trasare
a unei linii permite simplificarea argumentelor de
apelare a funcţiilor de desenare.

moveto (60,70); poziţionarea cursorului grafic în punctul de


coordonate x=60, y=70, necesar pentru trasarea
segmentului de dreaptă din acest punct,

linerel (0,130); desenarea segmentului de dreaptă din poziţia


cursorului grafic, apelat prin funcţiia anterioară
moveto, la noul punct declarat prin coordonatele
relative dx=0, dy=130, rezultă o dreaptă verticală
identică cu dreapta obţinută prin apelarea funcţiei
line (60,70,60,200);
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
moveto (150,200); poziţionarea cursorului grafic în punctul de
coordonate x=150, y=200, necesar pentru trasarea
segmentului de dreaptă din acest punct,

linerel (210,100); desenarea segmentului de dreaptă din poziţia


cursorului grafic, apelat prin funcţiia anterioară
moveto, la noul punct declarat prin coordonatele
relative dx=210, dy=100, rezultă o dreaptă
înclinată identică cu dreapta obţinută prin apelarea
funcţiei line (150,200,360,300);
LIMBAJUL C TEORIE ŞI APLICAŢI I 157

puts ("apasa o tasta");


getch ();
}

4.8.9. lineto
funcţia lineto desenează un segment de dreaptă din poziţia curentă a cursorului grafic la
punctul de coordonate, x, y specificate în argumentele funcţiei.
Linia desenată respectă culoarea, stilul şi modelul setate anterior apelării funcţiei
lineto. Se recomandă ca anterior apelării funcţiei lineto să se apeleze funcţia move
pentru poziţionarea cursorului grafic în poziţia dorită.
Prototipul funcţiei lineto este :

void far lineto (int x, int y) ;

int x coordonata x a punctului de terminare pentru linia desenată,


int y coordonata y a punctului de terminare pentru linia desenată,

Exemplu.

cleardevice();
setfillstyle (SOLID_FILL,RED);
moveto (50,50);
lineto (450,50); desenează un segment de dreaptă din poziţia
curentă a cursorului grafic indicată de funcţia
moveto, la punctul de coordonate x=450, y=50,
rezultă o dreaptă orizontală identică cu dreapta
trasată prin funcţiile line (50,50,450,50); şi
linerel (400,0);din exemplele anterioare,
moveto (60,70);
lineto (60,200); desenează un segment de dreaptă din poziţia
curentă a cursorului grafic indicată de funcţia
moveto, la punctul de coordonate x=60, y=200,
rezultă o dreaptă verticală identică cu dreapta
trasată prin funcţiile line (60,70,60,200); şi
linerel (0,130); din exemplele anterioare,

setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
moveto (150,200);
lineto (360,300); desenarea segmentului de dreaptă din poziţia
cursorului grafic, apelat prin funcţiia anterioară
moveto, la noul punct declarat prin coordonatele
x=360, y=300, rezultă o dreaptă înclinată identică
cu dreapta obţinută prin apelarea funcţiilor line
(150,200,360,300); şi linerel (210,100);
LIMBAJUL C TEORIE ŞI APLICAŢI I 158

puts ("apasa o tasta");


getch ();
}

4.8.10. moverel
Funcţia moverel poziţionează cursorul grafic relativ faţă de vechea poziţie cu
deplasarile dx şi dy indicate prin argumentele funcţiei.
Valorile deplasărilor dx şi dy pot avea valori negative, nule sau pozitive.
Prototipul funcţiei moverel este :

Void far moverel (int dx, int dy) ;

int dx =deplasarea pe direcţia axei x,


int dy = deplasarea pe direcţia axei y.
Funcţia moverel este folosită după apelarea funcţiei setviewport, datorită faptului
că poziţia curentă a cursorului grafic devine 0,0 raportat la colţul stânga sus a ferestrei
curente de desenare.

Exemplu.

cleardevice();
setviewport(150,150,xmax,ymax,0);definirea zonei curente de afişare grafică,
cu colţul stânga sus dat de coordonatele x=150,
y=150, ce are ca efect şi poziţionarea cursorului
grafic în colţul stânga sus a ferestrei curente.
setfillstyle (SOLID_FILL,RED);
moverel (50,50); deplasarea relativă a cursorului grafic cu dx=50,
dy=50 faţă de vechea poziţie a acestuia,
lineto (450,50); desenarea noilor entităţi raportate la noua poziţie
a cursorului grafic în noua fereastră,
moveto (60,70);
lineto (60,200);
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
moveto (150,200);
lineto (360,300);
puts ("apasa o tasta");
getch ();
}

4.8.11. drawpoly
Funcţia drawpoly permite desenarea unei polilinii cu un număr de vârfuri specificat de
utilizator cât şi coordonatele x, y ale fiecărui vârf.
LIMBAJUL C TEORIE ŞI APLICAŢI I 159

Dacă se doreşte realizarea unei polilinii închise (poligon) este necesar ca numărul de
vârfuri să fie cu 1 mai mare decât numărul de vârfuri ale poligonului şi coordonatele
ultimului vârf să fie indentice cu coordonatele primului vârf.
Desenarea poliliniei se face cu culoarea, tipul de linie şi modelul curent.
Prototipul funcţiei drawpoly este :
Void far drawpoly (int număr vârfuri, int far*puncte) ;

Int număr vârfuri = numărul de vârfuri ale poliliniei sau poligonului,


*puncte coordonatele x, y ale punctelor ce indică vârfurile, este un tablou de
tip vector cu mărimea egală cu numărul de vârfuri x 2.
Astfel :
puncte [0] = coordonata x a vârfului 1,
puncte [1] = coordonata y a vârfului 1,
puncte [2] = coordonata x a vârfului 2,
puncte [3] = coordonata y a vârfului 2,
…..
puncte [2n-2] = coordonata y a vârfului n.

Exemplu.

int xmax,ymax, puncte [10],puncte1 [10]; declararea tablourilor puncte şi


puncte1 care conţin coordonatele x,y ale
vârfurilor poliliniei,

cleardevice();
setviewport(100,100,xmax,ymax,0);
setfillstyle (SOLID_FILL,RED);
setcolor (RED);
puncte [0]=20; atribuirea coordonatei x a primului vârf,
puncte [1]=10; atribuirea coordonatei y a primului vârf,
puncte [2]=40; atribuirea coordonatei x a vârfului 2,
puncte [3]=10; atribuirea coordonatei y a vârfului 2,
puncte [4]=40;
puncte [5]=20;89
puncte [6]=20;
puncte [7]=20;
puncte [8]=20; atribuirea coordonatei x a ultimului vârf identică
cu coordonata primului vârf,
puncte [9]=10; atribuirea coordonatei y a ultimului vârf identică
cu coordonata primului vârf,
drawpoly (5,puncte); desenarea unei polilinii cu 5 vârfuri la care vârful
1 este identic cu vârful 5, rezultă un patrulater
(poligon închis),
puncte1 [0]=200; atribuirea coordonatei x a primului vârf, pentru o
nouă polilinie,
puncte1 [1]=100;
LIMBAJUL C TEORIE ŞI APLICAŢI I 160

puncte1 [2]=400;
puncte1 [3]=100;
puncte1 [4]=300;
puncte1 [5]=200;
puncte1 [6]=20;
puncte1 [7]=50;
puncte1 [8]=120;
puncte1 [9]=130;
drawpoly (5,puncte1); desenarea unei polilinii deschise cu 5 vârfuri,
coordonatele vârfurilor find în tabloul puncte1,
puts ("apasa o tasta");
getch ();
}

4.8.12. ellipse
Funcţia ellipse desenează un arc de elipsă la care utilizatorul precizează prin
argumentele funcţiei :
centru elipsei, unghiul de început, unghiul de sfârşit şi cele două raze pe
direcţiile x,y.
Desenarea arcului de elipsă începe de la unghiul de început în sens trigonometric spre
unghiul de sfârşit. Valoarea 0 a unghiului este considerat quadrantul din dreapta a
elipsei din care face parte arcul de elipsă. Trasarea arcului este în concordanţă cu
culoarea , grosimea liniei dar pentru modelul de linie foloseşte tipul continuă.
Prototipul funciei ellipse este :
Void far ellipse (int x, int y, int unghi_inceput, int unghi_sfârşit, int xraza, int
yraza) ;
int x= coordonata x a centrului elipsei din care face parte arcul,
int y= coordonata x a centrului elipsei din care face parte arcul,
int unghi_inceput =mărimea unghiului de inceput a arcului de elipsă,
int unghi_sfârşit=mărimea unghiului de sfârşit a arcului de elipsă,
int xraza=raza elipsei pe direcţia x,
int yraza) =raza elipsei pe direcţia y ;

Exemplu
cleardevice();
setfillstyle (SOLID_FILL,RED);
ellipse (100,200,0,90,40,80);desenează un arc de elipsă cu centrul în punctul
de coordonate x=100, y=200, cu unghiul de
început 0 iar unghiul de sfârşit =90, raza pe x=40,
raza pe y =80.
Dacă cele două raze sunt egale rezultă un arc de
cerc.
ellipse (200,200,0,-45,40,100); desenează un arc de elipsă cu centrul în
punctul de coordonate x=200, y=200, cu unghiul
de început 0 iar unghiul de sfârşit =-45, raza pe
x=40, raza pe y =100 care are ca efect desenarea
LIMBAJUL C TEORIE ŞI APLICAŢI I 161

unui arc de elipsă ce se desfăşoară pe 7 părţi din


cele 8 părţi ale elipsei.

puts ("apasa o tasta");


getch ();
}

4.8.13. fillellipse
Funcţia fillellipse desenează o elipsă completă. Culoarea de desenare şi modul de
umplere sunt alese funcţie de setările curente. Parametrii funcţiei fillelipse sunt centrul
elipsei şi cele două raze pe direcţiile x şi y. Dacă cele două raze sunt egale elipsa
desenată este un cerc plin.
Prototipul funcţiei fillellipse este :

Void far fillellipse (int x, int y, int razax, int razay) ;

int x = coordonata x a centrului elipsei,


int y = coordonata y a centrului elipsei,
int razax =mărimea razei elipsei pe direcţia x,
int razay =mărimea razei elipsei pe direcţia y,

Exemplu

cleardevice();
setfillstyle (SOLID_FILL,BLACK);setarea culorii de umplere indentic cu
culoarea de fond ferestrei de desenare, care va
crea iluzia că elipsa este trasată numai prin
conturul ei,
fillellipse (100,200,40,80);desenarea elipsei cu centrul în punctul de
coordonate x=100, y=200 şi razele rx=40, ry=80,
setfillstyle (SOLID_FILL,RED);setarea culoriide umplere pe roşu,
fillellipse (200,200,100,50); desenarea elipsei care va avea culoarea de
contur alb şi culoarea de umplere roşu,
puts ("apasa o tasta");
getch ();
}

4.8.14. fillpoly
Funcţia fillpoly desenează o polilinie închisă (poligon ) la care se va specifica
numărul de vârfuri şi coordonatele x,y ale acestor vârfuri. Spre deosebire de funcţia
drawpoly, funcţia fillpoly nu cere să se specifice ca ultimul vârf să fie indentic cu
primul vârf şi închide automat linia poligonală de la ultimul vârf indicat la primul vârf
al acesteia.Tabloul ce conţine coordonatele vârfurilor are mărimea dublă faţă de
LIMBAJUL C TEORIE ŞI APLICAŢI I 162

numărul de vârfuri.Primul termen al tabloului ce conţine coordonatele x,y reprezintă


coordonata x a primului vârf.
Prototipul funcţiei fillpoly este :

Void far fillpoly (int număr_vârfuri, int far*puncte) ;

int număr_vârfuri = numărul de vârfuri ale poliliniei sau poligonului,


*puncte= coordonatele x, y ale punctelor ce indică vârfurile, este un tablou de
tip vector cu mărimea egală cu numărul de vârfuri x 2.

Exemplu

cleardevice();
setviewport(100,100,xmax,ymax,0);
setfillstyle (SOLID_FILL,RED);
setcolor (RED);
puncte [0]=20; atribuirea coordonatei x a primului vârf,
puncte [1]=10; atribuirea coordonatei y a primului vârf,
puncte [2]=40; atribuirea coordonatei x a vârfului 2,
puncte [3]=10; atribuirea coordonatei y a vârfului 2,
puncte [4]=40;
puncte [5]=20;
puncte [6]=20;
puncte [7]=20; atribuirea coordonatei y a ultimului vârf
fillpoly (4,puncte); desenarea poligonului cu 4 vârfuri, culoarea de
umplere roşu şi culoarea de desenare alb
puncte1 [0]=200;
puncte1 [1]=100;
puncte1 [2]=400;
puncte1 [3]=100;
puncte1 [4]=300;
puncte1 [5]=200;
fillpoly (3,puncte1); desenarea poligonului cu 3 vârfuri (triunghi)
puts ("apasa o tasta");
getch ();
}

4.8.15. floodfill
Funcţia floodfill umple zona închisă care conţine punctul specificat de
utilizator prin coordonatele x,y. Modelul şi culoarea de umplere sunt cele setate curent
prin funcţia setfillstyle. Punctul care determină entitatea ce se umple trebuie să fie în
interiorul entităţii şi nu pe conturul ei. Entităţiile asupra cărora funcţia floodfill sunt :
circle (cercul), rectangle (dreptunghiul).
Prototipul funcţiei floodfill este :

Void far floodfill (int x, int y, int margine) ;


LIMBAJUL C TEORIE ŞI APLICAŢI I 163

int x= coordonata x a punctului interior a entităţii ce se umple cu culoare şi


model ,
int y= coordonata y a punctului interior a entităţii ce se umple cu culoare şi
model ,
int margine =culoarea entităţii care conţine punctul specificat.

Exemplu

cleardevice();
setfillstyle (SOLID_FILL,BLUE);
setcolor (RED);
rectangle (50,50,200,300);
setcolor (GREEN);
circle (300,200,50);
floodfill (100,150,RED); umplerea entităţii ce conţine punctul de
coordonate 100,150 în cazul de faţă dreptunghiul
care are ca şi culoare de graniţă culoarea roşu ,
umplerea se face cu culoarea albastru,
floodfill (300,200,GREEN); umplerea entităţii ce conţine punctul de
coordonate 300,200 în cazul de faţă cercul care
are ca şi culoare de graniţă culoarea verde ,
umplerea se face cu culoarea albastru,

puts ("apasa o tasta");


getch ();
}

4.8.16. outtext
Funcţia outtext permite afişarea unui şir de caractere, la poziţia curentă a
cursorului grafic.Se recomandă ca anterior apelării funcţiei outtext să se apeleze funcţia
moveto pentru poziţionarea cursorului grafic în poziţia de unde să fie afişat textul. Şirul
de caractere afişat de funcţia outtext poate fi direct specificat în apelarea funcţiei cât şi
prin apelarea unui tablou de caractere ce conţine textul.
Alinierea , culoarea, fontul, mărimea şi direcţia textului sunt cele curente.
Poziţia cursorului grafic este influenţată de funcţia text numai în cazul alinierii la
stânga şi direcţia orizontală, în acest caz cursorul grafic se poziţionează la terminarea
textului afişat. Dacă şirul de caractere afişat de funcţia outtext depăşeşte marginile
zonei curente de afişare se trunchiază.
Prototipul funcţiei outtext este :
Void far outtext (char *far şir de caractere) ;

char *far şir de caractere= şirul de caractere ce se afişează sau denumirea


tabloului ce conţine şirul de caractere.
LIMBAJUL C TEORIE ŞI APLICAŢI I 164

Exemplu

char text1 [30]; declararea unui tablou ce va conţine un şir de
caractere
int xmax,ymax;
clrscr ();
puts ("dati textul");
scanf ("%s",text1); citirea şirului de caractere ce va fi memorat în
tabloul text1
….
cleardevice();
setcolor (RED);
outtext ("scriere pe prima linie stinga "); apelarea funcţiei de afişare a
textului scriere pe prima linie stinga , care va
fi poziţionat pe prima linie şi prima coloană a
ferestrei de afişare (la poziţia curentă a cursorului
grafic,)
setcolor (GREEN);
outtext ("text 2 in continuarea primului text"); funcţia outtext va afişa
noul şir de caractere la noua poziţie a cursurului
grafic, care se află la sfârşitul şirului de caractere
de la apelarea anterioară a funcţieiouttext,
circle (300,200,50);
moveto (300,200); deplasarea cursorului grafic în centrul cercului,
outtext ("scrierea din centrul cercului"); afişarea textului din centrul
cercului, datorită funcţiei moveto care a poziţionat
cursorul grafic.
moveto (200,100);
outtext (text1); preluarea textului de afişat din tabloul text1.
getch ();
}

4.8.17. outtextxy
Funcţia outtextxy ca şi funcţia outtext afişează şirul de caractere specificat prin
parametri funcţiei, dar afişarea se începe din punctul de coordonate x,y. Toate
informaţiile de la funcţiaouttext rîmân valabile şi la funcţia outtextxy.

Prototipul funcţiei outtextxy este :

Void far outtextxy (int x, int y, char far*şir de caractere) ;

int x=coordonata x a punctului de unde începe afişarea textului,


int y=coordonata y a punctului de unde începe afişarea textului,
char *far şir de caractere= şirul de caractere ce se afişează sau denumirea
tabloului ce conţine şirul de caractere.
LIMBAJUL C TEORIE ŞI APLICAŢI I 165

Exemplu

char text1 [30];
int xmax,ymax;
clrscr ();
puts ("dati textul");
scanf ("%s",text1);

cleardevice();
setcolor (RED);
outtextxy (100,200,"scriere din punctul x=100,y=200 "); apelarea funcţiei
outtextxy care va afişa şirul de caractere scriere
din punctul x=100,y=200 începând din punctul
de coordonate x=100, y=200,
setcolor (GREEN);
outtextxy (200,300,text1); funcţia outtextxy va prelua şirul de caractere din
tabloul text1 şi îl va afişa de la punctul de
coordonate x=200, y=300,
getch ();
}

4.8.18. pieslice
Funcţia pieslice permite desenarea unui sector de cerc şi umple acest sector de
cerc cu modelul, culoarea şi tipul de linie curent.
Utilozatorul va preciza coordontele x,y ale centrului cercului, valoarea
unghiului de început, a unghiului de terminare şi raza cercului.
Desenarea sectorului de cerc are loc de la valoarea cea mai mică a unghiului
spre valoarea cea mai mare a unghiului indiferent de ordinea de introducere a valorilor.
Există o singură situaţie când sectorul de cerc se desenează în sens trigonometric de la
unghiul pozitiv la unghiul negativ dacă una sau ambele valori sunt negative.
Prototipul funcţiei pieslice este :

Void far pieslice (int x, int y, int unghi start, int unghi terminare, int raza);

int x= coordonata x a centrului cercului din care face parte sectorul de cerc,
int y= coordonata y a centrului cercului din care face parte sectorul de cerc,
int unghi start=valoarea unghiului de start,
int unghi terminare=valoarea unghiului de terminare,
int raza=mărimea razei cercului din care face parte sectorul de cerc.

Exemplu

cleardevice();
setcolor (RED);
LIMBAJUL C TEORIE ŞI APLICAŢI I 166

pieslice (200,200,45,20,25); desenarea sectorului de cerc de la unghiul cu


valoare minimă la unghiul cu valoare maximă (de
la 20 la 45 grade,)
pieslice (300,200,20,45,25);sectorul de cerc desenat este de aceeaş mărime
unghiulara ca şi în cazul precedent
setcolor (GREEN);
pieslice (100,300,0,90,25);desenarea sectorului de cerc de la 0 la 90 grade cu
aceeaş deschidere unghiulară ca în cazul ce
urmează,
pieslice (200,300,90,0,25);
pieslice (300,300,45,-90,25);desenarea sectorului de cerc de la unghiul de 45
grade în sens trigonometric la unghiul de
terminare –90 grade,
pieslice (350,300,-90,45,25);desenarea unui sector de cerc cu aceeaş
deschidere unghiulară ca şi în cazul precedent,
una din valori este negativă,
pieslice (400,300,-45,-90,25);desenarea sectorului de cerc de la –45 la –90 de
grade, ambele valori unghiulare sunt negative,
pieslice (350,400,0,-90,25);desenarea sectorului de cerc de la 0 la –90 grade
în sens trigonometric, valoarea 0 este considerată
pozitivă,
getch ();
}

4.8.19. putpixel
Funcţia putpixel desenează pe ecranul grafic la coordonatele x,y un pixel de
culoarea specificată prin parametrii funcţiei.
Prototipul funcţiei putpixel este :

Void far putpixel (int x, int y, int culoare) ;

int x=coordonata x a punctului de pozoţionare a pixelului,


int y=coordonata y a punctului de pozoţionare a pixelului,
int culoare=culoarea de afişare a pixelului.

Exemplu

cleardevice();
setbkcolor (BLACK); setarea culori de fond pe negru
for (i=1;i<=10;i++)
{
putpixel (200+i,210,RED); trasarea unei linii orizontaledin 10 pixeli de
culoare roşu,
putpixel (200,200+i,GREEN);trasarea unei linii verticale de 10 pixeli de culoare
verde,
LIMBAJUL C TEORIE ŞI APLICAŢI I 167

}
getch ();
}

4.8.20. sector
Funcţia sector desenează un sector de elipsă între unghiurile specificate.
Sectorul de elipsă este desenat de la unghiul cu valoare minimă la unghiul cu valoare
maximă dacă ambele valori ale unghiurilor au acelaş semn. Dacă una din valurile
unghiulare este negativă, desenarea sectorului de elipsă se efectuează în sens
trigonometric de la unghiul de start la unghiul de terminare.
Umplerea sectorului de elipsă se face cu modelul şi tipul de linie setat, iar conturul
sectorului se realizează cu culoarea setată de funcţia setcolor.
Prototipul funcţiei sector este :

Void far sector (int x, int y, int unghiul de start, int unghiul de terminare, int
razax, int razay);

int x = coordonata x a centrului elipsei,


int y = coordonata y a centrului elipsei,
int unghiul de start=valoarea unghiului de start,
int unghiul de terminare=valoarea unghiului de terminare început,
int razax =mărimea razei elipsei pe direcţia x,
int razay =mărimea razei elipsei pe direcţia y.

Exemplu

cleardevice();
setbkcolor (BLACK);
setcolor (RED);
sector (100, 200, 0, 90,20,40);desenarea unui sector de elipsă între
unghiurile 0, 90, sectorul face parte din elipsa cu
centrul în punctul de coordonate x=100, y=200 şi
cele două semiaxe de 20 pe x, 40 pe y,
sector (100,300,90,0,20,40);desenarea unui sector de elipsă cu aceeaş
deschidere unghiulară ca în cazul anteriuor, dacă
unghiurile sunt de acelaş semn, trasarea se face de
la unghiul mic la unghiul mare,
sector (200,300,0,-90,20,40);trasarea sectorului de elipsă se face de la unghiul
pozitiv la unghiul negativ în sens trigonometric
(de la dreapta la stânga,)
sector (300,300,-90,0,20,40);
sector (300,400,-80,-20,20,40);dacă ambele unghiuri sunt negative, desenarea
sectorului de elipsă se face de la unghiul mai
negativ la unghiul mai puţin negativ în sens
trigonometric,
LIMBAJUL C TEORIE ŞI APLICAŢI I 168

sector (400,400,-20,-80,20,40);
getch ();
}

4.9. Funcţii pentru setarea variabilelor in mod grafic

4.9.1. Setallpalette
Funcţia setallpalette permite modificarea tuturor culorilor din paleta curentă cu culorile
conţinute în noua paletă de culori specificată ca parametru.
Prototipul funcţiei setallpalette este :

Void far setallpalette (struct palettetype far*paleta);

struct palettetype far*paleta=noua paletă .

4.9.2. setbkcolor
Funcţia setbkcolor permite schimbarea culori fondului .
Prototipul funcţiei setbkcolor este :

Void far setbkcolor (int culoare) ;

int culoare= valoarea numerică sau numele constantei de culoare scrisă cu


majuscule BLACK.

4.9.3. Setcolor
Funcţia setcolor determiă culoarea curentă de desenare pentru text,linii, arce.
Prototipul funcţiei setcolor este :

Void far setcolor (int culoare) ;

int culoare= valoarea numerică sau numele constantei de culoare


scrisă cu majuscule BLUE.

4.9.4. setpalette
Funcţia setpalette modifică în paleta curentă o singură culoare cu o altă
culoare.
Îndicarea culorilor se face prin valoarea numerică sau prin numele constantei de
culoare scrisă cu majuscule.
Prototipul funcţiei setpalette este :

Void far setpalette (int numărul culori din paletă, int noua culoare) ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 169

int numărul culori din paletă= valoare întreagă 0 la 15,


int noua culoare = valoarea numerică sau numele constantei de culoare scrisă
cu majuscule GREEN.

Exemplu

cleardevice();
setbkcolor (2); setarea culori pentru fundal la valoarea 2
(GREEN),
setpalette (1,62); schimbarea culori 1(BLUE) în paleta de culori cu
culoarea 62 (YELLOW),
setcolor (1); setarea culori de desenare pe culoarea 1
sector (100, 200, 0, 90,20, 40); se desenează un sector de elipsă pe fond
verde, culoarea de desenare galbenă, culoarea de
umplere albă (culoare nemodificată de funcţiile
apelate,)
getch ();
}

4.9.5. setfillstyle
Funcţia setfillstyle determină culoarea şi modul de umplere curent, parametrii
funcţiei vor indica modelul de umplere şi culoarea.
Modelul creat de utilozator nu poate fi folosit prin intermediul acestei funcţii, acest
model se va încărca prin funcţia setfillpatern.
Prototipul funcţie setfillstyle este :

Void far setfillstyle (int patern, int culoare) ;

int patern= valoarea numerică sau denumirea constantei ce indică modelul de


umplere conform tabelului ,
int culoare= valoarea numerică sau numele constantei de culoare scrisă cu
majuscule GREEN.

4.9.6. setfillpattern
Funcţia setfillpattern permite setarea unui model de umplere creeat de
utilizator şi setarea culorii de umplere.
Prototipul funcţiei este :

Void far setfillpattern (char far*patern1, int culoare) ;


LIMBAJUL C TEORIE ŞI APLICAŢI I 170

char far*patern1= modelul de umplere creeat de utilizator prin intermediul


unui tablou de 8 caractere ce conţine 8 valori care indică dacă pixelul corespunzător va
avea valoarea curentă sau va avea valoarea neschimbată,
int culoare= culoarea de umplere.

Exemplu

char text1 [30], patern1 [8]=


{0x00,0x10,0x18,0x11,0x11,0x28,0x00,0x10}; creearea unuimodel de umplere
de către utilizator prin scrierea valorilor în tabloul
patern1 care va fi ales ca parametru la apelarea
funcţiei setfillpattern,
int xmax,ymax,i;

cleardevice();
setcolor (1);
setfillpattern (patern1,15); setarea modelului de umplere pentru un
model creat de utilizator prin indicarea valorilor
din tabloul patern1, culoarea de umplere este 15,
sector (100, 200, 0, 270,60, 140);desenarea sectorului de elipsă cu modelul
de umplere creat de utilizator, setat anterior ca
model curent,
getch ();
}

Exemplu

….
cleardevice();
setcolor (1);
setfillstyle (7,15); alegerea modelului de umplere corespunzător
valorii 7 şi alegerea culorii de umplere
corespunzătoare valorii 15 =alb,
sector (100, 200, 0, 270,60, 140);desenarea unui sector de elipsă cu modelul
de umplere setat anterior şi culoarea de umplere
alb,
getch ();
}

4.9.7. setlinestyle
Funcţia setlinestyle permite alegerea stilului, modelului şi al grosimii liniei de
desenare.
Prototipul funcţiei setlinestyle este :

Void far setlinestyle (int stilul liniei, unsigned model, int grosime) ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 171

int stilul liniei= o valoare numerică sau o constantă ce defineşte stilul liniei
0==SOLID_LINE sau 1==DOTTED_LINE..,
unsigned model =un model de 16 biţi care indică cum va arăta linia ,
valoarea 0xFFFF indică o linie continuă
valoarea 1101101101101101 indică o linie punctată cu 2 pixeli aprinşi, un
pixel stins ,
int grosime= o valoare =1 pentru grosimea de un pixel, valoare =3 pentru
grosimea liniei de 3 pixeli.

Exemplu

cleardevice();
setcolor (1);
setlinestyle (0,0xAAAA,3);setarea stilului de linie pe tipul continuă =0 cu
grosimea de 3 pixeli, modelul utilizatorului nu
influenăează aspectul liniei,
line (100,80,400,80); desenarea unei lini continue
setlinestyle (4,1111100001111101,3); stilul liniei este definit de utilizator prin
valoarea 4, iar modelul de linie definit de
utilizator este de 5 pixeli aprinşi, 4 pixeli stinşi, 5
pixeli aprinşi, 1 pixel stins, 1 pixel aprins,
line (100,100,400,100); linia ce se desenează va respecta modelul de linie
creeat de utilizator şi setat prin funcţia
setlinestyle,
setlinestyle (4,0xAAAA,3); setarea unui nou stil de linie cu un nou model
creeat de utilizator prin 0xAAAA,
line (100,120,400,120);
getch ();
}

4.9.8. settextjustify
Funcţia settextjustify setează modul de aliniere orizontal şi vertical al textului
în raport cu poziţia curentă a cursorului grafic. Parametrii funcţiei settextjustify trebuie
să fie în concordanţă cu valorile numerice sau a constantelor grafice din tabelul ….
Prototipul funcţiei settextjustify este :

Void far settextjustify (int orizontal, int vertical) ;

int orizontal = valoare numerică 0, 1, 2 sau constantele LEFT_TEXT,


CENTER_TEXT sau RIGHT_TEXT ce indică alinierea textului pe orizontală,
int vertical =valoare numerică 0, 1, 2, sau constantele BOTTOM_TEXT,
CENTER_TEXT, TOP_TEXT.
Alinierea implicită orizontală este la stânga iar alinierea verticală este
TOP_TEXT.
LIMBAJUL C TEORIE ŞI APLICAŢI I 172

Exemplu
În acest exemplu s-au folosit drepte ca reper pentru compararea alinierii textului
în raport cu aceste drepte. Prin funcţia moveto s-a poziţionat cursorul grafic la
inceputul dreptei din zona unde se va afişa textul.
cleardevice();
settextjustify (0,0); alinierea orizontală la stânga iar vertical jos,
setcolor (4);
moveto (200,40); poziţionarea cursorului grafic la capătul
segmentului de dreaptă,
outtext ("aliniat stinga jos"); afişarea textului cu setările de aliniere date
de funcţia settextjustify şi poziţionarea acestuia la
cursorul grafic,
line (200,40,200,60); afişarea liniei folosită ca reper,
settextjustify (1,0); modificarea alinierii orizontale la varianta centrat
la poziţia cursorului grafic,
moveto (250,80);
outtext ("aliniat centrat jos");
line (250,80,250,100);
settextjustify (2,0); modificarea alinierii orizontale la varianta dreapta
la poziţia cursorului grafic,
moveto (270,100);
outtext ("aliniat dreapta jos");
line (270,100,270,120);
settextjustify (0,1); modificarea alinierii verticale la varianta centrat la
poziţia cursorului grafic,
moveto (290,120);
outtext ("aliniat stinga centrat");
line (290,120,290,140);
getch ();
}

4.9.9. settextstyle
Funcţia settextstyle setează caracteristicile fontului cu care se va afişa textul.
Caracteristicile ce se modifică sunt :
Fontul.
Direcţia de scriere a fontului.
Dimensiunea fontului.
Parametrii funcţiei settextstyle pot lua valori numerice sau constante grafice conform
tabelelor…
Pentru direcţie valoarea implicită este 0= HORIZ_DIR, iar pentru mărimea fontului se
folosesc valori înte 1 şi 10.
Prototipul funcţiei settextstyle este :

Void far settextstyle (int font, int direcţie, int mărimea caracterului) ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 173

int font =valoare numerică 0 la4 sau constante grafice DEFAULT_FONT,


TRIPLEX_FONT, SMALL_FONT, SAN_SERIF_FONT, GOTHIC_FONT care indică
noul font pentru afişarea textului,
int direcţie= valoare numerică 0, 1 sau constanta grafică HORIZ_DIR,
VERT_DIR care indică sensul de scriere a textului, vertical =scriere pe direcţia
verticală la 90 grade de jos în sus,
int mărimea caracterului= valoare numerică 0 la 10.

Exemplu

cleardevice();
settextjustify (0,0);
setcolor (4);
moveto (200,40);
settextstyle (TRIPLEX_FONT,0,0);alegerea fontului triplex cu direcţia de
scriere orizontală,
outtext ("font triplex orizontal");
settextstyle (GOTHIC_FONT,0,0); alegerea fontului gotic cu direcţia de scriere
orizontală,
moveto (250,80);
outtext ("GOTIC FONT ORIZONTAL ");
settextstyle (DEFAULT_FONT,0,2); alegerea fontului hartă de biţi cu direcţia de
scriere orizontală şi mărimea 2,
moveto (270,100);
outtext ("FONT HARTA DE BITI 2");
settextstyle (0,1,2); alegerea fontului hartă de biţicu direcţia de scriere
verticală şi mărimea 1,
moveto (150,320);
outtext ("text pe verticala");
getch ();
}

4.9.10. setviewport
Funcţia setviewport setează mărimea zonei curente de afişare, prin indicarea
colţului stânga sus şi a colţului dreapta jos. După setarea ferestrei de afişare (zonei)
cursorul grafic se poziţionează la coordonatele 0,0 (colţul stânga sus al ferestrei de
afişare).
Funcţiile care folosesc coordonate se vor raporta la un sistem ce are originea în colţul
stânga sus al ferestrei curente.
La intrarea în modul grafic zona curentă de afişare este tot ecranul cu coordonatele 0, 0
în colţul stânga sus.
Pentru a modifica mărimea ferestre este necesar să se apeleză din nou funcţia
setviewport cu noi parametri. Coordonatele colţurilor ferestrei sunt raportate la
sistemul general x, y, cu originea sistemului în colţul stânga sus al ecranului
monitorului. Pentru a şterge conţinutul ferestrei active se va folosi funcţia
LIMBAJUL C TEORIE ŞI APLICAŢI I 174

clearviewport () ; , iar pentru a şterge tot conţinutul ecranului grafic se va folosi funcţia
cleardevice ();.
Prototipul funcţiei setviewport este :

Void far setviewport (int stânga, int sus, int dreapta, int jos, int clip) ;

int stânga=coordonata x a colţului 1 al ferestrei,


int sus= coordonata y a colţului 1 al ferestrei,
int dreapta= coordonata x a colţului 2 al ferestrei,
int jos= coordonata y a colţului 2 al ferestrei,
int clip=valoare 0 sau diferită care indică dacă elementele ce depăşesc
fereastra se desenează sau se trunchează.

Exemplu

cleardevice(); funcţia cleardevice () şterge conţinutul ecranului


grafic,
setbkcolor (1); setarea culori de fond pe albastru,
setviewport (100,100,400,400,0); setarea ferestrei de desenare, afişare cu
coordonatele colţului stânga sus x=100, y=100, iar
colţul dreapta jos x=400, y=400, entităţiile ce se
desenează pot depăşi fereastra (nu sunt
trunchiate,)
rectangle (0,0,300,300);desenarea dreptunghiului la limitele ferestre curente
moveto (200,40); deplasarea cursorului grafic în raport cu
coordonatele relative ale ferestrei curente,
line (0,0,300,300); linia desenată are coordonatele raportate la
sistemul ferestrei curente, cât şi textul afişat cu
funcţia ce urmează,
outtext ("in fereastra");
moveto (305,80);
outtext ("inafara ferestrei");acest text apare pe ecran numai dacă parametrul
de trunchiere al ferestrei curenteare valoarea 0,
cum este cazul de faţă, dacă acest parametru este
trecut pe 1 , acest text nu este afişat,
getch (); continuarea execuţiei programului condiţionat de
apăsarea unei taste
setcolor (4);
setviewport (0,0,500,479,1);setarea unei noi ferestre de afişare, care va
controla entităţile ce se vor desena, această
fereastră are parametrul de trunchiere pe valoarea
1, nu va afişa zona de entităţi ce depăşesc conturul
ferestrei, conţinutul primei ferestre nu este şters
LIMBAJUL C TEORIE ŞI APLICAŢI I 175

datorită faptului că nu s-a apelat funcţiile


cleardevice sau clearviewport,
rectangle (5,5,500,470);acest dreptunghi se încadrează în noua fereastră şi va
apare în totalitate pe ecran,
moveto (200,40); poziţionarea cursorului grafic se raportează la
noua fereastră,
outtext ("aliniat la fereastra2");
line (10,20,80,70);
getch ();
}

4.9.11. cleardwvice
Funcţia cleardevice tot conţinutul ecranului grafic, umple tot ecranul cu
culoarea de fond curentă.
Poziţia cursorului grafic este în colţul stânga sus al ferestre curente de afişare desenare.
Prototipul funcţiei este :

Void far cleardevice ();

4.9.12. clearviewport
Funcţia clearviewport şterge conţinutul ferestrei curente de afişare desenare şi
poziţionează cursorul grafic în colţul stânga sus al ferestre curente.
Prototipul funcţiei clearviewport este :

Void far clearviewport ();

Exemplu

cleardevice();
setbkcolor (1);
setviewport (100,100,400,400,0);
rectangle (0,0,300,300);
moveto (200,40);
line (0,0,300,300);
outtext ("in fereastra");
moveto (305,80);
outtext ("inafara ferestrei");
getch ();
clearviewport (); această linie de cod este introdusă în plus faţă de
exemplul anterior cu scopul de a şterge conţinutul
ferestrei curente de afişare desenare, care are ca
efect că textul in fereastră, dreptunghiul ce
delimita fereastra curentă cât şi diagonala nu vor
mai fi afişate după executarea acestei linii de cod,
LIMBAJUL C TEORIE ŞI APLICAŢI I 176

textul inafara ferestrei nu este afectat datorită


poziţionări lui înafara ferestrei curente,
setcolor (4);
setviewport (0,0,500,479,1);
rectangle (5,5,500,470);
moveto (200,40);
outtext ("aliniat la fereastra2");
line (10,20,80,70);
getch ();
}

4.10. Funcţii de interogare a sistemului.


4.10.1. getarccoords
funcţia getarccoords returnează intr-o structură de date coordonatele x,y ale centrului
cercului din care face parte ultimul arc desenat, coordonatele x,y ale punctelor de
început şi sfârşit ale arcului. Structura de date spre care pointează funcţia getarccoords
este de tipul arccoordstype .
Prototipul funcţiei getarccoords este :

Void far arccoords (struct arccoordtype far*arccoords) ;

struct arccoordtype far*arccoords=structura de tip arccoordtype în care se reţin


coordonatele punctelor caracteristice ale ultimului arc desenat.

Exemplu .
struct arccoordstype ar; declararea structurii ar de tipul arccoordstype în
care se vor returna elementele caracteristice ale
ultimuluiarc, determinate de funcţia getarccoords,

cleardevice();
setbkcolor (2);
setviewport (0,0,500,470,0);
rectangle (0,0,300,300);
arc (100,150,0,90,50); desenarea arcului cu elementele x centru=100,
ycentru=150, unghiul de start 0, unghiul de sfârşit
90 şi raza=50,
getarccoords (&ar); interogarea ultimului arc desenat, returnarea
coordonatelor punctelor caracteristice în structura
ar,
printf ("x centru=%d y centru =%d \n",ar.x, ar.y); afişarea coordonatelor
centrului arcului desenat anterior prin apelarea
datelor x,y din structura ar,
printf ("x start=%d y start=%d \n",ar.xstart,ar.ystart); afişarea
coordonatelor x,y ale punctului de start ale arcului
, prin apelarea datelor xstart, ystart din structura
ar,
LIMBAJUL C TEORIE ŞI APLICAŢI I 177

printf ("x sfirsit= %d y sfirsit = %d ",ar.xend , ar.yend); afişarea


coordonatelor x,y ale punctului de sfârşit ale
arcului , prin apelarea datelor xend, yend din
structura ar,
setcolor (4);
line (ar.x,ar.y,ar.xend,ar.yend); desenarea liniei din centrul arcului la
punctul de sfârşit al arcului,
line (ar.x, ar.y, ar.xstart, ar.ystart);desenarea liniei din centru arcului la
punctul de start ale arcului,
getch ();
}

4.10.2. getbkcolor
Funcţia getbkcolor returnează valoarea numerică a culorii de fond la momentul
emiterii funcţii. Funcţia getbkcolor returnează o valoare de tip intreg (int) şi are
prototipul :

Int far getbkcolor (void) ;


4.10.3. getcolor
Funcţia getcolor returnează valoarea numerică de tip întreg a culorii curente
de desenare şi are prototipul :
Valoarea numerică corespunzătoare culorii este în concordanţă cu tipul
modelului grafic detectat de funcţia detectgraph.

Int far getcolor (void);

Exemplu

int xmax,ymax,i, fond, culoare; declararea variabilelor fond, culoare pentru
reţinerea valorilor returnate de funcţiile
getbkcolor şi getcolor,

cleardevice();
setbkcolor (2); setarea culori de fond pe valoarea 2,
setcolor (4); setarea culori de desenare pe valoarea 4,
setviewport (0,0,500,470,0);
fond =getbkcolor (); apelarea funcţiei getbkcolor pentru determinarea
culoriide fond şi returnarea acesteia în variabila
fond,
culoare =getcolor (); apelarea funcţiei getcolor pentru determinarea
culoriide de desenare şi returnarea acesteia în
variabila culoare,
LIMBAJUL C TEORIE ŞI APLICAŢI I 178

printf ("culoarea de fond =%d \n",fond); afişarea valorilor detectate pentru


fond şi culoare de desenare în două variante :
1 prin variabilele fond, culoare
2 prin apelarea directă a funcţiilor de interogare a
culorii
printf ("culoarea de desenare=%d \n",culoare);
printf ("culoarea de desenare =%d",getcolor ());
getch ();
}

4.10.4. getgraphmode
Funcţia getgraphmode returnează valoarea modului grafic curent. Apelarea
funcţieise face după iniţializarea modului grafic. Valoarea returnată este de tip intreg
(int,) şi are prototipul :

Int far getgraphmode (void) ;


4.10.5. getmaxmode
Funcţia getmaxmode returnează cea mai mare valoare pentru mod a driverului
curent, valoarea returnată este de tip intreg (int) şi are prototipul :

Int far getmaxmode (void) ;


4.10.6. getmaxx
Funcţia getmaxx returnează coordonata x maximă acceptată de ecranul grafic, funcţie
de driverul şi modul grafic detectate la iniţializarea modului grafic.
Valoarea returnată este de tip intreg şi este cu o unitate mai mică decât rezoluţia pe
orizontală a ecranului, datorită numerotării cu valoarea 0 a primei coloane.
Prototipul funcţiei getmaxx este :

int far getmaxx (void) ;


4.10.7. getmaxy
Funcţia getmaxy returnează coordonata y maximă acceptată de ecranul grafic, funcţie
de driverul şi modul grafic detectate la iniţializarea modului grafic.
Valoarea returnată este de tip intreg şi este cu o unitate mai mică decât rezoluţia pe
verticală a ecranului, datorită numerotării cu valoarea 0 a primei linii.
Prototipul funcţiei getmaxy este :

int far getmaxy (void) ;

Exemplu

# include <stdio.h>
# include <conio.h>
LIMBAJUL C TEORIE ŞI APLICAŢI I 179

# include <graphics.h>
void main ()
{
int gdriver = DETECT,gmode,errorcode;
int xmax,ymax,i, fond, culoare;
clrscr ();
initgraph(&gdriver,&gmode," ");
xmax=getmaxx();ymax=getmaxy();apelarea funcţiilor pentru detectarea rezoluţiei
ecranului pe orizontală şi verticală,
cleardevice();
setviewport (0,0,500,470,0);
puts (" ");
printf (" rezolutia pe orizontala =%d \n",xmax+1);
printf (" rezolutia pe verticala=%d \n",ymax+1);
printf (" modelul grafic =%d \n",getgraphmode ());afişarea valorii
modelului grafic curent,
printf (" modelul maxim=%d \n",getmaxmode ());afişarea valorii modelului
grafic maxim acceptat,

getch ();
}

4.10.8. imagesize
Funcţia imagesize dimensiunea spaţiului de memorie necesar pentru a se putea
salva imaginea de pe ecran precizată printr-o zonă dreptunghiulară.
Utilizatorul va specifica coordonatele x, y ale colţului stânga sus respectiv ale colţului
dreapta jos ce delimitează zona de imagine.
Valoarea maximă returnată este 64 Ko, dacă zona selectată necesită o valoare mai mare
de 64Ko, funcţia va returna valoarea -1.
Prototipul funcţiei imagesize este :

Int far imagesize (int left, int top, int right, int bottom, );

int left= coordonata x a colţului din stânga,


int top= coordonata y a colţului din stânga,
int right= coordonata x a colţului din dreapta,
int bottom= coordonata y a colţului din dreapta,
Funcţia returnează o valoare de tip intreg fără semn ce reprezintă mărimea in octeţi a
zonei de imagine indicată prin parametrii funcţiei.
4.10.9. getimage
funcţia getimage salvează în spaţiul de memorie alocat o porţiune
dreptunghiulară din imaginea existentă pe ecran la momentul apelării funcţiei.
Porţiunea de imagine salvată poate fi restaurată în fereastra dorită şi la momentul dorit.
Datorită spaţiului de memorie alocat pentru salvarea de imagini se recomandă
caporţiunea de imagine selectată să nu depăşească o zona de 300x300pixeli ce
LIMBAJUL C TEORIE ŞI APLICAŢI I 180

corespunde unui spaţiu de 64Ko de memorie. Pentru determinarea spaţiului de


memorie necesar salvării imagini se va apela anterior alocării de memorie funcţia
imagesize .
Prototipul funcţiei getimage este :

Void far getimage (int left, int top, int right, int bottom, void far *imagine);

int left= coordonata x a colţului din stânga,


int top= coordonata y a colţului din stânga,
int right= coordonata x a colţului din dreapta,
int bottom= coordonata y a colţului din dreapta,
void far *imagine= pointerul spre zona de memorie alocată salvării.

Exemplu


void *ii; declararea pointerului ii,
unsigned int imag; declararea de variabilă pentru valoarea returnată
de funcţia imagesize,

cleardevice();
setbkcolor (1);
rectangle (10,10,300,300); desenarea de entităţi care să formeze o imagine ce
se va salva în memorie,
moveto (200,40);
arc (100,100,0,90,50);
pieslice (100,100,0,180,45);
pieslice (200,200,180,0,45);
pieslice (300,300,0,180,45);
circle (100,100,70);
circle (200,200,70);
line (10,10,300,300);
outtext ("in fereastra");
imag=imagesize (0,0,350,350); determinarea mărimii imagini delimitată de
dtreptunghiul imaginar ale cărui colţuri sunt
parametrii funcţiei imagesize,
printf ("imagine=%u",imag); afişarea mărimii imaginii, pentru ase controla
dacă nu s-a depăşt 64 Ko,
ii=malloc (imag); alocarea de spaţiu pentru memorarea imaginii,
getimage (0,0,350,350,ii); salvarea imaginii delimitată de dreptunghiul ce
are coordonatele colţului stânga x=0, y=0 şi
colţului dreapta jos x=350, y=350, imaginea este
salvată în zona de memorie alocată prin funcţia
malloc,
getch ();
clearviewport ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 181

putimage (100,100,ii,COPY_PUT);dispunerea pe ecran a imaginii salvate


anterior,
getch ();
}

4.10.10. getx
Funcţia getx determină şi returnează valoarea coordonatei x a poziţiei curente
pentru cursorul grafic. Valoarea coordonatei x este raportată la poziţia relativă a
ferestrei grafice curente.
Prototipul funcţiei getx este :

Int far getx ( void) ;

Valoarea returnată este de tip întreg (int).

4.10.11. gety
Funcţia gety determină şi returnează valoarea coordonatei y a poziţiei curente
pentru cursorul grafic. Valoarea coordonatei y este raportată la poziţia relativă a
ferestrei grafice curente.
Prototipul funcţiei gety este :

Int far gety ( void) ;

Valoarea returnată este de tip întreg (int).


4.10.12. getpixel
Funcţia getpixel determină şi returnează culoarea pixelului de coordonate x,y
precizaţi prin parametrii funcţiei. Valoarea returnată este de tip întreg (unsigned) şi este
in concordanţă cu valorile pentru culoare funcţie de driverul şi modul grafic curent.
Prototipul funcţiei getpixel este :

unsigned far getpixel (int x, int y) ;

int x= coordonata x a pixelului ,


int y= coordonata y a pixelului.

Exemplu


int xmax,ymax,i,x,y;
unsigned int culoare;

cleardevice();
setbkcolor (1);
LIMBAJUL C TEORIE ŞI APLICAŢI I 182

rectangle (10,10,300,300);
moveto (200,40);
arc (100,100,0,90,50);
x=getx (); detectarea coordonatei x a poziţiei cursorului
grafic,
y= gety (); detectarea coordonatei y a poziţiei cursorului
grafic,

culoare =getpixel (10,10);detectarea culorii pixelului de coordonate x=10,


y=10,
printf ("coordonatele cursorului grafic x=%d y=%d \n",x,y);
printf ("culoarea pixelului de coordonate 10,10 =%d ",culoare);
getch ();
}

4.11. Funcţii de iniţializare şi închidere a sistemului grafic.

4.11.1. initgraph
Funcţia initgraph încarcă sau validează un driver grafic şi trece sistemul în
modul grafic. Această funcţie este prima apelată pentru a detecta prin intermediul
funcţiei detectgraph driverul şi modul grafic aceptat de hardul calculatorului.
La polul opus acestei funcţii se află funcţia closegraph care închide modul grafic şi
trece sistemul în modul text.
Prototipul funcţiei initgraph este :

Void far initgraph (int far driver, int far mode, char far*cale pentru driver);

int far driver=valoarea driverului grafic ,


int far mode=valoarea modului grafic,
char far*cale pentru driver calea spre directorul ce conţine driverul grafic.

4.11.2. closegraph
Funcţia closegraph închide sistemul grafic deschis de funcţia initgraph şi trece
modelul video la modelul text. Prototipul funcţiei closegraph este :

Void far closegraph ( void);

Exemplu

# include <stdio.h>
# include <conio.h>
# include <graphics.h>
# include <stdlib.h>
void main ()
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 183

int gdriver = DETECT,gmode,errorcode;autodetecţia adaptorului şi modului


grafic la rezoluţia maximă suportat de sitemul de
calcul prin apelarea prin DETECT,
int xmax,ymax;
initgraph(&gdriver,&gmode," ");iniţializarea modului grafic,
xmax=getmaxx();ymax=getmaxy(); detectarea dimensiunii maxime a ecranului în
mod grafic,

setviewport(0,0,getmaxx(),getmaxy(),0);setarea ferestrei cu dimensiunile


maxime detectate de funcţiile getmaxx, getmaxy,
cleardevice();
setcolor (RED);
setfillstyle (SOLID_FILL,RED);
arc (50,50,0,180,25);
closegraph (); închiderea sistemului grafic,
puts ("apasa o tasta");
getch ();
}

5. Programe aplicative

5.1. Programe şi algoritmi pentru sortare şi căutare.


Programul cautare1.c permite căutarea unui număr natural introdus de la tastatură
sau prin apelarea funcţiilor de citire dintr-un fişier sau valoare de tip întreg livrată
de o placă de achiziţii de date. Pentru a determina numărul livrat se vor parcurge
etapele astfel :
1. Se apelează un ciclu for de
la 0 la 10000 cu pasul 100 pentru a se determina intervalul de câte 100 unităţi.
2. Se apelează un nou ciclu for cu limita inferioară mai
mică decât numărul n şi limita superioară mai mare decât n iar pasul este de 10.
Limita superioară şi inferioară a ciclului este livrată de primul ciclu for iar
lungimea intervalului este 100. În cadrul acestei etape domeniul în care se află
numărul n are lungimea de 10.
3. Se apelează ultimul ciclu ce are limitele intervalului
în stânga şi dreapta numărului n deduse de la etapa 2 şi pasul de ciclare egal 1.
Folosirea acestui algoritm reduce timpul de căutare nefiind necesară parcurgerea
tuturor numerelor de la 0 la numărul căutat n.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main ()
{
int j,k,x,i,n,p;
puts ("Algoritm de cautare a unui numar natural");
puts ("Dati numarul n ");
scanf ("%d",&n);
for (i=0; i<=10000; i=i+100)
LIMBAJUL C TEORIE ŞI APLICAŢI I 184

if (n<i)
{
break;
puts ("pas1");
goto t1;
}
else
if (n==i)
{
p=i;
goto tip;
}
else
goto sfirsit;
t1 :
for (k=i-100; k<i; k=k+10)
if (n<k)
{
break;
puts ("pasul2");
goto t2;
}
else
if(n==k)
{
p=k;
break;
goto tip;
}
else
goto sfirsit;
t2 :
for (j=k-10; j<k; j=j+1)
if (n==j)
{
p=j;
goto tip;
}
else
;
tip :
printf ("n=%d ",p);
sfirsit :
puts ("APASA O TASTA");
getch ();
}
Programul zecimaln.c permite determinarea numărului de zecimale ale unui
număr mai mare decât 0. Algoritmul foloseşte funcţia floor care rotunjeşte prin
lipsă valoarea parametrului apelat.
Numărul n citit de la tastatură se îmulţeşte cu 10, 100, 1000, … şi noua valoare
obţinută se rotunjeşte prin lipsă apoi se compară cu valoarea nerotunjită, când se
obţine egalitatea între noul numar şi valoarea rotunjită a acestuia se opreşte
LIMBAJUL C TEORIE ŞI APLICAŢI I 185

procesul de amplificare cu 10 la puterea j, valoarea lui j indicând numărul de


zecimale.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main ()
{
int j;
float k,x,i,n,p;
puts ("Se determina numarul de zecimale ale unui numar");
puts ("Dati numarul n mai mic decit 1 si pozitiv ");
scanf ("%f",&n);
k=1;
j=0;
inceput : eticheta de salt a lui goto
x=n*k; amplificarea numărului cu 10 la puterea k şi
atribuirea acestei valori variabilei x
p=floor (x); apelarea funcţiei de rotunjire prin lipsă asupra noului număr x
if (x==p)
{
printf ("Numarul introdus are %d zecimale \n",j);
goto sfirsit;
}
else
{
k=k*10;
j=j+1;
goto inceput;
}
sfirsit :
puts ("APASA O TASTA");
getch ();
}
Programul sortare2.c pentru ordonarea termenilor unui vector prin metoda shell.
Sortarea termenilor unui vector prin metoda shell constă în compararea termenilor
a[i] şi a[j] pentru i=j-1, j-2, …, 1 iar j =2, 3, …, n şi dacă a[i] este mai mare decât
a[j] se efectuează operaţia de interschimbare între a[i] şi a[j].
sortare1 (float a [100],int j); prototipul funcţiei sortare1

#include <stdio.h>
#include <conio.h>
#include <math.h>
void main ()
{
int n,i,j;
float a[100],x;
puts ("Se ordoneaza un vector metoda shell ");
puts ("Dati n marimea vectorului ");
scanf ("%d",&n);
LIMBAJUL C TEORIE ŞI APLICAŢI I 186

for (i=1; i<=n; i++) ciclul for pentru citirea termenilor


vectorului
{
printf ("Dati vec [%d]= ",i);
scanf ("%f",&a[i]);
}
for (j=2; j<=n; j++)
sortare1(a,j); apelarea funcţiei sortare1 de n-1 ori care
compară pe a[i] cu a[j]
for (i=1; i<=n; i++) ciclul de afişare a vectorului cu termenii
ordonaţi
printf ("a[%d]=%.2f \t",i, a[i]);
puts (" \n APASA O TASTA");
getch ();
}

sortare1 (float a [100], int j) antetul funţiei


{
int i;
float x;
inceput :
i=j-1;
if (a[i]>a[j]) dacă a[i] >a[j] are loc interschimbarea celor
doi termeni
{
x=a[i];
a[i]=a[j];
a[j]=x;
}
else
;
;
if (i==1)
goto iesire;
else
{
j=j-1;
goto inceput;
}
iesire :
;
}
Programul pentru sortarea termenilor unui vector prin metoda bulelor (bubble
sort).Metoda bulelor constă în operaţia de interschimbare intre a[i] şi a[j] dacă şi
numai dacă a[i] > a[j]. În caz contrar elementele rămân neschimbate. Metoda
bulelor consumă n-1 etape astfel : în prima etapă se efectuează comparaţia
a[i] > a[j] ale perechilor de termeni a[1] > a[2], a[2] > a[3], …, a[n-1] > a[n], ce
are ca efect că termenul a[1] se deplasează la dreapta peste toate elementele mai
mici decât el, apoi se reia procesul cu elementul a[2] şi aşa mai departe, până când
se ajunge la elementul a[n-1]. După efectuarea acestei etape termenul cel mai
LIMBAJUL C TEORIE ŞI APLICAŢI I 187

mare al vectorului va ocupa locul cel mai din dreapta n. Se reia procesul de
deplasare spre dreapta a termenilor 1 la n-1, rezultând termenul ce va ocupa locul
n-1, se continuă până când se ordonează toţi termenii vectorului.
Programul care sortează un vector cu metoda bulelor este prezentat în funcţia
sortare5.
sortare5 (float a[100], int m); prototipul funcţiei sortare5
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main ()
{
int n,i,m,k;
float a[100],x;
puts ("Se ordoneaza un vector prin metoda bulelor ");
puts ("Dati n marimea vectorului ");
scanf ("%d",&n);
for (i=1; i<=n; i++)
{
printf ("Dati termenul [%d] al vectorului= ",i);
scanf ("%f",&a[i]);
}
for (m=n-1; m>=1; m=m-1)
sortare5 (a,m);
a [k+1]=x;
for (i=1;i<=n;i++)
printf ("a[%d]=%.2f \t",i, a[i]);
puts (" \n APASA O TASTA");
getch ();
}
Funcţia sortare5 pentru ordonarea termenilor unui vector prin metoda bulelor.
sortare5 (float a[100], int m)
{
int i;
float x;
i=1;
inceput :
if (a[i]>a[i+1])
{
x=a[i];
a[i]=a[i+1];
a[i+1]=x;
}
else
;
if (i==m)
goto iesire;
else
i=i+1;
goto inceput;
iesire :
;
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 188

Programul sortare6.c pentru ordonarea termenilor unui vector prin metoda selecţiei
directe. Sortarea prin selecţie directă constă în faptul că la pasul k, (k aparţine
intervalului 1, …, n-1) se calculează a[i] =max (a[1], a[2], a[3], …, a[n-k+1]) şi apoi se
face interschimbarea a[i] cu a[n-k+1].
sortare6 (float a[100], int m, int k);
sort61 (int k, int m, float a[100]);

#include <stdio.h>
#include <conio.h>
#include <math.h>
void main ()
{
int n,i,m,k;
float a[100],x;
puts ("Se ordoneaza un vector prin metoda selectie directa");
puts ("Dati n marimea vectorului");
scanf ("%d",&n);
for (i=1;i<=n;i++)
{
printf ("Dati vec [%d]= ",i);
scanf ("%f",&a[i]);
}
for (m=n; m>2; m=m-1)
{
sortare6 (a,m,k);
sort61 (k,m,a);
}
for (i=1;i<=n;i++)
printf ("a[%d]=%.2f \t",i, a[i]);
puts (" \n APASA O TASTA");
getch ();
}

sortare6 (float a[100], int m, int k) funcţia determină pe k astfel ca a[k] =


max(a[1], a[2], a[3], …, a[n])
{
int i;
k=2;
for (i=2; i<m;i++)
{
if (a[k]<a[i])
k=i;
else
;
}
}

sort61 (int k, int m, float a[100]) funcţia de interschimbare a lui a[m] cu


a[k]
{
float x;
LIMBAJUL C TEORIE ŞI APLICAŢI I 189

x=a[k];
a[k]=a[m];
a[m]=x;
}

5.2. Program pentru rezolvarea sistemelor de ecuaţii liniare


Pentru rezolvarea sistemelor de ecuaţii liniare, vom folosi metoda lui Gauss.
Metoda lui Gauss este în fapt metoda eliminării pentru soluţionarea sistemelor
liniare învăţată în sistemul gimnazial. Pentru a formaliza această metodă vom nota
elementele matricei iniţiale prin aij1 , i, j 1, , n , iar membrul al doilea al
sistemului prin bi 1 , i 1, , n . Primul pas constă în eliminarea necunoscutei x1
din ecuaţiile corespunzătoare lui i = 2, …, n. Presupunând că a11 este diferit de
zero, vom defini
mi1 ai11 a111 , i 2, , n .
Aceste cantităţi sunt utilizate pentru eliminarea lui x1 din ecuaţiile ce îi urmează
primeia. Noii coeficienţi vor fi
aij2 aij1 mi1a11j
, i, j 2, , n
bi 2 bi 1 mi1b11
Prima linie a matricei A şi elementul b1 rămân neschimbaţi. Sistemul după această
etapă are forma
a111 a121  a11r x1 b11
0 a222  a22r x2 b22
     
2 2
0 a n2  a nn
xn bn2
Continuăm eliminarea cu coloanele următoare. Presupunem că după r-1 paşi
sistemul are forma
a111 a121  a11r  a11n x1 b11
0 a222  a22r  a22n x2 b22
       
r r
0 0  a rr  a rn
xr br r
       
r r
0 0  a nr  a nn
xn bnr
Presupunând arrr diferit de zero, vom defini coeficienţii
mir airr arrr , i r 1, , n
cu ajutorul cărora vom elimina necunoscuta xr din ecuaţiile ce urmează lui i=r.
Vom avea
LIMBAJUL C TEORIE ŞI APLICAŢI I 190

aijr 1
aijr mir arjr
, i, j r 1, , n
bi r 1
bi r mir br r
Prin aceste transformări liniile anterioare liniei i=r+1 din matricea A sunt lăsate
neschimbate iar în coloana r sub diagonala principală se introduc zerouri. După n-
1 paşi obţinem sistemul sub forma
a111 a121  a11r x1 b11
0 a222  a22r x2 b22
     
n
0 0  a nn
xn bnn
Acest procedeu de transformare a matricei A într-o matrice superior triunghiulară
se numeşte factorizare a matricii A prin procedura lui Gauss.
Soluţia sistemului de ecuaţii cu matricea A factorizată şi vectorul b transformat
poate fi scrisă imediat :
xn bnn annn
n
xr br r arjr x j arrr , r n 1, , 1
j r 1

Această etapă poartă numele de substituţie inversă (back substitution).


Programul care implementează algoritmul lui Gauss este prezentat în continuare.
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "eliml1.c"
#include "citv.c"
#include "triu1.c"
#include "adaugal.c"
#include "tipv1.c"
#include "scriev.c"
#include "adaugac.c"
#include "inlocc.c"
#include "egalm.c"
#include "elimc1.c"
#include <conio.h>
void main ()
{
int i,j,k,q,n,m,n1;
double a[10][10],b[10][10],c[10][10],e[10][10],x[10],s;
double det,det1[10],colt [10],p,e1[10],d[10][10];
puts ("Rezolvarea sistemelor liniare calcul determinant");
puts ("Dati marimea sistemului ");
scanf ("%d",&n);
citm (n,n,a);
puts ("Dati coloana terminilor liberi");
citv (n,colt);
LIMBAJUL C TEORIE ŞI APLICAŢI I 191

egalm (n,n,a,b);
adaugac (n,n,b,colt,c);
adaugal (n,n,c);
n1=n+1;
triu1 (n1,n1,c);
eliml (n1,n1,n1,c,e);
puts (" ");
scriev (n,n1, e, e1);
tipv (n,e1);
elimc (n,n1,n1,e,d);
x[n]=e1[n]/d[n][n];
for (k=n-1;k>=1;k--) Substituţia inversă
{
s=0;
for (j=k+1;j<=n;j++)
s=s+d[k][j]*x[j];
x[k]=(e1[k]-s)/d[k][k];
}
for(i=1;i<=n;i++ )
printf ("x[%d]==%lf \n",i,x[i]);
puts ("\n Apasa o tasta ");
getch ();
}
Funcţia egalm egalează matricea B cu matricea A, astfel încât matricea care se
prelucrează să fie matricea B, iar matricea originală A să rămână nemodificată.
Funcţia este salvată în fişierul egalm.c
egalm (int n, int m, double a[10][10], double b[10][10])
{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
b[i][j]=a[i][j];
}
Funcţia adaugl permite adăugarea unei linii cu termenii egali cu 1 la o matrice cu
n linii şi m coloane. Funcţia este salvată în fişierul adaugal.c
adaugal (int n, int m, double c[10][10])
{
int i,j;
for (i=1;i<=n+1;i++)
for (j=1;j<=m+1;j++)
if (i>n)
c[i][j]=1;
else
c[i][j]=c[i][j];
}
Funcţia adaugc permite adăugarea unei coloane la o matrice, în cazul de faţă
coloana ce se adaugă este coloana termenilor liberi. Funcţia este salvată în fişierul
adaugac.c
adaugac (int n, int m, double b[10][10], double d[10],double e[10][10])
{
int i,j;
LIMBAJUL C TEORIE ŞI APLICAŢI I 192

for (i=1;i<=n;i++)
for (j=1;j<=m+1;j++)
if (j>m)
e[i][j]=d[i];
else
e[i][j]=b[i][j];
}
Funcţia triu1 efectuează triangularizarea unei matrici pătratice de mărime n n.
Funcţia este salvată în fişierul triu1.c
triu1 (int n, int m, double a[10][10])
{
int i,j,k;
double p;
for (i=1;i<n;i++)
for (j=i+1;j<=n;j++)
{
p=a[j][i]/a[i][i];
for (k=i;k<=n;k++)
a[j][k]=a[j][k]-p*a[i][k];
}
}
Funcţia eliml elimină dintr-o matrice ultima linie. Funcţia este salvată în fişierul
eliml1.c
eliml (int n, int m, int k, double a[10][10], double b[10][10])
{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (i!=k)
if(i<k)
b[i][j]=a[i][j];
else
b[i-1][j]=a[i][j];
}
Funcţia elimc elimină coloana k dintr-o matrice. Funcţia este salvată în fişierul
elimc.c
elimc (int n, int m, int k, float a[10][10], float b[10][10])
{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (j!=k)
if(j<k)
b[i][j]=a[i][j];
else
b[i][j-1]=a[i][j];
else
;
}
Funcţia scriev transferă dintr-o matrice, ultima coloană într-un vector. Funcţia este
salvată în fişierul scriev.c
scriev (int n, int m, double a[10][10], double b[10])
LIMBAJUL C TEORIE ŞI APLICAŢI I 193

{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (j==m)
b[i]=a[i][j];
else
;
}

5.3. Metoda Cramer pentru determinarea valorii determinantului


Fişierul cu programul sursă este prezentat în continuare.
#include <stdio.h>
#include "citm.c"
#include "tipm.c"
#include "trimat.c"
#include "inlocc.c"
#include "egalm.c"
#include <conio.h>
void main ()
{
int i,j,k,q,n,m;
double a[10][10],b[10][10],c[10][10],det,det1[10],colt [10][10],p;
puts ("Rezolvarea sistemelor liniare calcul determinant");
puts ("Dati marimea sistemului ");
scanf ("%d",&n);
citm (n,n,a);
puts ("Dati coloana termenilor liberi");
citm (n,1,colt);
for (q=1;q<=n;q++)
{
egalm (n,n,a,b);
inlocc (n,n,q,b,colt);
det1[q]=trimat (n,n,b);
}
egalm (n,n,a,b);
tipm (n,1,colt);
tipm (n,n,b);
det=trimat (n,n,b);
printf (" determinantul==%.25lf\n",det);
if (det!=0)
{
for (i=1;i<=n;i++)
{
printf (" det1 [%d]=%.25lf\n",i,det1[i]);
printf (" x[%d] =%lf\n",i,det1[i]/det);
}
}
else
puts ("sistem incompatibil");
puts ("\n Apasa o tasta ");
getch ();
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 194

Funcţia trimat efectuează triangularizarea unei matrici pătratice de mărimea n n


şi determină valoarea determinantului noii matrici triangularizate. Funcţia este
salvată în fişierul trimat.c
double trimat (int n,int m, double a[10][10])
{
int i,j,k;
double det,p;
for (i=1;i<n;i++)
for (j=i+1;j<=n;j++)
{
p=a[j][i]/a[i][i];
for (k=i;k<=n;k++)
a[j][k]=a[j][k]-p*a[i][k];
}
det=1;
for (i=1;i<=n;i++)
det=det*a[i][i];
return (det);
}
Funcţia inlocc efectuează înlocuirea coloanei i a matricii coeficienţilor
necunoscutelor cu coloana termenilor liberi. Funcţia este salvată în fişierul
inlocc.c
inlocc (int n, int m,int k, double b[10][10], double colt[10][10])
{
int i,j;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (j==k)
b[i][j]=colt[i][1];
else
b[i][j]=b[i][j];
}

5.4. Caracteristicile geometrice ale secţiunilor transversale


#include <conio.h>
#include <stdio.h>
#include "sfirsit.c"
#include "fz0g.c"
#include "fy0g.c"
#include "fIy.c"
#include "fIz.c"
#include "fIyz.c"
void main ()
{
float ai[10],y0i[10],z0i[10],y0g,z0g,Iy,Iz,Iyz;
int n,i;
float Iyi[10],Izi[10],Iyzi[10];
puts ("dati nr de elemente");
scanf ("%d",&n);
for (i=1;i<=n;i++)
{
printf ("dati aria[%d] y0%d z0%d ",i,i,i);
LIMBAJUL C TEORIE ŞI APLICAŢI I 195

scanf("%f %f %f",&ai[i],&y0i[i],&z0i[i]);
}
y0g=fy0g(n,y0i,ai);
z0g=fz0g(n,z0i,ai);
for (i=1;i<=n;i++)
{
printf ("dati Iyi[%d]= Izi%d= Iyz%d= ",i,i,i);
scanf ("%f %f %f",&Iyi[i],&Izi[i],&Iyzi[i]);
}
printf ("y0g=%f z0g=%f\n",y0g,z0g);
printf ("Iy=%f\n",fIy(n,z0g,ai,Iyi,z0i));
printf ("Iz=%f\n",fIz(n,y0g,ai,Izi,y0i));
printf ("Iyz=%f\n",fIyz(n,z0g,y0g,ai,Iyzi,z0i,y0i));
sfirsit ();
}

float fz0g (int n,float z0i[10],float ai[10])


{
int i;
float z0g,a;
z0g=0;a=0;
for (i=1;i<=n;i++)
a=ai[i]+a;
for(i=1;i<=n;i++)
z0g=z0g+z0i[i]*ai[i];
z0g=z0g/a;
return z0g;
}

float fy0g (int n,float y0i[10],float ai[10])


{
int i;
float y0g,a;
y0g=0;a=0;
for (i=1;i<=n;i++)
a=ai[i]+a;
for(i=1;i<=n;i++)
y0g=y0g+y0i[i]*ai[i];
y0g=y0g/a;
return y0g;
}

float fIy (int n,float z0g,float ai[10],float Iyi[10],float z0i[10])


{
int i;
float Iy=0;
for (i=1;i<=n;i++)
Iy=Iy+Iyi[i]+(z0i[i]-z0g)*(z0i[i]-z0g)*ai[i];
return Iy;
}

float fIz (int n,float y0g,float ai[10],float Izi[10],float y0i[10])


{
int i;
LIMBAJUL C TEORIE ŞI APLICAŢI I 196

float Iz=0;
for (i=1;i<=n;i++)
Iz=Iz+Izi[i]+(y0i[i]-y0g)*(y0i[i]-y0g)*ai[i];
return Iz;
}

float fIyz (int n,float z0g,float y0g, float ai[10],float Iyzi[10],float


z0i[10],float y0i[10])
{
int i;
float Iyz=0;
for (i=1;i<=n;i++)
Iyz=Iyz+Iyzi[i]+(z0i[i]-z0g)*(y0i[i]-y0g)*ai[i];
return Iyz;
}

5.5. Calculul analitic al eforturilor M, N, T


Programul care este prezentat în acest paragraf permite determinarea momentelor
de încastrare perfectă ale unei bare dublu încastrată încărcată cu forţe concentrate
sau forţe distribuite sau cu momente concentrate. Cu acest program se determină
foarte uşor valoarea momentelor de încastrare perfectă în cadrul metodei
deplasărilor folosită la studiul structurilor nedeterminate static (la disciplina
Statica construcţiilor, metoda deplasărilor ce se studiază în anul III).
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include "forta1.c"
#include "distrib1.c"
#include "momen1.c"
void IESIRE1 (void);

void main ()
{
int i,j,n,m,o;
float M1,M2,V1,V2,N1,N2,p,q,l;
puts ("SE DETERMINA FORTELE SI MOMENTELE NODALE ");
puts ("BARA DUBLU INCASTRATA ");
INCEPUT1 :
puts ("ALEGETI OPTIUNEA DORITA");
puts ("FORTA CONCENTRATA NORMALA =1");
puts ("FORTA DISTRIBUITA NORMALA =2");
puts ("MOMENT CONCENTRAT =3");
puts ("FORTA CONCENTRATA AXIALA =4");
puts ("IESIREA DIN PROGRAM =5");
fflush (stdin);
if (scanf ("%d",&o)==1)
switch (o)
{
case 1:
FORTACONCENTRATA1 ();
break;
LIMBAJUL C TEORIE ŞI APLICAŢI I 197

case 2 :
FORTADISTRIBUITA ();
break;
case 3 :
MOMENTCONCENTRAT ();
break;
case 4 :
puts ("FORTAAXIALA ();");
break;
default :
IESIRE1 ();

}
else
{
puts ("ATI INTRODUS OPTIUNEA GRESITA ");
goto INCEPUT1;
}
}

void IESIRE1 (void)


{
puts ("APASA O TASTA");
getch ();
}
Funcţia FORTACONCENTRATA1 permite determinarea valorii momentelor de capăt
când pe bară acţionează forţe concentrate.
void FORTACONCENTRATA1 (void)
{
int i,j,n,m;
float M1,M2,V1,V2,N1,N2,a[10],l,p[10],b[10];
puts ("DATI LUNGIMEA BAREI ");
scanf ("%f",&l);
puts ("DATI NUMARUL DE FORTE CONCENTRATE PE BARA");
scanf ("%d",&n);
for (i=1;i<=n;i++)
{
printf("DATI DISTANTA LA FORTA [%d]= SI MARIMEA FORTEI = ",i);
scanf ("%f,%f",&a[i],&p[i]);
b[i]=l-a[i];
}
M1=0; M2=0; V1=0; V2=0;
for (i=1;i<=n;i++)
{
M1=M1-p[i]*(a[i]*b[i]*b[i])/(l*l);
M2=M2-p[i]*(a[i]*a[i]*b[i])/(l*l);
}
printf ("Momentul 1 si 2 are valoarea =%f =%f \n ",M1,M2);
delay (1000);
puts ("APASATI O TASTA PENTRU REVENIREA IN PROGRAM ");
getch ();
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 198

Funcţia FORTADISTRIBUITA permite determinarea valorii momentelor de


capăt când pe bară acţionează forţe distribuite
void FORTADISTRIBUITA (void)
{
int i,j,n;
float M1,M2,V1,V2,N1,N2,a[10],l,q[10],c[10],b[10];
puts ("DATI LUNGIMEA BAREI ");
scanf ("%f",&l);
puts ("DATI NUMARUL DE FORTE DISTRIBUITE");
scanf ("%d",&n);
for (i=1;i<=n;i++)
{
printf ("DATI DISTANTA PINA LA MIJLOCUL FORTEI [%d] ",i);
scanf ("%f",&a[i]);
printf ("DATI LUNGIMEA DE DISTRIBUTIE A FORTEI [%d] SI MARIMEA
FORTEI=",i);
scanf ("%f %f",&c[i],&q[i]);
b[i]=l-a[i];
}
M1=0; M2=0; V1=0; V2=0;
for (i=1;i<=n;i++)
{
M1=M1+((q[i]*c[i])/(24*l))*(24*b[i]*b[i]*b[i]/l-
(6*c[i]*c[i]*(a[i]+c[i]/2))/l+3*c[i]*c[i]*c[i]/l+4*c[i]*c[i]-24*b[i]*b[i]);
M2=M2-((q[i]*c[i])/(24*l))*(24*b[i]*b[i]*b[i]/l-
6*c[i]*c[i]*(a[i]+c[i]/2)/l+3*c[i]*c[i]*c[i]/l+2*c[i]*c[i]-
48*b[i]*b[i]+24*b[i]*l);
}
printf ("MOMENTELE M1=%f M2= %f ",M1,M2);
puts ("APASATI O TASTA ");
getch ();
}
Funcţia MOMENTCONCENTRAT permite determinarea valori momentelor de
capăt când pe structură acţionează momente concentrate.
void MOMENTCONCENTRAT (void)
{
int i,j,n;
float M1,M2,V1,V2,N1,N2,a[10],l,m[10],b[10];
puts ("DATI LUNGIMEA BAREI ");
scanf ("%f",&l);
puts ("DATI NUMARUL DE MOMENTE CONCENTRATE PE BARA");
scanf ("%d",&n);
for (i=1;i<=n;i++)
{
printf ("DATI DISTANTA PINA LA MOMENTUL [%d]= SI MARIMEA MOMENTULUI =
",i);
scanf ("%f,%f",&a[i],&m[i]);
b[i]=l-a[i];
}
M1=0; M2=0; V1=0; V2=0;
for (i=1;i<=n;i++)
{
M1=M1+m[i]*(4*a[i]*l-3*a[i]*a[i]-l*l)/(l*l);
LIMBAJUL C TEORIE ŞI APLICAŢI I 199

M2=M2-m[i]*(2*l*a[i]-3*a[i]*a[i])/(l*l);
}
printf ("Momentul 1 si 2 are valoarea =%f =%f \n ",M1,M2);
delay (1000);
puts ("APASATI O TASTA PENTRU REVENIREA IN PROGRAM ");
getch ();
}

5.6. Calculul ariilor contururilor poligonale închise


Să considerăm un poligon închis, compus din segmente de dreaptă între n vârfuri
(x1, y1), i =0, …, n-1. Ultimul vârf este identic cu primul (adică poligonul este
închis).
(x2, y2)
(x1, y1)

n=6

(x0, y0) (x3, y3)

(x4, y4)

Aria poligonului va fi dată de formula


1n1
A xi yi 1 xi 1 xi .
2i 0
Pentru ca această formulă să poată fi aplicată, trebuie respectat un sens de
parcurgere al poligonului, coordonatele vârfurilor introducându-se fie în sens orar,
fie în sens anti orar. Aria obţinută va fi pozitivă, dacă poligonul a fost parcurs în
sens anti orar, sau negativă, dacă poligonul a fost parcurs în sens orar.
Deducerea formulei de mai sus este evidentă din figura de mai jos. Dacă se
respectă un sens de parcurs orar, aria conturului poligonal închis se poate obţine
ca suma trapezelor formate de laturile conturului poligonal şi verticalele coborâte
din vârfuri. Trapezele 1, 2 şi 3 vor avea ariile pozitive, pe când trapezele 4, 5 şi 6
vor avea ariile negative, însumând toate aceste arii cu semnele lor, rezultând aria
poligonului.
LIMBAJUL C TEORIE ŞI APLICAŢI I 200

2
3

1
5 4
x

Programul sursă C, care rezolvă această problemă este prezentat în continuare.


#include<stdio.h>
void main ()
{
int i, j, n;
float x[10], y[10], aria = 0;

printf("Cate varfuri:");
scanf("%d",&n);
for (i=0; i<n; i++)
{
printf("x(%d) y(%d)", i, i);
scanf("%f %f", &x[i], y[i]);
}
for (i=0; i<n; i++)
{
j = (i+1) % n;
aria += x[i] * y[j];
aria -= y[i] * x[j];
}
aria = aria / 2;
aria < 0 ? -aria: aria;
}
Vom atrage atenţia asupra instrucţiunii de atribuire j = (i+1) % n;. De la i = 0,
până la i = n-2, j va lua valorile 1 până la n-1. Când i este n-1, j va lua valoarea 0,
asigurând închiderea conturului poligonal.

5.7. Calculul integralelor prin metoda dreptunghiului


Valoarea integralei definite în intervalul [a, b], a unei funcţii continue f(x),
reprezintă aria suprafeţei mărginită de funcţia f(x), axa absciselor, şi cele două
segmente de dreaptă ce trec prin capetele intervalului.
Astfel, calculul numeric al integralei poate fi făcut împărţind suprafaţa respectivă
în suprafeţe elementare, a căror arie poate fi evaluată uşor. Se pot folosi
LIMBAJUL C TEORIE ŞI APLICAŢI I 201

dreptunghiuri sau trapeze pentru forma suprafeţelor elementare. Metoda


aproximării cu dreptunghiuri este mai uşoară, necesitând mai puţine calcule.

f(x)

f(x)

a b
x h x

Astfel, programul sursă C, va fi:


#include <stdio.h>
void main ()
{
int n, i;
double a, b, x, fx, h, integ;
printf("\nProgramul calculeaza integrala functiei x^2 in intervalul [a, b]");
printf("\nDati capatele intervalului");
scanf("%lf %lf", &a, &b);
printf("\nCate diviziuni ale intervalului");
scanf("%d", &n);
h=(b-a)/n;
integ=0;
for (i=0; i<n; i++)
{
x=a+i*h;
fx=x*x;
integ=integ+fx*h;
}
printf("\nIntegrala din x^2 in intervalul [%lf, %lf] este %lf", a, b, integ);
}
Problemă propusă
Să se scrie programul sursă C care calculează integrala definită în intervalul [a, b]
a funcţiei continue f(x), folosind regula trapezului.

5.8. Soluţionarea numerică a ecuaţiilor neliniare prin metoda bisecţiei


Problema determinării rădăcinilor unei ecuaţii de forma
f(x)=0,
LIMBAJUL C TEORIE ŞI APLICAŢI I 202

unde f(x) este o funcţie continuă, apare frecvent în aplicaţii. Metode analitice de
soluţionare a unor astfel de ecuaţii există numai pentru cazuri particulare.
In multe situaţii problema fizică ce a condus la ecuaţia f(x)=0 furnizează
informaţii asupra distribuţiei rădăcinilor. In continuare presupunem depăşită
această etapă, cu alte cuvinte, admitem că ecuaţia f(x)=0 are o rădăcină simplă x1
în intervalul [a, b]. Ceea ce ne propunem este determinarea acestei rădăcini cu
precizia ε, adică valoarea funcţiei în punctul x1 să fie mai mică decât precizia ε.
Cea mai simplă metodă de soluţionare numerică a ecuaţiei este metoda
înjumătăţirii intervalului (a bisecţiei). Iată algoritmul metodei:
1. Se defineşte c := (a+b)/2
2. Dacă f(b) ∙ f(c) ≤ 0, atunci a := c, altfel b := c
3. Dacă │f(c)│ ≤ ε, rădăcina ecuaţiei este c; STOP
4. Treci la pasul 1
Ideea metodei este simplă : intervalul [a, b] este înjumătăţit la fiecare trecere, iar
condiţia pusă la pasul 2 ne asigură că rădăcina este inclusă în intervalul [a, b].
Programul sursă al problemei este:
#include <stdio.h>
#include <math.h>

float f(float x)
{
return (x*x-3*x+2);
}

void main ()
{
int cont=0, err=0;
float a, b, c, eps=0.0001;
printf("\Program care calculeaza o radacina a ecuatiei f(x)=0 in intervalul
[a, b]");
printf("\nDati limitele intervalului");
scanf("%f %f", &a, &b);
do
{
c=(a+b)/2;
if (f(b)*f(c) <= 0)
a=c;
else
b=c;
cont++;
if (cont > 1000)
{
err=1;
break;
}
} while(fabs(f(c))>eps);
if (err)
printf("\nNu exista solutie in intervalul ales");
else
LIMBAJUL C TEORIE ŞI APLICAŢI I 203

printf("O solutie a ecuatiei este %f", c);


}
În problema noastră am ales ecuaţia x2-3x+2 care are soluţiile 1 şi 2. Condiţia de
ieşire din ciclu este ca modulul funcţiei f în punctul c să fie mai mic decât precizia
eps.
Pentru a fi siguri că programul nu intră într-un ciclu infinit, am adăugat o variabilă
contor denumită cont, care este incrementată în fiecare ciclu. Dacă contorul este
mai mare decât 1000, variabila întreagă err primeşte valoarea 1 şi se întrerupe
ciclul do while cu ajutorul instrucţiunii break. Variabila err este folosită după
terminarea ciclului. Dacă err este 0, înseamnă că ciclul a fost terminat normal
(fără eroare). Dacă err este 1, însemnă că am depăşit numărul maxim de cicluri şi
se va tipări mesajul de eroare: Nu exista solutii in intervalul ales.
Problemă propusă
Să se scrie programul sursă C care calculează o rădăcină a ecuaţiei f(x)=0, în
intervalul [a, b] folosind metoda coardei. Funcţia f(x) ale cărei rădăcini sunt
căutate este x3-6x2+11x-6.
Notă
Metoda coardei este o modificare a metodei bisecţiei. Graficul funcţiei f(x) este
aproximat prin dreapta care uneşte punctele (a, f(a)) şi (b, f(b)), iar punctul c se
găseşte la intersecţia acestei drepte cu axa Ox:
c := b-f(b)(b-a)/[f(b)-f(a)].
Algoritmul metodei coincide cu cel al bisectoarei cu deosebirea că la primul pas c
se calculează după regula de mai sus.

5.9 Calculul coordonatelor unei retrointersecţie


Să se determine coordonatele unui numar n de puncte, la care s-au măsurat
unghiul şi distanţa de la staţia de lucru la fiecare punct, folosind metoda
retrointersecţiei .
Pentru staţia de lucru se cunosc cele două coordonate x şi y.
Obs. Axa X este orientată pe verticală de jos în sus conform sistemului topografic.
Datele de intrare sunt :
Coordonatele staţiei de lucru.
Numărul de puncte măsurate din staţia de lucru.
Distanţa şi unghiul măsurat la fiecare punct.
Datele de ieşire:
Coordonatele X, Y ale fiecărui punct măsurat afişate pe monitor şi scrise intr-
un fişier, fişierul de lucru este topo_calc.c.
Pentru determinarea coordonatelor x, y se aplică relaţiile de calcul :

x [i] =xs+dist [i]*cos (M_PI*unghi [i]/200);


y [i] =ys+dist [i]* sin (M_PI*unghi [i]/200);
xs=coordonata x a staţiei de lucru.
LIMBAJUL C TEORIE ŞI APLICAŢI I 204

Ys=coordonata y a staţiei de lucru.


M_PI =valoarea constantei π.
Unghiul citit este în grade centizimale (sistem topografic) şi este convertit ăn
radiani, pentru a se utiliza funcşiile matematice din cadrul limbajului C.

#include<stdio.h>
#include<conio.h>
#include<io.h>
#include<math.h>
void main ()
{
FILE * f1;
int i,n;
float unghi [20], dist [20],x[20],y[20],xs,ys;
f1=fopen("topo_calc.c","w");
puts (" Calcul coordonate x, y, axa x este pe verticala ");
puts (" Dati numarul de puncte citite");
scanf ("%d",&n);
puts (" Dati coordonatele x si y ale statiei");
scanf ("%f,%f",&xs,&ys);
for (i=1;i<=n;i++)
{
printf (" Dati unghiul si distanta pentru punctul %d ",i);
scanf ("%f,%f",&unghi [i],&dist [i]);
x [i] =xs+dist [i]*cos (M_PI*unghi [i]/200);
y [i] =ys+dist [i]* sin (M_PI*unghi [i]/200);
fprintf (f1,"punctul %d u=%.4f d=%.2f x=%.3f
y=%.3f\n",i,unghi[i],dist[i],x[i],y[i]);
printf (" punctul %d u=%.4f d=%.2f x=%.3f
y=%.3f\n",i,unghi[i],dist[i],x[i],y[i]);
}
puts (" Valorile citite si calculate sunt scrise in fisierul
topo_calc.c");
puts (" Apasa o tasta pentru terminarea programului");
getch ();
}

5.10 Calculul distanţelor dintre puncte consecutive şi calculul


distanţei totale dintre primul şi ultimul punct.
Se va determina distanţele parţiale şi distanţa totalădintre un număr de
puncte la care se cunosc coordonatele x şi y.
Date de intrare:
Numărul punctelor.
Coordonatele x, y ale fiecărui punct.
Date de ieşire :
Distanţele dintre puncte.
Distanţa totală.
LIMBAJUL C TEORIE ŞI APLICAŢI I 205

X
P3
P2
P1
Y1
Y

X1
X2

Distanţele parţiale dintre două puncte consecutive se determină cu relaţia :


d[i]=sqrt((x[i]-x[i+1])*(x[i]-x[i+1])+(y[i]-y[i+1])*(y[i]-y[i+1]));
distanţa totală =∑ d[i].

#include<stdio.h>
#include<conio.h>
#include<io.h>
#include<math.h>
void main ()
{
FILE * f1;
int i,n;
float x[20],y[20],l,d[20];
f1=fopen("topo_ca1.c","w");
puts (" Calcul distantelor dintre puncte si lungimea totala ");
puts (" Dati numarul de puncte ");
scanf (" %d",&n);
for (i=1;i<=n;i++)
{
printf (" Dati coordonatele x,y ale punctului %d ",i);
scanf (" %f,%f",&x [i],&y [i]);
}
l=0;
for (i=1;i<n;i++)
{
d[i]=sqrt((x[i]-x[i+1])*(x[i]-x[i+1])+(y[i]-y[i+1])*(y[i]-y[i+1]));
l=l+d[i];
fprintf (f1,"Distanta %d =%.4f \n",i,d[i]);
printf (" Distanta %d =%.4f \n",i,d[i]);
}
printf (" Lungimea totala =%.4f\n",l);
fprintf (f1,"Lungimea totala=%.4f",l);
puts (" Valorile distantelor si lungimea totala sunt scrise in
fisierul topo_ca1.c");
LIMBAJUL C TEORIE ŞI APLICAŢI I 206

puts (" Apasa o tasta pentru terminarea programului");


getch ();
}

5.11. Calculul momentelor de inerţie şi poziţia centrului de


greutate folosind o bază de date pentru profile standard
În cadrul acestui exemplu s-a creat o bază de date, pentru o categorie de profile şi
s-a realizat o interfaţă grafică, pentru a se înţelege mai bine forma secţiunii
transversale.
Pentru exemplul ales numărul secţiunii este 1, iar profolele disponibile în baza de
date sunt U6, 8, 10, 12.
După indicarea profilului ales din lista de profile disponibile, programul afişează
caracteristicile principale ale profilului.
În etapa următoare se cere distanţa dintre cele două profile U exprimată în cm.
Programul determină lăţimea minimă a platbandelor şi indică această mărime, după
care utilizatorul va introduce lăţimea şi grosimea celor două platbande.
Programul livrează aria,momentele de inerţie faţă de cele două axe x, y.
Programul se poate dezvolta prin complectarea bazei de date cu noi valori, pentru
profilul U cât şi prin adăugarea de noi tipuri de secţiuni.
Programul a fost efectuat cu scopul de a îmbina noţiunile de grafică, cu noţiunile
de calcul şi realizarea unei baze de date a caracteristicilor geometrice ale profilelor.

# include <stdio.h>
# include <conio.h>
# include <graphics.h>
void void main ()
{
int gdriver = DETECT,gmode,errorcode;
int xmax,ymax,s,i,j,n,m;
float a,b,c,d,t,zog,yog;
float iyb, izb, iyzb, iy, iz, beta, wy, wz,iyy,izz;
float h1, b1, a1, iy1, iz1, ey1,iu, iv, iy1z1,ez1;
float u[80];
u[1]=6.5; u[2]=4.2; u[3]=9.03; u[4]=57.5; u[5]=14.1;
u[6]=1.42;
u[7]=8; u[8]=4.5; u[9]=11; u[10]=106; u[11]=19.4;
u[12]=1.45;
u[13]=10; u[14]=5; u[15]=13.5; u[16]=206; u[17]=29.3;
u[18]=1.55;
u[19]=12; u[20]=5.5; u[21]=17; u[22]=364; u[23]=43.2;
u[24]=1.6;

clrscr ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 207

initgraph(&gdriver,&gmode," ");
xmax=getmaxx();ymax=getmaxy();
printf ("x max=%d y max=%d",xmax,ymax);
errorcode=graphresult();
if(errorcode!=grOk) printf("Eroare grafica:
%s\n",grapherrormsg(errorcode));
cleardevice();
setviewport(0,0,xmax,ymax,0);
setfillstyle (SOLID_FILL,RED);
rectangle (50,50,120,54);
rectangle (50,129,120,133);
moveto (80,54);
linerel (0,75);
linerel (-25,0);
linerel (0,-4);
linerel (21,0);
linerel (0,-67);
linerel (-21,0);
linerel (0,-4);
linerel (25,0);

moveto (90,54);
linerel (25,0);
linerel (0,4);
linerel (-21,0);
linerel (0,67);
linerel (21,0);
linerel (0,4);
linerel (-25,0);
linerel (0,-75);

moveto (77,160);
outtext ("1");
gotoxy (10,15);
printf ("Alegeti numarul sectiunii=");
scanf ("%d",&s);
gotoxy (10,16);
printf ("Pentru sectiunea aleasa se vor introduce elementele
caracteristice");
gotoxy (20,17);
printf ("APASATI O TASTA PENTRU CONTINUARE");
getch ();
cleardevice ();
switch (s)
{
case 1:
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 208

rectangle (50,50,120,54);
rectangle (50,129,120,133);
moveto (80,54);
linerel (0,75);
linerel (-25,0);
linerel (0,-4);
linerel (21,0);
linerel (0,-67);
linerel (-21,0);
linerel (0,-4);
linerel (25,0);

moveto (90,54);
linerel (25,0);
linerel (0,4);
linerel (-21,0);
linerel (0,67);
linerel (21,0);
linerel (0,4);
linerel (-25,0);
linerel (0,-75);
gotoxy (10,10);
printf ("Dati marimea profilului U 6,8,10,12=");
scanf ("%d",&n);
printf (" ---- U%d are caracteristicile---\n",n);
switch (n)
{
case 6:
i=1;
break ;
case 8:
i=7;
case 10:
i=13;
break ;
case 12:
i=19;
}
printf ("h=%.2f b=%.2f a=%.2f iy=%.2f iz=%.2f e=%.2f
",u[i],u[i+1],u[i+2],u[i+3],u[i+4],u[i+5]);
printf ("\n Dati distanta dintre profile in cm d=");
scanf ("%f",&d);
printf ("Dati latimea mai mare sau = %.0f si grosimea
platbandei in cm=",2*u[i+1]+d);
scanf ("%f,%f",&b,&t);
iyb=u[i+3]*2+t*t*t*b/6+b*t*2*(u[i]/2+t/2)*(u[i]/2+t/2);
izb=u[i+4]*2+b*b*b*t/6+2*u[i+2]*(d/2+u[i+5])*(d/2+u[i+5]);
LIMBAJUL C TEORIE ŞI APLICAŢI I 209

a=2*u[i+2]+b*t*2;
printf ("\n aria =%.2f Iy=%.2f Iz=%.2f\n",a,iyb,izb);
}
}
puts ("apasa o tasta");
getch ();
}

5.12 Program pentru rezolvarea ecuaţiei de gradul II


Pentru ca elevul să poată lucra singur şi să fie testat fără a implica factorul uman, s-
a realizat un program ce permite alegerea unui set de 9 ecuaţii de gradul II ,
afişarea acestei ecuaţii într-un mod indentic cu scrierea pe tablă, apoi afişarea
casetei de dialog, în care elevul va indica cele două soluţii.
În următoarea etapă se evaluează de calculator soluţiile date cu soluţiile corecte şi
atribuie sau nu 1 punct .
Se continuă evaluarea următoarelor 8 ecuaţii, în final calculatorul afişează
punctajul obţinut şi nota.
Programul combină modul grafic cu modul text şi prin dezvoltarea bazei de date
aferente celor 3 coeficienţi a, b, c ale ecuaţiei de gradul II, se poate realiza
evaluarea a unui număr cât mai mare de elevi.
La modificarea bazei de date se va ţine cont ca soluţiile sistemului să fie valori
reale.Programul sursă a fost realizat pentru numărul calculatorului =6.

# include <stdio.h>
# include <conio.h>
# include <dos.h>
# include <graphics.h>
# include <math.h>
# include <stdlib.h>
void gresit (void);
void corect (void);
int ecu2 (float,float,float,float,float);
caseta1 (int ,int,int ,int, int,int );
int caseta2 (int um ,int cul , int stinga, int sus , int cul1, int
cul2);
void main ()
{
int gdriver = DETECT,gmode,errorcode;
unsigned long s;
int xmax,ymax,i,ii,j,l,n,x,y,a,b,c,t,r,d,f,g,w1,w2;
int e,e1;
int um,cul,stinga,jos,dreapta,sus,cul1,cul2;
float w,z[170],xx1,xx2;
fflush (stdin);
w1=0; w2=0;
LIMBAJUL C TEORIE ŞI APLICAŢI I 210

z[136]=1; z[137]=3; z[138]=-4;


z[139]=-6; z[140]=0 ; z[141]=6;
z[142]=1; z[143]=6 ; z[144]=-7;
z[145]=1; z[146]=0; z[147]=-64;
z[148]=7; z[149]=0 ; z[150]=0;
z[151]=1; z[152]=-5 ; z[153]=0;
z[154]=1; z[155]=-12; z[156]=36;
z[157]=4; z[158]=-7 ; z[159]=3;
z[160]=5; z[161]=15 ; z[162]=10;
clrscr ();
xmax=getmaxx();ymax=getmaxy();
initgraph(&gdriver,&gmode," ");
setviewport(0,0,getmaxx(),getmaxy(),0);
errorcode=graphresult();
if(errorcode!=grOk) printf("Eroare grafica:
%s\n",grapherrormsg(errorcode));
cleardevice();
MENIU:
clrscr ();
setfillstyle (SOLID_FILL,RED);
bar (100,100,300,240);
setcolor (WHITE);
moveto (120,160);
lineto (120,120);
lineto (279,120);
setcolor (BLACK);
outtextxy (125,130," ALGEBRA ");
outtextxy (125,140," Cls.a VIII-a ");
moveto (120,160);
lineto (279,160);
lineto (279,120);
moveto (120,220);
lineto (120,180);
lineto (279,180);
setcolor (WHITE);
moveto (120,220);
lineto (279,220);
lineto (279,180);
moveto (105,285);
lineto (295,285);
lineto (295,285);
setfillstyle (SOLID_FILL,LIGHTGRAY);
bar (100,280,300,440);
setcolor (WHITE);
moveto (105,435);
lineto (105,285);
lineto (295,285);
setcolor (BLACK);
lineto (295,435);
lineto (105,435);
outtextxy (135,190,"TEST DE EVALUARE");
LIMBAJUL C TEORIE ŞI APLICAŢI I 211

outtextxy (135,200,"CU CALCULATORUL ");


setcolor (RED);
outtextxy (125,315,"ECUATIA DE GRADUL ");
outtextxy (125,330," al doilea ");
outtextxy (125,345,"");
gotoxy (16,24);
printf (" INTRODUCETI NR ");
gotoxy (16,25);
printf (" CALCULATORULUI =");
scanf ("%d",&f);
setcolor (BLUE);
for (w=10;w<=50;w=w+2)
{
delay (30);
circle (450,300,60+w);
}
delay (3000);
cleardevice();
for (i=-26+27*f;i<=27*f;i=i+3)
{
a=z[i];
b=z[i+1];
c=z[i+2];
setfillstyle (SOLID_FILL,RED);
bar (100,100,310,190);
setcolor (WHITE);
moveto (120,170);
lineto (120,120);
lineto (290,120);
setcolor (BLACK);
lineto (290,170);
lineto (120,170);
gotoxy (18,9);
printf ("REZOLVATI ECUATIA");
gotoxy (20,10);
if (a==1)
{
if (b<0)
if (b==-1)
{
if (c<0)
printf ("x^2-x%d=0",c);
else
if (c==0)
printf ("x^2-x=0");
else
printf ("x^2-x+%d=0",c);
}
else
{
if (c<0)
LIMBAJUL C TEORIE ŞI APLICAŢI I 212

printf ("x^2%dx%d=0",b,c);
else
if (c==0)
printf ("x^2%dx=0",b);
else
printf ("x^2%dx+%d=0",b,c);
}
else
if (b==0)
{
if (c<0)
printf ("x^2%d=0",c);
else
if (c==0)
printf ("x^2=0");
else
printf ("x^2+%d=0",c);
}
else
if (b==1)
{
if (c<0)
printf ("x^2+x%d=0",c);
else
if (c==0)
printf ("x^2+x=0");
else
printf ("x^2+x+%d=0",c);
;
}
else
if (c<0)
printf ("x^2+%dx%d=0",b,c);
else
if (c==0)
printf ("x^2+%dx=0",b);
else
printf ("x^2+%dx+%d=0",b,c);
;
}
else

{
if (b<0)
if(b==-1)
{
if (c<0)
printf ("%dx^2-x%d=0",a,c);
else
if (c==0)
printf ("%dx^2-x=0",a);
LIMBAJUL C TEORIE ŞI APLICAŢI I 213

else
printf ("%dx^2-x+%d=0",a,c);
}
else
{
if (c<0)
printf ("%dx^2%dx%d=0",a,b,c);
else
if (c==0)
printf ("%dx^2%dx=0",a,b);
else
printf ("%dx^2%dx+%d=0",a,b,c);
}
else
if (b==0)
{
if (c<0)
printf ("%dx^2%d=0",a,c);
else
if (c==0)
printf ("%dx^2=0",a);
else
printf ("%dx^2+%d=0",a,c);
}
else
if (b==1)
{
if (c<0)
printf ("%dx^2+x%d=0",a,c);
else
if (c==0)
printf ("%dx^2+x=0",a);
else
printf ("%dx^2+x+%d=0",a,c);
;
}
else
if (c<0)
printf ("%dx^2+%dx%d=0",a,b,c);
else
if (c==0)
printf ("%dx^2+%dx=0",a,b);
else
printf ("%dx^2+%dx+%d=0",a,b,c);
;
}
setfillstyle (SOLID_FILL,CYAN);
bar (100,250,310,342);
setcolor (WHITE);
moveto (120,330);
lineto (120,265);
LIMBAJUL C TEORIE ŞI APLICAŢI I 214

lineto (290,265);
setcolor (BLACK);
lineto (290,330);
lineto (120,330);
gotoxy (18,18);
printf ("SCRIETI SOLUTIILE");
gotoxy (20,19);
printf ("X1=");
scanf ("%f",&xx1);
gotoxy (20,20);
printf ("X2=");
scanf ("%f",&xx2);
w1= ecu2 (a,b,c,xx1,xx2);
setfillstyle (SOLID_FILL,YELLOW);
bar (320,100,560,190);
setcolor (WHITE);
moveto (340,180);
lineto (340,110);
lineto (550,110);
setcolor (BLACK);
lineto (550,180);
lineto (340,180);
gotoxy (45,9);
printf ("PUNCTAJUL OBTINUT");
gotoxy (45,10);
printf ("PARTIAL=%d",w1);
w2=w1+w2;
gotoxy (45,11);
printf ("TOTAL=%d",w2);
setfillstyle (SOLID_FILL,BLUE);
bar (200,348,380,370);
delay (100);
for (ii=1;ii<=5;ii=ii+1)
{
gotoxy (28,23);
puts (" ");
delay (100);
gotoxy (28,23);
puts (" Apasati o tasta ");
delay (200);
}
getch ();
clrscr ();
}
dd:
setfillstyle (SOLID_FILL,MAGENTA);
setcolor (BLUE);
bar (100,200,400,360);
gotoxy (15,15);
printf (" PUNCTAJUL TOTAL OBTINUT ESTE= %d \n",w2 );
gotoxy (15,17);
LIMBAJUL C TEORIE ŞI APLICAŢI I 215

printf (" ATI OBTINUT NOTA : %d ",w2+1);


gotoxy (17,21);
puts (" APASATI O TASTA ");

getch ();
closegraph ();
}

int ecu2(float a, float b, float c, float


xx1 , float xx2)
{
float x1,x2,x1r,x1i,x2i,d ;
int punctaj1 ,punctjt ,i;
char e;
inceput:
clrscr ();
sound (1200);
delay (200);
nosound ();
puts ("");
/* puts (" ECUATIA DE
GRADUL AL DOILEA CU COEFICIENTI REALI ");
*/

fflush (stdin);
d=b*b-4*a*c;
if(d>0)
{
d=sqrt (d);
d=d/(2*a);
x1=-b/(2*a)+d;
x2=-b/(2*a)-d;
/* printf (" Solutiile ecuatiei
sunt reale si diferite \n"); */
/* printf (" x1=%f
x2=%f\n",x1,x2); */
}
else
if (d==0)
{
if (b==0)
{
x1=0;
x2=0;
}
else
{
x1=-b/(2*a);
x2=x1;
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 216

/* printf (" Solutiile ecuatiei


sunt reale si egale \n "); */
/* printf (" x1=x2=%f \n",x1,x2);
*/
}
else
{
d=-d;
d=sqrt (d);
x1r=-b/(2*a);
x1i=d/(2*a);
/* printf (" Solutiile ecuatiei nu
sunt numere reale \n"); */
/* printf (" x1=%f+i*%f x2=%f-
i*%f\n",x1r,x1i,x1r,x1i); */
}
fflush (stdin);

if (fabs (xx1-x1)<=0.02)
{
if (fabs(xx2-x2)<=0.02)
{
punctaj1=1;
corect ();
}
else
{
punctaj1=0;
gresit ();
}
}
else
{
if (fabs (xx2-x1)<=0.02)
{
if (fabs (xx1-x2)<=0.02)
{
punctaj1=1;
corect ();
}
else
{
punctaj1=0;
gresit ();
}
}
else
{
punctaj1=0;
gresit ();
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 217

}
setfillstyle (SOLID_FILL,GREEN);
bar (320,250,560,342);
setcolor (WHITE);
moveto (340,330);
lineto (340,265);
lineto (550,265);
setcolor (BLACK);
lineto (550,330);
lineto (340,330);
gotoxy (45,18);
printf ("SOLUTIILE CORECTE SUNT");
gotoxy (45,19);
printf ("X1=%.2f",x1);
gotoxy (45,20);
printf ("X2=%.2f",x2);
return (punctaj1);
}

void corect (void)


{
bar (200,200,380,240);
gotoxy (29,14);
printf (" CORECT ");
}

void gresit (void)


{
bar (200,200,380,240);
gotoxy (29,14);
printf (" GRESIT ") ;
}

caseta1 (int um ,int cul , int stinga, int sus , int cul1, int cul2)
{
int dreapta,jos ;
dreapta=stinga+200;
jos=sus+190;
setfillstyle (um,cul);
bar (stinga,sus,dreapta,jos);
setcolor (cul1);
moveto (stinga+20,sus+90);
lineto (stinga+20,sus+20);
lineto (dreapta-30,sus+20);
setcolor (cul2);
outtextxy (stinga+25,sus+40," test1 ");
outtextxy (stinga+25,sus+60," rind 2 ");
moveto (stinga+20,sus+90);
lineto (dreapta-30,sus+90);
lineto (dreapta-30,sus+20);
moveto (stinga+20,sus+170);
LIMBAJUL C TEORIE ŞI APLICAŢI I 218

lineto (stinga+20,sus+100);
lineto (dreapta-30,sus+100);
setcolor (cul1);
moveto (stinga+20,sus+170);
lineto (dreapta-30,sus+170);
lineto (dreapta-30,sus+100);
}

int caseta2 (int um ,int cul , int stinga, int sus , int cul1, int
cul2)
{
int dreapta,jos,punctaj1 ;
dreapta=stinga+250;
jos=sus+190;
setfillstyle (um,cul);
bar (stinga,sus,dreapta,jos);
setcolor (cul1);
moveto (stinga+20,sus+90);
lineto (stinga+20,sus+20);
lineto (dreapta-30,sus+20);
setcolor (cul2);
outtextxy (stinga+25,sus+40,"");
outtextxy (stinga+25,sus+60,"");
moveto (stinga+20,sus+90);
lineto (dreapta-30,sus+90);
lineto (dreapta-30,sus+20);
moveto (stinga+20,sus+170);
lineto (stinga+20,sus+100);
lineto (dreapta-30,sus+100);
setcolor (cul1);
moveto (stinga+20,sus+170);
lineto (dreapta-30,sus+170);
lineto (dreapta-30,sus+100);

outtextxy (stinga+38,sus+30,"SOLUTIILE CORECTE SUNT");


gotoxy (stinga/6+3,sus/12+3);
printf ("X1=%.2f \n");
gotoxy (stinga/6+3,sus/12+5);
printf ("X2=%.2f");
return (punctaj1);
}

caseta3 (int um ,int cul , int stinga, int sus , int cul1, int cul2)
{
int dreapta,jos ;
dreapta=stinga+250;
jos=sus+190;
setfillstyle (um,cul);
bar (stinga,sus,dreapta,jos);
setcolor (cul1);
moveto (stinga+20,sus+90);
LIMBAJUL C TEORIE ŞI APLICAŢI I 219

lineto (stinga+20,sus+20);
lineto (dreapta-30,sus+20);
setcolor (cul2);
outtextxy (stinga+25,sus+40," test1 ");
outtextxy (stinga+25,sus+60," rind 2 ");
moveto (stinga+20,sus+90);
lineto (dreapta-30,sus+90);
lineto (dreapta-30,sus+20);
moveto (stinga+20,sus+170);
lineto (stinga+20,sus+100);
lineto (dreapta-30,sus+100);
setcolor (cul1);
moveto (stinga+20,sus+170);
lineto (dreapta-30,sus+170);
lineto (dreapta-30,sus+100);

gotoxy (45,18);
printf ("SOLUTIILE CORECTE SUNT");
gotoxy (45,19);
printf ("X1=%.2f");
gotoxy (45,20);
printf ("X2=%.2f");
}

5.13 Program de rezolvare a sistemului liniar cu 2 necunoscute.


Pentru ca elevul să poată lucra singur şi să fie testat fără a implica factorul uman, s-
a realizat un program ce permite alegerea unui set de 9 sisteme liniare , afişarea
acestor sisteme într-un mod indentic cu scrierea pe tablă, apoi afişarea casetei de
dialog, în care elevul va indica cele două soluţii.
În următoarea etapă se evaluează de calculator soluţiile date cu soluţiile corecte şi
atribuie sau nu a unui punct pentru fiecare sistem prelucrat .
Se continuă evaluarea următoarelor 8 sisteme, în final calculatorul afişează
punctajul obţinut şi nota.
Programul combină modul grafic cu modul text şi prin dezvoltarea bazei de date
aferente celor 6 coeficienţi a, b, c, d,e, f, ale sistemului liniar, se poate realiza
evaluarea a unui număr cât mai mare de elevi.
La modificarea bazei de date se va ţine cont ca soluţiile sistemului să fie valori
reale. Pentru a controla accesul în program cât şi închiderea programului, s-a
prevăzut un cod de intrare 1900 şi un cod de terminare 1800, aceste coduri se pot
modifica prin schimbarea valorilor aferente în programul sursă.
Programul sursă este efectuat pentru numărul calculatorului =1.

# include <stdio.h>
# include <conio.h>
# include <dos.h>
# include <graphics.h>
# include <math.h>
LIMBAJUL C TEORIE ŞI APLICAŢI I 220

# include <stdlib.h>
# include <stdarg.h>
void gresit (void);
void corect (void);
int ecu2 (float,float,float,float,float,float,float,float);
void main ()
{
int gdriver = DETECT,gmode,errorcode;
unsigned long s;
int xmax,ymax,i,ii,j,l,n,x,y,a,b,c,a1,b1,c1,t,r,d,f,g,w1,w2;
int e;
int um,cul,stinga,jos,dreapta,sus,cul1,cul2;

float w,z[170],xx1,xx2,e1;
fflush (stdin);
w1=0; w2=0;
puts ("DATI CODUL");
scanf ("%d",&r);
if (r==1900)
{
clrscr ();
xmax=getmaxx();ymax=getmaxy();
initgraph(&gdriver,&gmode," ");
setviewport(0,0,getmaxx(),getmaxy(),0);
errorcode=graphresult();
if(errorcode!=grOk) printf("Eroare grafica:
%s\n",grapherrormsg(errorcode));
cleardevice();
MENIU:
/* settextstyle (SANS_SERIF_FONT,HORIZ_DIR,0); */
/* setusercharsize (6,2,6,2); */

setfillstyle (SOLID_FILL,RED);
bar (100,100,300,240);
setcolor (WHITE);
moveto (120,160);
lineto (120,120);
lineto (279,120);
setcolor (BLACK);
outtextxy (125,130," ALGEBRA ");
outtextxy (125,140," Cls.a VIII-a ");
moveto (120,160);
lineto (279,160);
lineto (279,120);
moveto (120,220);
lineto (120,180);
lineto (279,180);
setcolor (WHITE);
moveto (120,220);
lineto (279,220);
lineto (279,180);
LIMBAJUL C TEORIE ŞI APLICAŢI I 221

moveto (105,285);
lineto (295,285);
lineto (295,285);
setfillstyle (SOLID_FILL,LIGHTGRAY);
bar (100,280,300,440);
setcolor (WHITE);
moveto (105,435);
lineto (105,285);
lineto (295,285);
setcolor (BLACK);
lineto (295,435);
lineto (105,435);
outtextxy (135,190,"TEST DE EVALUARE");
outtextxy (135,200,"CU CALCULATORUL ");
setcolor (RED);
outtextxy (125,315,"SISTEME DE ECUATII ");
outtextxy (125,330," ");
outtextxy (125,345,"");
gotoxy (16,24);
printf (" INTRODUCETI NR ");
gotoxy (16,25);
printf (" CALCULATORULUI =");
scanf ("%d",&f);
setcolor (BLUE);
for (w=10;w<=50;w=w+2)
{
delay (30);
circle (450,300,60+w);
}
delay (3000);
cleardevice();
z[1]=1; z[2]=0; z[3]=5;
z[4]=2; z[5]=3; z[6]=4;
z[7]=5;z[8]=-1;z[9]=3;
z[10]=0;z[11]=1;z[12]=2;
z[13]=1; z[14]=-3; z[15]=0;
z[16]=5; z[17]=-7; z[18]=8;
z[19]=-4;z[20]=1;z[21]=-3;
z[22]=1;z[23]=1;z[24]=7;
z[25]=1; z[26]=-1; z[27]=4;
z[28]=1; z[29]=1; z[30]=11;
z[31]=1;z[32]=2;z[33]=3;
z[34]=2;z[35]=1;z[36]=3;
z[37]=1; z[38]=1; z[39]=1;
z[40]=1; z[41]=-1; z[42]=-3;
z[43]=-1;z[44]=4;z[45]=5;
z[46]=1;z[47]=3;z[48]=2;
z[49]=3; z[50]=2; z[51]=10;
z[52]=7; z[53]=-8; z[54]=-2;

for (i=-53+54*f;i<=54*f;i=i+6)
LIMBAJUL C TEORIE ŞI APLICAŢI I 222

{
setfillstyle (SOLID_FILL,RED);
bar (100,100,310,190);
setcolor (WHITE);
moveto (120,180);
lineto (120,110);
lineto (290,110);
setcolor (BLACK);
lineto (290,180);
lineto (120,180);
gotoxy (18,8);
printf ("REZOLVATI SISTEMUL");
gotoxy (20,10);
a=z[i];
b=z[i+1];
c=z[i+2];
a1=z[i+3];
b1=z[i+4];
c1=z[i+5];

if (a==1)
{
if (b<0)
if (b==-1)
{
if (c<0)
printf ("x-y=%d",c);
else
if (c==0)
printf ("x-y=0");
else
printf ("x-y=%d",c);
}
else
{
if (c<0)
printf ("x%dy=%d",b,c);
else
if (c==0)
printf ("x%dy=0",b);
else
printf ("x%dy=%d",b,c);
}
else
if (b==0)
{
if (c<0)
printf ("x=%d",c);
else
if (c==0)
printf ("x=0");
LIMBAJUL C TEORIE ŞI APLICAŢI I 223

else
printf ("x=%d",c);
}
else
if (b==1)
{
if (c<0)
printf ("x+y=%d",c);
else
if (c==0)
printf ("x+y=0");
else
printf ("x+y=%d",c);
;
}
else
if (c<0)
printf ("x+%dy=%d",b,c);
else
if (c==0)
printf ("x+%dy=0",b);
else
printf ("x+%dy=%d",b,c);
;
}
else
if (a!=0)
{
if (b<0)
if(b==-1)
{
if (c<0)
printf ("%dx-y=%d",a,c);
else
if (c==0)
printf ("%dx-y=0",a);
else
printf ("%dx-y=%d",a,c);
}
else
{
if (c<0)
printf ("%dx%dy =%d",a,b,c);
else
if (c==0)
printf ("%dx%dy=0",a,b);
else
printf ("%dx%dy=%d",a,b,c);
}
else
if (b==0)
LIMBAJUL C TEORIE ŞI APLICAŢI I 224

{
if (c<0)
printf ("%dx=%d",a,c);
else
if (c==0)
printf ("%dx=0",a);
else
printf ("%dx=%d",a,c);
}
else
if (b==1)
{
if (c<0)
printf ("%dx+y=%d",a,c);
else
if (c==0)
printf ("%dx+y=0",a);
else
printf ("%dx+y=%d",a,c);
;
}
else
if (c<0)
printf ("%dx+%dy=%d",a,b,c);
else
if (c==0)
printf ("%dx+%dy=0",a,b);
else
printf ("%dx+%dy=%d",a,b,c);
;
}

else

{
if (b<0)
if (b==-1)
{
if (c<0)
printf ("-y=%d",c);
else
if (c==0)
printf ("-y=0");
else
printf ("-y=%d",c);
}
else
{
if (c<0)
printf ("%dy=%d",b,c);
LIMBAJUL C TEORIE ŞI APLICAŢI I 225

else
if (c==0)
printf ("%dy=0",b);
else
printf ("%dy=%d",b,c);
}
else
if (b==0)
{
if (c<0)
printf ("=%d",c);
else
if (c==0)
printf ("=0");
else
printf ("=%d",c);
}
else
if (b==1)
{
if (c<0)
printf ("y=%d",c);
else
if (c==0)
printf ("y=0");
else
printf ("y=%d",c);
}
else
if (c<0)
printf ("%dy=%d",b,c);
else
if (c==0)
printf ("%dy=0",b);
else
printf ("%dy=%d",b,c);
;
}

gotoxy (20,11);

if (a1==1)
{
if (b1<0)
if (b1==-1)
{
if (c1<0)
printf ("x-y=%d",c1);
else
if (c1==0)
printf ("x-y=0");
LIMBAJUL C TEORIE ŞI APLICAŢI I 226

else
printf ("x-y=%d",c1);
}
else
{
if (c1<0)
printf ("x%dy=%d",b1,c1);
else
if (c1==0)
printf ("x%dy=0",b1);
else
printf ("x%dy=%d",b1,c1);
}
else
if (b1==0)
{
if (c1<0)
printf ("x=%d",c1);
else
if (c1==0)
printf ("x=0");
else
printf ("x=%d",c1);
}
else
if (b1==1)
{
if (c1<0)
printf ("x+y=%d",c1);
else
if (c1==0)
printf ("x+y=0");
else
printf ("x+y=%d",c1);
;
}
else
if (c1<0)
printf ("x+%dy=%d",b1,c1);
else
if (c1==0)
printf ("x+%dy=0",b1);
else
printf ("x+%dy=%d",b1,c1);
;
}
else

if (a1!=0)

{
LIMBAJUL C TEORIE ŞI APLICAŢI I 227

if (b1<0)
if(b1==-1)
{
if (c1<0)
printf ("%dx-y=%d",a1,c1);
else
if (c1==0)
printf ("%dx-y=0",a1);
else
printf ("%dx-y=%d",a1,c1);
}
else
{
if (c1<0)
printf ("%dx%dy =%d",a1,b1,c1);
else
if (c1==0)
printf ("%dx%dy=0",a1,b1);
else
printf ("%dx%dy=%d",a1,b1,c1);
}
else
if (b1==0)
{
if (c1<0)
printf ("%dx=%d",a1,c1);
else
if (c1==0)
printf ("%dx=0",a1);
else
printf ("%dx=%d",a1,c1);
}
else
if (b1==1)
{
if (c1<0)
printf ("%dx+y=%d",a1,c1);
else
if (c1==0)
printf ("%dx+y=0",a1);
else
printf ("%dx+y=%d",a1,c1);
;
}
else
if (c1<0)
printf ("%dx+%dy=%d",a1,b1,c1);
else
if (c1==0)
printf ("%dx+%dy=0",a1,b1);
else
LIMBAJUL C TEORIE ŞI APLICAŢI I 228

printf ("%dx+%dy=%d",a1,b1,c1);
;
}

else

{
if (b1<0)
if (b1==-1)
{
if (c1<0)
printf ("-y=%d",c1);
else
if (c1==0)
printf ("-y=0");
else
printf ("-y=%d",c1);
}
else
{
if (c1<0)
printf ("%dy=%d",b1,c1);
else
if (c1==0)
printf ("%dy=0",b1);
else
printf ("%dy=%d",b1,c1);
}
else
if (b1==0)
{
if (c1<0)
printf ("=%d",c1);
else
if (c1==0)
printf ("=0");
else
printf ("=%d",c1);
}
else
if (b1==1)
{
if (c1<0)
printf ("y=%d",c1);
else
if (c1==0)
printf ("y=0");
else
printf ("y=%d",c1);

}
LIMBAJUL C TEORIE ŞI APLICAŢI I 229

else
if (c1<0)
printf ("%dy=%d",b1,c1);
else
if (c1==0)
printf ("%dy=0",b1);
else
printf ("%dy=%d",b1,c1);
;
}

setfillstyle (SOLID_FILL,CYAN);
bar (100,250,310,342);
setcolor (WHITE);
moveto (120,330);
lineto (120,265);
lineto (290,265);
setcolor (BLACK);
lineto (290,330);
lineto (120,330);
gotoxy (18,18);
printf ("SCRIETI SOLUTIA");
gotoxy (20,19);
printf ("X=");
scanf ("%f",&xx1);
gotoxy (20,20);
printf ("Y=");
scanf ("%f",&xx2);
w1= ecu2 (a,b,c,a1,b1,c1,xx1,xx2);
setfillstyle (SOLID_FILL,YELLOW);
bar (320,100,560,190);
setcolor (WHITE);
moveto (340,180);
lineto (340,110);
lineto (550,110);
setcolor (BLACK);
lineto (550,180);
lineto (340,180);
gotoxy (45,9);
printf ("PUNCTAJUL OBTINUT");
gotoxy (45,10);
printf ("PARTIAL=%d",w1);
w2=w1+w2;
gotoxy (45,11);
printf ("TOTAL=%d",w2);
setfillstyle (SOLID_FILL,BLUE);
bar (200,348,380,370);
delay (100);
for (ii=1;ii<=5;ii=ii+1)
{
gotoxy (28,23);
LIMBAJUL C TEORIE ŞI APLICAŢI I 230

puts (" ");


delay (100);
gotoxy (28,23);
puts (" Apasati o tasta ");
delay (200);
}
getch ();
clrscr ();
}

dd:
setfillstyle (SOLID_FILL,MAGENTA);
setcolor (BLUE);
bar (100,200,400,360);
gotoxy (15,15);
printf (" PUNCTAJUL TOTAL OBTINUT ESTE= %d \n",w2 );
gotoxy (15,17);
printf (" ATI OBTINUT NOTA : %d ",w2+1);
gotoxy (17,21);
puts ("CODUL DE TERMINARE");
gotoxy (17,22);
fflush (stdin);
scanf ("%f",&e1);
if (e1==1800)
{
gotoxy (17,22);
puts (" ");
gotoxy (17,21);
puts ("CORECT APASATI O TASTA");
}
else
{
gotoxy (17,22);
puts (" ");
goto dd;
}
}
else
puts ("\n EROARE");
getch ();
closegraph ();
}

int ecu2(float a, float b, float c,float a1, float b1, float


c1, float xx1 , float xx2)
{
float x1,x2,d ;
int punctaj1 ,punctjt ,i;
char e;
inceput:
clrscr ();
LIMBAJUL C TEORIE ŞI APLICAŢI I 231

sound (1200);
delay (200);
nosound ();
puts ("");

fflush (stdin);
d=a*b1-a1*b;
if(d==0)
{
printf (" Sistemul nu are solutii unice \n");
}
else
{
x1=(c1*b-c*b1)/(a1*b-a*b1);
x2=(c1*a-c*a1)/(a*b1-a1*b);
}
fflush (stdin);

if (fabs (xx1-x1)<=0.02)
{
if (fabs(xx2-x2)<=0.02)
{
punctaj1=1;
corect ();
}
else
{
punctaj1=0;
gresit ();
}
}
else
{
punctaj1=0;
gresit ();
}
setfillstyle (SOLID_FILL,GREEN);
bar (320,250,560,342);
setcolor (WHITE);
moveto (340,330);
lineto (340,265);
lineto (550,265);
setcolor (BLACK);
lineto (550,330);
lineto (340,330);
gotoxy (45,18);
printf ("SOLUTIILE CORECTE SUNT");
gotoxy (45,19);
printf ("X=%.2f",x1);
gotoxy (45,20);
printf ("Y=%.2f",x2);
LIMBAJUL C TEORIE ŞI APLICAŢI I 232

return (punctaj1);
}

void corect (void)


{
bar (200,200,380,240);
gotoxy (29,14);
printf (" CORECT ");
}
void gresit (void)
{
bar (200,200,380,240);
gotoxy (29,14);
printf (" GRESIT ") ;
}
LIMBAJUL C TEORIE ŞI APLICAŢI I 233

Bibliografie

1. Williams S., Programming the 68000, Sybex Inc., Berkeley, 1982


2. Patrubany M., Totul despre microprocesorul Z80, Editura tehnică, Bucureşti, 1989
3. Caius I., ş.a., Matematici clasice şi moderne, Editura tehnică, Bucureşti, 1983
4. Bobancu V., ş.a., Dicţionar de matematici generale, Editura enciclopedică
română, Bucureşti, 1974
5. Ionică A., Iordan V., Algoritmi şi programe, Editura Mirton, Timişoara, 1994
6. Ilin A., Munteanu C., Programarea calculaoarelor – Limbajul C, Editura
orizonturi universitare, Timişoara, 2000
7. Negrescu L., Limbajul C şi C++ pentru începători, volumele 1, 2 şi 3, Editura
microinformatica, Cluj, 1994
8. Căprariu V., Ghid de utilizare Turbo C 2.0, Editura microinformatica, Cluj, 1991
9. Chioreanu C., Utilizare comenzi interfeţe MS-DOS 6.0, Editura microinformatica,
Cluj, 1994
10. Lucanu D., Proiectarea algoritmilor – Tehnici elementare, Editura univerităţii Al.
I. Cuza, Iaşi, 1993
11. Cucuruz L. R., Radu B., Limbaje de programare şi utilizarea calculatoarelor,
Editura Mirton, Timişoara, 1998
12. Boian F., ş.a., Informatica pentru elevi, Editura microinformatica, Cluj, 1992
13. Swan T., Învăţăm C++ pas cu pas, Editura tehnică, Bucureşti, 1996
14. Catrina O., Cojocaru I., Turbo C++, Editura Teora, 1993
15. Doandeş P. Pintea D. Utilizarea calculatoarelor, Editura de Vest, Timişoara, 2002.
LIMBAJUL C TEORIE ŞI APLICAŢI I 234

CUPRINS
1 Algoritmi ..................................................................................................... 9
1.1 Introducere .................................................................................................... 9
1.2. Algoritmi şi organigrame........................................................................................9
1.2.1. Algoritmi liniari ..................................................................................... 11
1.2.2. Algoritmi ramificaţi ................................................................................ 12
1.2.3. Algoritmi ciclici ....................................................................................... 17
2. Mediul de programare turbo c 2.0 .......................................................... 22
2.1. Mediul de lucru .......................................................................................... 22
2.1.2.Meniul principal ............................................................................................... 24
2.1.2.1.Meniul FILE ....................................................................................................25
2.1.2.2. Meniul Edit .....................................................................................................25
2.1.2.3. Meniul Run .....................................................................................................29
2.1.2.4. Meniul Debug. ................................................................................................ 29
2.1.2.5. Meniul Break/watch. ...................................................................................... 30
2.1.2.6. Meniul options ................................................................................................ 30
3. Structura unui program sursă în limbajul C. ........................................ 32
3.1. Crearea unui program ............................................................................... 33
3.2. Tipuri de date. ............................................................................................ 35
3.2.1. Tipul întreg ........................................................................................................ 35
3.2.2. Tipul real ........................................................................................................... 35
3.2.3. Tipul caracter .....................................................................................................35
3.3. Constante şi variabile ................................................................................ 36
3.3.1. Constante ......................................................................................................... 36
3.3.2. Variabile ........................................................................................................... 36
3.3.2.1. Variabile locale şi globale............................................................................. 37
3.3.2.2. Convenţia de denumire a variabilelor şi constantelor. .............................. 38
3.4. Funcţii. Introducere ................................................................................... 38
3.4.1. Funcţii standard de intrare ieşire ......................................................... 39
3.5. Instrucţiuni. Expresii. Operatori .............................................................. 45
3.5.1. Instrucţiuni. ......................................................................................................45
3.5.1.1. Instrucţiunea vidă. ........................................................................................ 46
3.5.1.2. Instrucţiunea expresie. ................................................................................. 46
3.5.1.3. Instrucţiunea compusă. ................................................................................ 46
3.5.1.4. Instrucţiunea de atribuire. ........................................................................... 47
3.5.2. Operatori. ......................................................................................................... 47
3.5.2.1. Operatori aritmetici. .................................................................................... 48
LIMBAJUL C TEORIE ŞI APLICAŢI I 235

3.5.2.2. Typecasting. ..................................................................................................49


3.5.2.3. Operatori relaţionali..................................................................................... 49
3.5.2.4. Operatorii logici. ........................................................................................... 51
3.5.2.5. Operatorii de incrementare şi decrementare. ............................................ 51
3.5.3. Instrucţiunea if. ...................................................................................... 52
3.5.4. Instrucţiunea for. ................................................................................... 59
3.5.5. Instrucţiunea while. ................................................................................ 69
3.5.6. Instrucţiunea do while. .......................................................................... 73
3.5.7. Instrucţiunea break. .............................................................................. 77
3.5.8. Instrucţiunea continue. ........................................................................... 77
3.5.9. Funcţia exit. ............................................................................................. 78
3.5.10. Instrucţiunea switch............................................................................. 78
3.5.11. Instrucţiunea goto. ................................................................................ 81
3.6. Apelul prin valoare şi apelul prin referinţă al unei funcţii. .................. 82
3.7. Operaţii asupra vectorilor. ....................................................................... 82
3.8. Operaţii asupra tablourilor cu două dimensiuni..................................... 92
3.9. Funcţii de bibliotecă. ................................................................................. 99
3.9.1. Funcţii de intrare ieşire. ................................................................................ 100
3.9.2. Funcţii matematice. ....................................................................................... 100
3.9.3. Funcţii de uz general. .................................................................................... 101
3.9.4. Funcţii de conversie. ...................................................................................... 104
3.10. Pointeri. ................................................................................................... 107
3.11. Structuri şi tipuri definite de utilizator. ............................................... 111
3.11.1. Declaraţie de structură. ...................................................................... 112
3.11.2. Accesul la elementele unei structuri. ................................................. 114
3.11.3. Asignări de nume pentru tipuri de date. ........................................... 117
3.12. Prelucrarea şirurilor de caractere. ....................................................... 119
3.12.1. Funcţia strlen,lungimea şirului de caractere. ................................... 120
3.12.2. Funcţia strcpy, copierea unui şir de caractere. ................................ 120
3.12.3. Funcţia strncpy, copierea a cel mult n caractere ale unui şir de
caractere........................................................................................................... 121
3.12.4. Funcţia strcat, concatenarea şirurilor de caractere. ........................ 122
LIMBAJUL C TEORIE ŞI APLICAŢI I 236

3.12.5. Funcţia strncat, concatenarea şirurilor de caractere cu lungimea


impusă. ............................................................................................................. 122
3.12.6. Funcţia strcmp, compararea a două şiruri de caractere. ................ 123
3.12.7. Funcţia stricmp, compararea a două şiruri fără a se face distincţia
între litere mari sau mici. ............................................................................... 123
3.12.8. Funcţia strincmp. ................................................................................ 124
3.13. Prelucrarea fişierelor. ............................................................................ 126
3.13.1.1 Nivelul superior de prelucrare a fişierelor. ............................................. 126
3.13.2. Intrări ieşiri cu format. ............................................................................... 127
3.13.3. Poziţionarea în fişier. .......................................................................... 127
3.14. Preprocesorul C. .................................................................................... 131
Directiva #include. ...................................................................................................131
directiva #define ......................................................................................................132
Directiva #error. ...................................................................................................... 135
Compilarea condiţionată. ........................................................................................ 135
Directiva #if. ............................................................................................................. 136
Directiva #elif. .......................................................................................................... 137
Directivele #ifdef şi ifndef. ...................................................................................... 138
Diectiva #line. .......................................................................................................... 139
Operatori de preprocesare # şi ##. ......................................................................... 140
4. Grafică în C. .......................................................................................... 140
4.1. Moduri grafice. ......................................................................................... 141
4.2. Sisteme de cordonate. .............................................................................. 142
4.3. Culori şi palete de culori.......................................................................... 143
4.4. Moduri de umplere. ................................................................................. 143
4.5. Stiluri de linii. ........................................................................................... 144
4.6. Afişarea textului în mod grafic. ............................................................. 144
4.7. Tipuri de date folosite în funcţiile grafice. ............................................. 145
4.8. FUNCŢII DE DESENARE. .................................................................... 149
4.8.1. ARC. ............................................................................................................... 149
4.8.2. Bar .................................................................................................................. 150
4.8.3. Bar3d .............................................................................................................. 152
4.8.4. Circle............................................................................................................... 153
4.8.5. Rectangle ........................................................................................................ 154
4.8.6. Line ................................................................................................................. 154
4.8.7. Moveto ............................................................................................................ 155
4.8.8. linerel .............................................................................................................. 155
LIMBAJUL C TEORIE ŞI APLICAŢI I 237

4.8.9. lineto ............................................................................................................... 157


4.8.10. moverel ......................................................................................................... 158
4.8.11. drawpoly ....................................................................................................... 158
4.8.12. ellipse ............................................................................................................ 160
4.8.13. fillellipse ........................................................................................................ 161
4.8.14. fillpoly ........................................................................................................... 161
4.8.15. floodfill .......................................................................................................... 162
4.8.16. outtext ........................................................................................................... 163
4.8.17. outtextxy ....................................................................................................... 164
4.8.18. pieslice........................................................................................................... 165
4.8.19. putpixel ......................................................................................................... 166
4.8.20. sector ............................................................................................................. 167
4.9. Funcţii pentru setarea variabilelor in mod grafic ................................. 168
4.9.1. Setallpalette ....................................................................................................168
4.9.2. setbkcolor ....................................................................................................... 168
4.9.3. Setcolor ........................................................................................................... 168
4.9.4. setpalette ......................................................................................................... 168
4.9.5. setfillstyle ........................................................................................................ 169
4.9.6. setfillpattern ...................................................................................................169
4.9.7. setlinestyle ...................................................................................................... 170
4.9.8. settextjustify ...................................................................................................171
4.9.9. settextstyle ...................................................................................................... 172
4.9.10. setviewport ...................................................................................................173
4.9.11. cleardwvice ...................................................................................................175
4.9.12. clearviewport................................................................................................ 175
4.10. Funcţii de interogare a sistemului. ....................................................... 176
4.10.1. getarccoords .................................................................................................176
4.10.2. getbkcolor .....................................................................................................177
4.10.3. getcolor ......................................................................................................... 177
4.10.4. getgraphmode .............................................................................................. 178
4.10.5. getmaxmode .................................................................................................178
4.10.6. getmaxx ......................................................................................................... 178
4.10.7. getmaxy ......................................................................................................... 178
4.10.8. imagesize ....................................................................................................... 179
4.10.9. getimage ........................................................................................................ 179
4.10.10. getx .............................................................................................................. 181
4.10.11. gety .............................................................................................................. 181
4.10.12. getpixel ........................................................................................................ 181
4.11. Funcţii de iniţializare şi închidere a sistemului grafic. ....................... 182
4.11.1. initgraph ....................................................................................................... 182
4.11.2. closegraph.....................................................................................................182
5. Programe aplicative.............................................................................. 183
5.1. Programe şi algoritmi pentru sortare şi căutare. ................................. 183
LIMBAJUL C TEORIE ŞI APLICAŢI I 238

5.2. Program pentru rezolvarea sistemelor de ecuaţii liniare .................... 189


5.3. Metoda Cramer pentru determinarea valorii determinantului .......... 193
5.4. Caracteristicile geometrice ale secţiunilor transversale ....................... 194
5.5. Calculul analitic al eforturilor M, N, T .................................................. 196
5.6. Calculul ariilor contururilor poligonale închise ................................... 199
5.7. Calculul integralelor prin metoda dreptunghiului............................... 200
5.8. Soluţionarea numerică a ecuaţiilor neliniare prin metoda bisecţiei .... 201
5.9. Calculul coordonatelor unei retrointersecţie ......................................... 203
5.10 .Calculul distanţelor dintre puncte consecutive şi calculul distanţei
totale dintre primul şi ultimul punct. ............................................................ 204
5.11. Calculul momentelor de inerţie şi poziţia centrului de greutate folosind
o bază de date pentru profile standard ......................................................... 206
5.12. Program pentru rezolvarea ecuaţiei de gradul II ............................... 209
5.13. Program de rezolvare a sistemului liniar cu 2 necunoscute. .............. 219

S-ar putea să vă placă și