Documente Academic
Documente Profesional
Documente Cultură
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.
a, b
x := -b/a
Stop
Start
a:= a*π/180
Stop
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
START
ORDONAT X,Y
CITEŞTE
a,b,c
nu
X>Y
x(1)=a da
y(1)=b
z(1)=c t=y
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
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
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
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
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.
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
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
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.
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.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.
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])
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
%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.
%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.
a programului poate fi :
Structura secvenţială.
Structură alternativă.
Structură ciclică condiţionată anterior.
Structură selectivă.
Structură ciclică condiţionată posterior.
{
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.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.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
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
--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ă.
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
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
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 ,
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
x3 + 3 x<0
F ( x ) = x ( x − 1) x > 1
x 2 + 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 : C xy
Condiţii : x > 1, y < x, y > 1
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.
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
puts("apasa o tasta");
getch ();
}
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
puts ("dati numarul n=?"); afişarea şirului de caractere dintre “dati numarul
n=? ”
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
}
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ă
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
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
#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
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
Probleme propuse
1. Să se realizeze un program care să calculeze Fx = 3x 2 + 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
#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
Probleme propuse
1. Să se realizeze un program care să afişeze Fx = 4 x 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 = 4 x 2 + 2 x + 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");
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
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
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
#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
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
}
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
#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.
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
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);
}
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 :
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
#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
Exemplu.
LIMBAJUL C TEORIE ŞI APLICAŢI I 106
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 :
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
void main ()
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 107
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");
}
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");
}
}
}
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.
struct nume_complex
{
float real ;
LIMBAJUL C TEORIE ŞI APLICAŢI I 112
float imaginar ;
} ;
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 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
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 data_personal
{
char nume ;
char prenume ;
struct data_calendar
data_nasteri ;
char adresa ;
char localitatea ;
} ;
struct complex
{
float real ;
float imaginar ;
}
x,a[3] ;
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
angajat.data_nasteri.zi =12 ;
angajat.data_nasteri.an =1949 ;
Exemplu.
#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
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
p->x ;
p->y ;
operatorul săgeată -> se consideră de prioritate maximă prin asociere de la
stânga la dreapta.
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;
Fişierul erton13.c
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
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.
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
Ş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.
Ş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 :
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 .
Exemplu de folosire :
Exemplu de folosire :
Exemplu de apelare :
Sir1 mic
Sir2 MIC
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);
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
Apasa o tasta
#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
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 :
#define pi 3.14156
la întâlnirea numelui pi în cadrul programuluisursă se va înlocui acest nume cu
valoarea 3.14156.
#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
printf (sir_lung) ;
Se va afişa :
#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.
#undef nume
#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
…..
#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:
#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 ();
}
#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 ();
}
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
#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
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
#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 ();
}
sau
#endif
secventa instructiuni (bloc)
sau
#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 :
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.
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
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
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
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 :
};
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.
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
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 ;
}
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);
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
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
void far bar (int left, int top, int right, int bottom);
# 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ă
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);
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ă
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 ;
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.
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) ;
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) ;
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 :
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 :
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.
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 :
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
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 :
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) ;
Exemplu.
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
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 :
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
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 :
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,
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) ;
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.
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
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 :
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);
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.2. setbkcolor
Funcţia setbkcolor permite schimbarea culori fondului .
Prototipul funcţiei setbkcolor este :
4.9.3. Setcolor
Funcţia setcolor determiă culoarea curentă de desenare pentru text,linii, arce.
Prototipul funcţiei setcolor este :
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
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 :
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 :
Exemplu
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 :
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
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) ;
Exemplu
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 :
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 :
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
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
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 :
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
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 :
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, );
Void far getimage (int left, int top, int right, int bottom, void far *imagine);
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
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 :
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 :
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,
Void far initgraph (int far driver, int far mode, char far*cale pentru driver);
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 :
Exemplu
# include <stdio.h>
# include <conio.h>
# include <graphics.h>
# include <stdlib.h>
void main ()
{
LIMBAJUL C TEORIE ŞI APLICAŢI I 183
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
#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
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 ();
}
x=a[k];
a[k]=a[m];
a[m]=x;
}
n
xr = br( r ) − ∑ arj( r ) x j arr( r ) , 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
;
}
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 Iz=0;
for (i=1;i<=n;i++)
Iz=Iz+Izi[i]+(y0i[i]-y0g)*(y0i[i]-y0g)*ai[i];
return Iz;
}
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;
}
}
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 ();
}
n=6
(x4, y4)
2
3
1
5 4
x
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.
f(x)
f(x)
a b
x h x
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
#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 ();
}
X
P3
P2
P1
Y1
Y
X1
X2
#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
# 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 ();
}
# 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
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
getch ();
closegraph ();
}
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
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);
}
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);
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");
}
# 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
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 ();
}
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);
}
Bibliografie
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