Sunteți pe pagina 1din 25

Limbaje de programare Elemente generale ale limbajului C

1

Lucrarea nr. 2

ELEMENTE GENERALE ALE LIMBAJULUI C


1. Scopul lucrrii
Lucrarea are ca scop prezentarea elementelor de baz ale limbajului C.

2. Noiuni teoretice

2.1 Structura programelor
Orice activitate de programare ncepe cu editarea
programului, n conformitate cu regulile sintactice i
semantice aferente limbajului. Se elaboreaz astfel aa-
numitul program surs", care se pstreaz ntr-un
fiier (fiier surs) sau mai multe. Aceste fiiere au
extensia .c pentru limbajul C i .cpp pentru limbajul
C++.
Pentru a putea fi executat, programul trebuie s
parcurg o serie de etape:
- etapa de compilare care presupune rezolvarea
directivelor ctre preprocesor i transpunerea
programului surs n program obiect" (prin
compilarea unui fiier surs se obine un fiier obiect cu
extensia .obj):
- etapa de link-editare care presupune legarea
programului obiect obinut cu bibliotecile de sistem;
rezult un program executabil (n urma link-editrii
se obine un fiier executabil cu extensia .exe)
- etapa de lansare n execuie.
Un program surs este compus din una sau mai
multe funcii dintre care una singur trebuie numit
main().
Exemplul urmtor conine o singur funcie, funcia
main(). Ctre aceast funcie principal sistemul de
operare transfer controlul la lansarea n execuie a
programului.
Ex. 1
#include<stdio.h>
main()
{
printf ("Program in limbajul C!");
}
Dac sunt parcurse n mod corect etapele de
compilare i link-editare ale programului, la lansarea lui
n execuie va apare mesajul:
Program in limbajul C!
Acoladele { } ncadreaz o construcie (instruciune
compus sau bloc) alctuit din declaraii i
instruciuni aa cum este cazul corpului unei funcii.

2.2 Variabile. Tipuri de variabile. Declarare
Limbajul C permite utilizarea de variabile (nume
simbolice) pentru memorarea datelor, calculelor sau
rezultatelor.
n cadrul programelor C este obligatorie declararea
variabilelor, care const n precizarea tipului variabilei.
n urma declaraiei, variabila determin compilatorul
s-i aloce un spaiu corespunztor de memorie.
n limbajul C exist cinci tipuri de variabile:
- caracter: char,
- ntreg: int,
- real n virgula mobil n simpl precizie: float,
- real n virgula mobil n dubl precizie: double i
- tip de variabil neprecizat sau inexistent: void
Primele 4 tipuri aritmetice de baz pot fi extinse cu
ajutorul unor declaraii suplimentare, cum ar fi:
- signed (cu semn)
- unsigned (fr semn)
- long (lung)
- short (scurt).
Un exemplu de set de tipuri de variabile obinut cu
ajutorul acestor declaraii este prezentat n Tab.1.
Exemple de declaraii de variabile:
int i, j, k;
double val, set;
unsigned int m;

Programul urmtor utilizeaz declaraii multiple de
variabile:

Ex. 2
#include<stdio.h>
main()
{
int nr;
char ev;
float timp;
nr=5;
ev = 'S';
timp = 11.30;
printf("Evenimentul %c are numrul %d ", ev, nr);
printf("si a avut loc la %f", timp);
}

n urma execuiei acestui program se va afia:

Evenimentul S are numrul 5 i a avut loc la
11.300000
Limbaje de programare Elemente generale ale limbajului C
2
2.3 Funcia printf( )
Funcia printf() permite afiarea textului aflat ntre
ghilimele precum i valori ale diferitelor variabile din
program, utiliznd anumite notaii denumite
specificatori de format care realizeaz conversia datelor
ntr-o form adecvat pentru afiare.
Prototipul funciei printf() se gsete n fiierul antet
stdio.h i de aceea este nevoie de declaraia
preprocesor: #include<stdio.h> la nceputul fiecrui
program care folosete aceast funcie.
Formatele specifice utilizate de funcia printf() sunt:
%c pentru afiarea unui singur caracter;
%s pentru afiarea unui ir de caractere;
%d pentru afiarea unui numr ntreg (n baza zece)
cu semn;
%i pentru afiarea unui numr ntreg (n baza zece)
cu semn ;
%u pentru afiarea unui numr ntreg (n baza zece)
fr semn;
%f pentru afiarea unui numr real (notaie
zecimal);
%e pentru afiarea unui numr real (notaie
exponenial);
%g pentru afiarea unui numr real (cea mai scurt
reprezentare dintre %f si %e);
%x pentru afiarea unui numr hexazecimal ntreg
fr semn;
%o pentru afiarea unui numr octal ntreg fr
semn
%p pentru afiarea unui pointer (a unei adrese);
n plus se pot folosi urmtoarele prefixe:
l cu d, i, u, x, o permite afiarea unei date de tip long

l cu f, e, g permite afiarea unei date de tip double
h cu d, i, u, x, o permite afiarea unei date de tip
short
L cu f, e, g permite afiarea unei date de tip long
double.
Exemple:
%ld - permite afiarea unei date de tip long int
%hu - permite afiarea unei date de tip short unsigned
int
n exemplul 2 afiarea valorii reale s-a realizat cu
ase zecimale i nu cu dou conform operaiei de
atribuire iniiale a acestei variabile. Pentru afiarea
corect, formatul de scriere %f trebuie nsoit de o
notaie suplimentar care specific dimensiunea
cmpului de afiare a datelor i precizia de afiare a
acestora. Aceast notaie suplimentar se introduce ntre
simbolul % i simbolul f i are forma general
%-m.nf cu m i n numere ntregi avnd urmtoarele
semnificaii:
semnul -, n cazul n care este folosit,
realizeaz alinierea la stnga a informaiei
afiate n cadrul cmpului de afiare; n lipsa
acestuia, implicit alinierea se face la dreapta.
m precizeaz dimensiunea cmpului de afiare
(numrul de coloane)
.n reprezint numrul de digii din partea
zecimal (precizia de afiare a numrului)
Astfel, n exemplul 2, dac n locul specificaiei de
format %f am fi trecut %5.2f, la consol ar fi aprut
mesajul:
Evenimentul S are numrul 5 i a avut loc la 11.30

Tab.1 Tipuri de variabile n limbajul C
Tip Spaiul
(bii)
Domeniul de valori
char 8 - 128127
unsigned char 8 0255
signed char 8 -128 127
int 16 - 3276832767
unsigned int 16 065535
signed int 16 - 32768 32767
short int 16 - 3276832767
unsigned short int 16 065535
signed short int 16 - 3276832767
long int 32 -2.147.483.648 2.147.483.647
signed long int 32 -2.147.483.648 2.147.483.617
unsigned long int 32 04.294.967.295
float 32 10
-37
10
37
(6 digiti precizie)
double 64 10
-308
10
308
(10 digiti precizie)
long double 80 10
-4932
10
4932
(15 digiti precizie)
Limbaje de programare Elemente generale ale limbajului C
3

Ex. 3
#include<stdio.h>
main()
{
float valoare;
valoare = 20.13301;
printf ("%8.1f%8.1f\n, 22.5,425.7);
printf ("% -8.1f % -8.1f\n.", 22.5,425.7);
printf ("%f\n",valoare);
printf ("%5.2f\n", valoare);
printf (" %012f\n", valoare) ;
printf ("%10f\n

, valoare);
}
n urma executrii programului din ex.3, va rezulta:

2 2 . 5 4 2 5 . 7
2 2 . 5 4 2 5 . 7
2 0 . 1 3 3 0 1 1
2 0 . 1 3
2 0 . 1 3
0 0 0 2 0 . 1 3 3 0 1 1
2 0 . 1 3 3 0 1 1

Se observ c prezena unui zero naintea numrului
care specific dimensiunea cmpului de scriere
determin la afiare umplerea cu zero a spaiilor goale.

2.4. Secvene de evitare (escape)
n exemplul 3, caracterul "\n" inserat n irul de
caractere din apelul funciei printf() a determinat
afiarea pe o linie nou (carriage return-linefeed).
Acest caracter este un exemplu de secven escape,
numit aa deoarece simbolul (\) backslash este
considerat caracter escape, care determin o abatere de
la interpretarea normal a irului. Aceste secvene
escape sunt:
\a beep alarm-sonor;
\b backspace spaiu napoi;
\f formfeed linie nou, dar pe coloana urmtoare
celei curente;
\n newline determin trecerea la linie nou, pe
prima coloan;
\r carriage return determin revenirea la nceputul
liniei;
\t tab determin saltul cursorului din 8 in 8 coloane;
\\ backslash ;
\' apostrof simplu;
\" ghilimele;
\0 null ;
\ddd valoare caracter n notaie octal
(fiecare d reprezint un digit);
\xdd valoare caracter n notaie hexazecimal;

2.5. Funcia scanf()
O alt funcie des utilizat a limbajului C este
funcia de introducere a datelor scanf(). n mod similar
cu printf(), apelul funciei scanf() implic utilizarea
unui ir de caractere de control urmate de o list de
argumente. Dar, n timp ce printf() utilizeaz nume de
variabile, constante i expresii, scanf() utilizeaz
pointeri la variabile.
Exemplul 4 este o variant a programului din
exemplul 2 n care, n plus, se utilizeaz funcia scanf().

Ex. 4
#include<stdio.h>
main()
{
int nr;
char ev;
float timp;
printf ("Introducei pozitia, evenimentul, timp:");
scanf ("%c %d %f", &ev, &nr, &timp);
printf ("Evenimentul %c are numrul %d ", ev, nr);
printf (" i a avut loc la %5.2f", timp);
}

Execuia programului poate fi:
Introducei pozitia, evenimentul i timpul: A 6 11.30
Evenimentul A are numrul 6 i a avut loc la 11.30

Valorile variabilelor ev, nr i timp au fost introduse
de la tastatur. Pentru separarea lor a fost utilizat spaiu
(blank). Putea fi folosit return sau tab; orice alt
separator (linie, virgula) nu realizeaz aceast separare.

3. Problem rezolvat

3.1 S se scrie un program care permite aflarea
codului numeric al unei taste n zecimal, hexa si octal.

#include<stdio.h>
#include<conio.h>
void main(void)
{char caracter;
clrscr();
printf("Acest program afiseaza codul unei taste in
zecimal, hexa si octal.\n");
printf("Apasati o tasta:");
scanf("%c",&caracter);
printf("Codul tastei \%c\ este %d (in decimal),
%x (in hexa), %o (in octal)\n", caracter, caracter,
caracter, caracter);
getch();
}

4. Chestiuni de studiat
4.1 Studierea noiunilor teoretice i a exemplelor
prezentate.
4.2 Studierea problemelor rezolvate i identificarea
elementelor de limbaj i a algoritmilor utilizai.

Limbaje de programare Pointeri n limbajul C
1

Lucrarea nr. 3


POINTERI N LIMBAJUL C




1. Scopul lucrrii
Lucrarea are ca scop prezentarea utilizrii variabilelor pointer n limbajul C.

2. Noiuni teoretice

2.1 Declararea variabilelor pointer

Variabilele pointer (indicator) reprezint adrese
ale unor zone de memorie. Pointerii sunt utilizai
pentru a face referire la date cunoscute, prin
adresele lor. Puterea i flexibilitate n utilizarea
pointerilor, specific limbajului C, reprezint un
avantaj fa de celelalte limbaje (de ex. Pascal).
Exist 2 categorii de pointeri:
pointeri de date (obiecte) care conin adrese
ale unor variabile sau constante din
memorie;
pointeri de funcii care conin adresa
codului executabil al unei funcii.
n plus, exist i pointeri de tip void (o a treia
categorie), care pot conine adresa unui obiect
oarecare.
Declararea unui pointer de date se face cu
sintaxa:
tip *var_ptr;

Prezena caracterului * definete variabila
var_ptr ca fiind de tip pointer, n timp ce tip este
tipul obiectelor a cror adres o va conine (numit
i tipul de baz al variabilei pointer var_ptr).
Pentru pointerii de tip void se folosete
declaraia:
void * v_ptr;

Exemplul urmtor conine un set de declaraii
de variabile pointer:
Ex.1:

int *iptr;
float *fptr, val;
void *v_adr;
int * tabptr [10];
float ** dptr;



n aceast secven de program, variabila iptr
este un pointer de obiecte int, iar variabila fptr un
pointer de obiecte float. Tot aici, tabptr este un
tablou de 10 pointeri de tip int, iar dptr va putea
conine adresa unui pointer de obiecte float (se
realizeaz o dubl indirectare, pointer la pointer).
Deoarece, la compilare sau n timpul execuiei
programului nu se fac verificri ale validitii
valorilor pointerilor, orice variabil pointer trebuie
iniializat cu o valoare valid, 0 sau adresa unui
obiect sau a unei funcii, nainte de a fi utilizat.
Iniializarea cu valoarea 0 a unei variabile
pointer indic faptul ca aceasta nu conine adresa
unui obiect sau a unei funcii. Uzual, n aceste
cazuri, se folosete pentru atribuire identificatorul
NULL(=0), care este declarat n fiierele antet
(stdio.h, stdlib.h etc.).
Utilizarea variabilelor pointer implic folosirea
a doi operatori unari: operatorul & ce permite
aflarea adresei unei variabile oarecare i
operatorul * care permite accesul la variabila
adresat de un pointer.
Astfel, n cazul unei variabile var de tipul tip,
expresia:
&var se citete: adresa variabilei var
iar rezultatul este un pointer de obiecte tip i are
valoarea adresei obiectului var.
n cazul unei variabile pointer de obiecte tip,
numit ptr, expresia:
*ptr se citete: la adresa ptr
iar rezultatul este de tipul tip i reprezint obiectul
adresat de variabila pointer ptr. Expresia *ptr
poate fi utilizat att pentru a aflarea valorii
obiectului, dar i n cadrul unei operaii de
atribuire.
Limbaje de programare Pointeri n limbajul C
2
Utilizarea acestor operatori este prezentat n
exemplul urmtor, n care, pentru afiarea adreselor
n hexazecimal se folosete funcia printf()
mpreun cu specificatorul de format %p:

Ex.2:
#include <stdio.h>
void main(void)
{
int var=5, *ptr;
printf(\n Variabila var se afl la adresa:%p,
&var);
printf(\n i are valoarea var=%d,var);
ptr=&var;
printf(\n Variabila ptr are valoarea:%p, ptr);
printf(\n i conine adresa obiectului: %d,*ptr);
*ptr=10;
printf(\nAcum, variabila var are valoarea
%d\n,var);
}

n urma execuiei programului se afieaz:

Variabila var se afl la adresa: 1A56
i are valoarea var=5
Variabila ptr are valoarea: 1A56
i conine adresa obiectului: 5
Acum, variabila var are valoarea 10

n urma operaiei de atribuire ptr=&var,
variabila pointer ptr preia adresa variabilei var,
astfel nct cele dou obiecte *iptr i var devin
identice, reprezentnd un ntreg cu valoarea 5 de la
adresa 1A56. n aceste condiii, expresia *ptr
poate fi folosit n locul variabilei var, cu efecte
identice. De aceea, atribuirea *ptr=10 are ca efect
modificarea valorii variabilei var din 5 n 10.

2.2 Operaii arimetice cu pointeri

Operaiile aritmetice ce se pot efectua cu
pointeri sunt: compararea, adunarea i scderea.
Aceste operaii sunt supuse unor reguli i restricii
specifice. n cazul n care tipurile asociate
operanzilor pointer nu sunt identice, pot apare
erori, care nu sunt ntotdeauna semnalate de
compilator. n acest sens, se recomand conversia
de tip explicit cu operatorul cast, de forma (tip*).
Operatorii relaionali permit compararea
valorilor a doi pointeri:
..
int *ptr1,*ptr2;
if(ptr1<ptr2)
printf(ptr1=%p <ptr2=%p,ptr1,ptr2);

n multe situaii este necesar compararea unui
pointer cu 0, pentru a verifica dac adreseaz sau
nu un obiect:
..
if(ptr1==NULL)/* ptr1 este un pointer nul*/
else /* ptr1 este un pointer nenul*/
..
sau, sub forma:

if(!ptr1) /* ptr1 este un pointer nul*/
else /* ptr1 este un pointer nenul*/

Pot fi efectuate operaii de adunare sau de
scdere ntre un pointer de obiecte i un ntreg.
Deoarece un pointer este o valoare care indic o
anumit locaie din memorie, dac adugm
numrul 1 acestei valori, pointerul va indica
urmtoarea locaie din memorie. Deci, n cadrul
acestor operaii intervine i tipul variabilei.
Regula dup care se efectueaz aceste operaii
este urmtoarea:
n cazul unei variabile pointer ptr:
tip *ptr;
operaiile aritmetice:
ptr+n i ptr-n
corespund adugrii/scderii la adresa ptr a valorii
n*sizeof(tip).

De exemplu:
..
int *ip; /* sizeof(int)=2 */
float *fp; /* sizeof(float)=4 */
double *dp1, *dp2; /* sizeof(double)=8 */
.
dp2=dp1+5; /* dp2<-- adresa_dp1+5*8 */
fp=fp-2; /* fp<-- adresa_fp-2*4 */
ip++; /* ip<-- adresa_ip+1*2 */
dp1--; /* dp<-- adresa_dp-1*8 */

n acelai context, se poate efectua scderea a
doi pointeri de obiecte de acelai tip, avnd ca
rezultat o valoare ntreag ce reprezint raportul
dintre diferena celor dou adrese i dimensiunea
tipului de baz, ca n exemplul:

int i;
float *fp1,*fp2; /*sizeof(float)=4*/
i=fp2-fp1;
/*i=(adresa_fp2-adresa_fp1)/sizeof(float)*/
Limbaje de programare Pointeri n limbajul C
3
Avnd n vedere importana tipului pointerilor
n cadrul operaiilor de adunare i scdere,
operanzii nu pot fi pointeri de funcii sau pointeri
void.

2.3 Variabile dinamice

Pentru tipurile de date la care se cunoate
dimensiunea zonei de memorie necesar, aceasta
este fixat n urma declaraiei, naintea lansrii n
execuie a programului.
n cazul structurilor de date a cror dimensiune
nu este cunoscut sau se modific n timpul
execuiei programului, este necesar o alocare prin
program a memoriei, n timpul execuiei. Memoria
alocat este folosit, iar atunci cnd nu mai este
util, se elibereaz tot n timpul execuiei
programului.
Variabilele create astfel se numesc dinamice.
Prototipurile funciilor utilizate pentru alocarea
i eliberarea memoriei n timpul execuiei
programului se afl n fiierele alloc.h i stdlib.h.
O funcie des utilizat pentru alocarea dinamic
a memoriei este malloc() i are prototipul:

void*malloc(unsigned nr_octei);

Prin parametrul funciei malloc() se precizeaz
dimensiunea n octei a zonei de memorie
solicitate. Dac operaia de alocare reuete,
funcia ntoarce un pointer care conine adresa
primului octet al zonei de memorie alocate. n caz
contrar (spaiul disponibil este insuficient)
pointerul rezultat este NULL (=0).
Pentru o bun portabilitate a programelor, este
recomandabil, n apelul funciei malloc(), s se
utilizeze operatorii cast (pentru conversie de tip la
atribuire) i sizeof (pentru precizarea dimensiunii
zonei solicitate).
De exemplu, dac se dorete alocarea unei zone
de memorie pentru 10 valori de tipul float, se poate
proceda astfel:
.
float *fp;
fp=(float*)malloc(10*sizeof(float));
.
Eliberarea memoriei (rezultate n urma unei
alocri dinamice) se face atunci cnd variabila
dinamic nu mai este util, iar spaiul alocat poate
fi refolosit. n acest caz se poate folosi funcia
free() care are prototipul:

void free(void*ptr);

Parametrul funciei free() este un pointer ce
conine adresa zonei care trebuie eliberat i care
obligatoriu este rezultatul unui apel al unei funcii
de alocare dinamic (de tip malloc()).
Astfel, zona alocat anterior poate fi eliberat
prin apelul:
.
free(fp);
.
Zona de memorie alocat astfel este echivalent
cu un tablou. Elementele acestuia pot fi referite
indexat. De exemplu fp[5] este obiectul float de la
adresa fp+5.

3. Problem rezolvat
3.1 Acest program exemplific regulile specifice
operaiilor aritmetice cu pointeri.

#include <stdio.h>
void main(void)
{
int a=5,b=10, *iptr1, *iptr2,i;
float m=7.3, *fptr;
iptr1=&a;iptr2=&b;
fptr=&m;
printf("\n fptr=%u, *fptr=%2.1f, &fptr=%u", fptr,
*fptr, &fptr);
fptr++;printf("\n Incrementare fptr:");
printf("\n fptr=%u, *fptr=%2.1f, &fptr=%u", fptr,
*fptr, &fptr);
printf("\n iptr1=%u, *iptr1=%d, iptr2=%u,
*iptr2=%d", iptr1, *iptr1, iptr2,*iptr2);
i=iptr1-iptr2;
printf("\n Diferenta pointerilor iptr1 si iptr2
este=%d",i);
iptr2=iptr1+8;
printf("\n iptr1=%u, *iptr1=%d, iptr2=%u,
*iptr2=%d", iptr1, *iptr1,iptr2,*iptr2);
}

4. Chestiuni de studiat
4.1 Studierea i nsuirea noiunilor teoretice i
a exemplelor prezentate.
4.2 Identificarea elementelor de limbaj i a
algoritmilor utilizai.



Limbaje de programare Tablouri i pointeri n limbajul C
1

Lucrarea nr. 4


TABLOURI I POINTERI N LIMBAJUL C



1. Scopul lucrrii
Lucrarea are ca scop prezentarea legturii dintre tablouri i pointeri n limbajul C


2. Noiuni teoretice

2.1 Tablouri i iruri de caractere

Un tablou este o structur omogen, format
dintr-un numr finit de elemente de acelai tip
denumit tipul de baz al tabloului. Sintaxa de baz
n declararea unui tablou este:

tip nume_tablou[nr_elem]={val_initiala.};

De exemplu:

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

definete un tablou de 5 valori de tip int i
realizeaz iniializarea acestuia cu valorile din
interiorul acoladelor.
Pentru identificarea unui element al unui tablou
se folosete numele tabloului i indexul (poziia
elementului n tablou). Valorile pe care le poate lua
indexul pleac de la 0, ultimul element avnd
indexul nr_elem-1:
Astfel, n exemplul precedent, tab[0] este
primul element al tabloului i are valoarea 5.
Limbajul C nu are un tip de date special pentru
iruri de caractere, dar permite folosirea tablourilor
unidimensionale de tip caracter (char). Sintaxa de
declarare este:

char nume_sir [nr_elem];

Pentru a marca sfritul unui ir cu n elemente,
dup ultimul caracter, compilatorul rezerv n+1
locaii de memorie, pe ultima poziie adugnd un
octet cu valoarea 0 (caracterul \0). Astfel, acest
terminator \0 permite testarea sfritului irului.
n biblioteca limbajului C exist un set de
funcii dedicate operaiilor cu iruri.


Astfel, n fiierul stdio.h sunt declarate:
- funcia gets(sir_dest) care citete caractere
introduse de la tastatura i le transfer n irul
sir_dest i
- funcia puts(sir) care afieaz irul ir pe
ecran ,
iar, n fiierul string.h, se gsesc cteva funcii ce
realizeaz operaii uzuale cu iruri, cum ar fi:
- funcia strcpy(sir_dest,sir_sursa) care
copiaz irul sir_sursa n irul sir_dest,
- funcia strcat(sir1, sir2) care adaug irul sir2
la sfritul irului sir1 (concatenare) i
- funcia strlen(sir) care returneaz numrul de
elemente al irului sir.
- funcia strcmp(sir1,sir2) care compar
succesiv caracterele celor 2 iruri. Dac irurile
sunt identice returneaz valoarea 0, iar dac difer,
o valoare nenul.

Utilizare acestor funcii este prezentat n
exemplul urmtor, care testeaz introducerea
parolei corecte next:

#include <stdio.h>
#include <string.h>
#include<process.h>
void main(void) {
char sir[20], parola[10];
strcpy(parola,next);
puts(Introduceti parola:);
gets(sir);
if (strcmp(sir, parola)) {
puts(Incorect);
exit(1); /*iesire din program */
}
else puts(Corect!);
/*si se poate executa in continuare programul
*/
}

Limbaje de programare Tablouri i pointeri n limbajul C
2
n cazul tablourilor unidimensionale, se poate
omite dimensiunea la declaraie. n aceast situaie,
dimensiunea zonei de memorie alocate este fixat
de compilator pe baza listei de constante utilizate la
iniializare.
n cazul tablourilor mari, nu mai este necesar
numrarea elementelor, ca n declaraia:

char sir[]=Nu mai este nevoie de dimensiunea
sirului;

2.2 Tablouri i pointeri

Numele unui tablou fr index este echivalent
cu un pointer constant de tipul elementelor
tabloului, avnd ca valoare adresa primului
element din tablou. Totui, n timp ce unei
variabile de tip pointer i se atribuie valori la
execuie, nu este posibil i pentru numele unui
tablou, care va avea mereu ca valoare adresa
primului element. De aceea se spune c numele
unui tablou este un pointer constant.
De exemplu, dup declaraiile:
..
float ftab[10],*fptr;
int i;
.
se poate face atribuirea:
fptr=ftab;
n urma creia variabila pointer fptr va avea adresa
primului element al tabloului ftab. Exist de
asemenea urmtoarele echivalene:

1. &ftab[0] <= => ftab
2. &ftab[1] <= => ftab+1
3. &ftab[i] <= => ftab+i
4. ftab[0] <= => *ftab
5. ftab[4] <= => *(ftab+4)
6. fptr+i <= => fptr[i]

Pe baza acestor egaliti se poate calcula expresia:

(&ftab[i]-ftab)= = ftab+i- ftab==i

Chiar dac conine adresa primului element,
numele tabloului (fr index) refer ntregul tablou,
astfel c n exemplul nostru sizeof(ftab) va avea
valoarea 40 (10 elemente de 4 octei fiecare).
n cazul tablourilor multidimensionale,
deoarece reprezint tablouri cu elemente tablouri,
numele unui astfel de tablou (fr index) este un
pointer de tablouri.
n exemplul:
..
float fmat [10][10];
float *fp;
fp=mat;
..
atribuirea fp=mat; este incorect, deoarece mat
este pointer de tablouri float cu 10 elemente i nu
un pointer float.
Astfel, mat refer prima linie a matricii
identificat prin mat[0], iar mat[0] refer primul
element al matricii mat[0][0]. Pot fi scrise
echivalenele:

1. &mat[0] <= => mat
2. &mat[0][0] <= => mat[0]
3. mat[0][0] <= => *mat[0] <= => **mat
4. *(mat+i) <= => mat[i] <= =>&mat[i][0]
5. *(*(mat+1)+5)<==>*(mat[1]+5)<==>mat[1][5]

n general este valabil echivalena:
mat[i][j] <= =>*(*(mat+i)+j)


3. Probleme rezolvate

3.1 Acest program ncarc tabloul t1 cu
numerele 1.10 i apoi copiaz coninutul lui t1 n
tabloul t2:

PROGRAMUL 3.1

#include <stdio.h>
main ( )
{
int t1 [10] ,t2[10];
int i;
for (i=1;i<11;i++) t1[i-1] = i;
for (i=0;i<10;i++) t2[i] =t1[i];
for (i=0;i<10;i++)
printf(%d ,t2[i] );
}

3.2 Acest program calculeaz urma unei matrice
ptrate (suma elementelor de pe diagonala
principal) utiliznd variabile pointer pentru
adresarea elementelor matricei. Aceste variabile
pointer sunt iniializat (pentru fiecare linie) cu
adresa de nceput a liniei respective.

Limbaje de programare Tablouri i pointeri n limbajul C
3
PROGRAMUL 3.2

#include <stdio.h>
#include <conio.h>
main ( )
{
int mat[10][10];
int s=0, *ptr,n,i,j;
printf("Dati dimensiunea matricei patrate:");
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("mat[%d][%d]=",i+1,j+1);
scanf("%d",&mat[i][j]);
}
for(i=0;i<n;i++)
{
ptr=mat[i];
s=s+*(ptr+i);
}
printf("Suma=%d\n",s);
}

3.3 Acest program numr spaiile dintr-un ir
introdus de la tastatura de ctre utilizator. Este
testat fiecare caracter, iar dac acesta nu este
spaiu, instruciunea continue foreaz reluarea
ciclului for. n cazul n care este gsit un spaiu,
valoarea variabilei spaiu este incrementat.
Parcurgerea irului se realizeaz prin
incrementarea variabilei str de tip pointer la un ir
de caractere



















PROGRAMUL 3.3

#include <stdio.h>
void main (void)
{
char sir[80], *str;
int spatiu;
printf("Introduceti un sir: ");
gets(sir);
str = sir;
for (spatiu=0; *str; str++)
{
if (*str != ' ') continue;
spatiu++;
}
printf("Sirul contine %d spatii \n",spatiu);
}

4. Chestiuni de studiat
4.1 Studierea noiunilor teoretice i a
exemplelor prezentate.
4.2 Studierea problemelor rezolvate i
identificarea elementelor de limbaj i a
algoritmilor utilizai.
Limbaje de programare Funcii in limbajul C
1


Lucrarea nr. 5



FUNCII N LIMBAJUL C




1. Scopul lucrrii
Lucrarea are ca scop prezentarea funciilor n limbajul C.

2. Noiuni teoretice

n general, un program C este alctuit din una
sau mai multe funcii. ntotdeauna exist cel puin
o funcie, funcia main() care este apelat la
lansarea n execuie a programului.
Sintaxa general a definirii unei funcii este :

tip_fct nume_fct(list_declaraii_parametrii)
{
<lista_declaraii_locale>
list_instruciuni
}

tip_fct este tipul rezultatului returnat de funcie.
Dac o funcie nu ntoarce un rezultat, tipul
folosit este void.
n exemplul urmtor funcia max primete doi
parametrii de tip float i afieaz valoarea maxim
i media acestora. Deoarece funcia nu ntoarce
niciun rezultat, tipul su este void:
Ex.1:
.
void max(float a1,float a2)
{
float maxim; /* declaratie local */
if(a1>a2) maxim=a1;
else maxim=a2;
printf
(Maxim=%f;Medie=%f\n,maxim,(a1+a2)/2);
a1=7.5;
}
main()
{
float r;

max(r,4.53); /*apel al functiei afmax*/
}




Formatul general al apelului unei funcii este:
nume_fct (param1, param2)
Numim parametrii formali identificatorii din
lista_declaraii_parametrii din definiia funciei
i parametrii efectivi acele variabile, constante
sau expresii din lista unui apel al funciei.
Se observ ca parametrii formali reprezint
variabilele locale ale funciei. Timpul lor de via
corespunde duratei de execuie a funciei.
Transmiterea parametrilor (n urma unui apel al
funciei) se realizeaz prin ncrcarea valorii
parametrilor efectivi n zona de memorie a
parametrilor formali. Acest procedeu se numete
transfer prin valoare.
n cazul n care parametrul efectiv este o
variabil, operaiile efectuate n cadrul funciei
asupra parametrului formal nu o afecteaz. n Ex.1,
atribuirea a1=7.5 din finalul funciei nu modific
valoarea variabilei r din apelul max(r,4.53); .
Dac se dorete modificarea valorii unei
variabile indicate ca parametru efectiv ntr-o
funcie, trebuie ca parametrul formal s fie de tip
pointer. La apelare, trebuie s i se ofere explicit
adresa unei variabile. Acest procedeu se numete
transfer prin referin.
n cazul transferului prin referin, modificarea
realizat de funcie asupra parametrilor efectivi
este valabil att n interiorul ct i n exteriorul
funciei.
Atunci cnd se dorete ca funcia s returneze
un rezultat se folosete instruciunea return cu
sintaxa:
return (expresie)
Valoarea expresiei este rezultatul ntors de
funcie, iar parantezele sunt opionale.



Limbaje de programare Funcii in limbajul C
2
3. Probleme rezolvate
3.1 Urmtorul program creeaz i
implementeaz o funcie care caut un caracter
ntr-un ir i returneaz toate poziiile pe care
acesta este gsit. Poziiile returnate sunt grupate
ntr-un tablou, deoarece rezultatul funciei este de
tip pointer la ntreg.

#include<string.h>
#include<stdio.h>
#include<conio.h>
#include<alloc.h> /*<malloc.h> ptr Visual C*/

int *find(char*sir,char caracter)
{
int*a,*b;
char*sir1;
sir1=sir;
a=(int*)malloc(strlen(sir));
b=a;
while(*sir1!='\0')
{
if(*sir1==caracter)
{
*a=(sir1-sir);
a++;
}
sir1++;
}
*a=-1;
return(b);
}
void main(void)
{
clrscr();
char *s="acesta este sirul care va fi analizat";
char car='a';
int *pozitia,i;
pozitia=find(s,car);
i=0;
while (pozitia[i] !=-1)
printf(" %d ", pozitia[i++]+1);
}









3.2 Urmtorul program calculeaz suma
elementelor unui vector utiliznd o funcie avnd
printre parametrii formali i o variabil pointer.

#include<stdio.h>
double fsuma(double *ptr, int n)
{
int i;
double sum=0;
for(i=0;i<n;i++)
sum=sum+*(ptr+i);
return sum;
}
main()
{
double tab[20],elem,suma;
int i,nr;
printf("Dati numarul de elemente al vectorului:");
scanf("%d",&nr);
for (i=0; i<nr;i++)
{
printf("Numar(%d)=",i+1);
scanf("%lf", &elem);
tab[i]=elem;
}
suma=fsuma(tab,nr);
printf("Suma elementelor vectorului este: %5.2lf",
suma);
}

4. Probleme propuse
4.1. S se implementeze o funcie care caut un
caracter ntr-un ir i returneaz de cte ori s-a
gsit caracterul.
4.2 S se implementeze o funcie care
calculeaz suma elementelor de pe diagonala
principal a unei matrice ptrate, utiliznd
variabile pointer pentru adresarea elementelor
matricei.

5. Chestiuni de studiat
5.1 Studierea noiunilor teoretice i a
exemplelor prezentate.
5.2 Studierea problemelor rezolvate i
identificarea elementelor de limbaj i a
algoritmilor utilizai.
5.3 Rezolvarea problemelor propuse

Limbaje de programare Structuri
1

Lucrarea nr.6



STRUCTURI



1. Scopul lucrrii
Lucrarea are ca scop prezentarea utilizrii tipurilor de date de tip structur n limbajul C.

2. Noiuni teoretice
Limbajul C permite utilizatorului s defineasc
noi tipuri de date pentru a avea o reprezentare mai
convenabil a informaiei. Exist posibilitatea
gruprii unor elemente, pentru a reprezenta date
complexe, cel mai des sub forma unor structuri.
Structura este o colecie de variabile ce pot fi
de tipuri diferite, grupate mpreun sub un singur
nume i memorat ntr-o zon continu de
memorie.
Sintaxa general de declarare a unei structuri
este:
struct nume_structura {
tip1 elem1;
tip2 elem2;

tipn elemn;
} lista_var_struct;
n care:
struct = cuvnt cheie asociat structurilor;
nume_structura = numele dat de utilizator
structurii;
tipi = tipul elementului elemi ;
lista_var_struct = lista variabilelor de tip
structur nume_structura definit anterior.
Elementele componente ale unei structuri se
numesc membrii sau cmpuri.
De exemplu un punct identificat prin
coordonatele sale x i y poate fi reprezentat prin
intermediul unei structuri cu dou cmpuri x i y
de tip float:
struct punct
{
float x;
float y;
}m,n;
iar m i n sunt dou variabile de tip structur
punct.
Referirea la un membru al unei structuri se face
cu ajutorul operatorului punct . plasat ntre
numele structurii i numele membrului, m.x fiind
abscisa punctului m.
Iniializarea unei variabile de tip structur se
poate face:
- prin iniializarea fiecrui membru al
structurii sau,
- global, prin enumerarea, ntre acolade, a
valorilor iniiale ale membrilor, n ordinea
n care apar n declaraie.
Pentru variabilele structur punct din exemplul
precedent se pot face iniializrile:
m.x=10.5;
m.y=m.x+7;
n={12.3, 34.5};

Pot fi definite i structuri ncuibate. De
exemplu, un dreptunghi poate fi definit prin dou
puncte ale unei diagonale:
struct dreptunghi {
struct punct pt1;
struct punct pt2;
};
struct dreptunghi d;
d.pt2.y=9.7;
n ultima atribuire, ordonata punctului pt2 al
dreptunghiului d primete valoarea 9.7.
De asemenea, pot fi declarate tablouri cu
elemente structuri:
struct punct sirpuncte[10];
Pentru acest ir de puncte, secvena:
sirpuncte[2].x=20;
atribuie abscisei celui de-al treilea punct valoarea
20.
Pot fi efectuate operaii de atribuire ntre
variabile de tip structur de acelai tip, care
echivaleaz cu atribuiri membru cu membru.
Pot fi definite i variabile pointer de tip
structur:
struct punct *pct;
pct=&sirpuncte[5];
Pentru accesul la un element al unei structuri
indicate de un pointer se utilizeaz operatorul de
selecie indirect:-> (sgeata):
pct->y=12.3;
Limbaje de programare Structuri
2
3. Probleme rezolvate
3.1 Se consider o grup de maxim 20 de
studeni identificai prin numele lor. Pentru fiecare
student se cunosc notele la cele patru examene din
sesiune. S se afieze toi studenii bursieri (a
cror medie este mai mare sau egal cu 8.5).

#include<stdio.h>
struct student
{
char nume[15];
int nota1;
int nota2;
int nota3;
int nota4;
} stud[20];
int i,n;
float medie;
void main (void)
{
printf(" Dati numarul de studenti: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf(" NUME=");
scanf("%s",stud[i].nume);
printf(" NOTA1=");
scanf("%d",&stud[i].nota1);
printf(" NOTA2=");
scanf("%d",&stud[i].nota2);
printf(" NOTA3=");
scanf("%d",&stud[i].nota3);
printf(" NOTA4=");
scanf("%d",&stud[i].nota4);
}
i=0;
while(i<n)
{
medie=(float)(stud[i].nota1+stud[i].nota2+
stud[i].nota3+ stud[i].nota4)/4;
if(medie>=8.5)
{
puts(stud[i].nume);
printf("%5.2f\n",medie);
}
i++;
}
}




3.2. Programul urmtor utilizeaz tipul structur
asociat crilor dintr-o bibliotec i face o selecie
dup anul apariiei.

#include<stdio.h>
#include<conio.h>
struct carte
{
char titlu[20];
char autor[20];
int an;
float pret;
};
void main(void)
{
struct carte bib[50];
int i,n=0;
clrscr();
printf("\n Dati numarul de carti:");
scanf("%d",&n);

for(i=0;i<n;i++)
{
printf(" Titlu=");
scanf("%s",bib[i].titlu);
printf(" Autor=");
scanf("%s",bib[i].autor);
printf(" Anul aparitiei=");
scanf("%d",&bib[i].an);
printf(" Pret=");
scanf("%f",&bib[i].pret);
}

printf("Carti editate nainte de revolutie:\n");
i=0;

while(i<n)
{
if(bib[i].an<=1989)
{

puts(bib[i].titlu);
puts(bib[i].autor);
printf("\n");
}
i++;
}
}




Limbaje de programare Structuri
3

4. Probleme propuse

4.1 Pentru o grup de studeni se cunosc numele
studenilor i 5 note obinute la sfritul
semestrului. Se cere s se afieze studenii care nu
au nici o restan.

4.2. S se foloseasc structuri de tip punct,
pentru a determina daca trei puncte A,B,C (date
prin coordonatele lor) pot forma un triunghi i de
ce tip (oarecare, isoscel, echilateral).

4.3 Folosind tipul complex ca o structur cu
dou cmpuri (parte real i parte imaginar), s
se simuleze operaiile asupra numerelor complexe:
adunare, scdere, nmulire, mprire, modul,
parte real i parte imaginar.



































5. Chestiuni de studiat

5.1 Studierea noiunilor teoretice i a
exemplelor prezentate.
5.2 Studierea problemelor rezolvate i
identificarea elementelor de limbaj i a
algoritmilor utilizai.
5.3 Rezolvarea problemelor propuse.

Limbaje de programare Liste
1

Lucrarea nr. 7

LISTE


1. Scopul lucrrii
Lucrarea are ca scop prezentarea listelor n limbajul C, punnd accentul pe reprezentarea acestora cu ajutorul
structurilor de date dinamice.


2. Noiuni teoretice
n anumite situaii este necesar organizarea
informaiilor sub forma unor liste. De exemplu lista
persoanelor dintr-o instituie, a produselor dintr-un
magazin etc.. Lista este deci compus din elemente de
acelai tip, iar informaia coninut n fiecare element al
listei este de multe ori complex.
Lista are un numr variabil de elemente i deci un
caracter dinamic. Astfel, la nceputul execuiei
programului, lista este goal urmnd ca aceasta s fie
completat i s i se aduc apoi modificri, tot prin
program.
Limbajul C permite implementarea listelor cu
ajutorul variabilelor dinamice de tip structur.
Utilizarea tablourilor pentru reprezentarea unor liste
este posibil, dar nu este eficient, deoarece listele au
un caracter dinamic spre deosebire de tablouri. De
aceea, practica uzual este de a ordona elementele unei
liste folosind variabile pointer care intr n componena
elementelor. Utilizarea acestor variabile pointer d un
caracter recursiv elementelor listei. Listele
implementate astfel se numesc nlnuite.
Elementele unei astfel de liste poart denumirea
uzual de noduri. Dac ntre noduri exist o singur
relaie de legtur lista se numete simplu nlnuit, iar
dac exist dou relaii de legtur lista se numete
dublu nlnuit.
Cele mai uzuale operaii care se pot efectua asupra
unei liste nlnuite sunt: crearea listei, accesul la un
nod, adugarea, tergerea sau modificarea unui element
i tergerea listei.

2.1. Liste simplu nlnuite
ntre nodurile unei liste simplu nlnuite exist o
singur relaie de legtur, de obicei de indicare a
succesorului unui element. Aceast legtur se
implementeaz cu ajutorul unui pointer ce memoreaz
adresa nodului urmtor din list.
De exemplu pentru o list de persoane simplu
nlnuit, la care se cunosc numele, prenumele i
vrsta, nodul are urmtoarea form:
struct nod {
char nume[15];
char prenume[15];
int varsta;
struct nod *urm;};
n aceast structur, cmpul urm va conine adresa
urmtorului nod din list. El este un pointer la o
variabil de tip structur identic cu cea din care face
parte. Pentru ultimul nod din list, variabila urm va
avea valoarea NULL, deoarece nu mai urmeaz un alt
nod. De asemenea, spre primul nod al listei nu
pointeaz nici un alt nod.
Cunoaterea primului i ultimului element al listei
este importan, deoarece permite accesul la orice
element prin parcurgerea listei (ncepnd cu primul) i
faciliteaz operaiile de adugare de elemente noi la
sfritul listei.
Atunci cnd trebuie adugat un element n list se
parcurg etapele:
1. se aloc dinamic spaiu pentru respectivul
element,
2. se creeaz elementul prin nscrierea
informaiilor corespunztoare i
3. se leag n list.
Cnd un element trebuie scos din list, se rup i se
refac legturile, iar spaiul ocupat de acesta se
elibereaz.

2.2.Liste dublu nlnuite
ntre nodurile unei liste dublu nlnuite vor exista
dou relaii de legtur, cu elementul anterior i cu
elementul urmtor. n acest caz, vor exista doi pointeri
de legtur ce memoreaz adresa nodului anterior i
respectiv a celui urmtor din list. Implementarea
exemplului precedent se va face, n cazul utilizrii
listelor dublu nlnuite, sub forma:

struct nod
{
char nume[15];
char prenume[15];
int varsta;
struct nod *ant;
struct nod *urm;
};

Adugarea unui element ntr-o list dublu nlnuit
va necesita aceleai etape ca n cazul listelor simplu
nlnuite. Funcia care realizeaz adugarea unui
element ntr-o list dublu nlnuit, al crui nod are
structura de mai sus, va avea urmtoarea form:
Limbaje de programare Liste
2
void adauga(char *Nume,char *Prenume,int Varsta)
{
struct nod *p;
p=(struct nod *)malloc(sizeof(struct nod));
if(p==NULL)
{
printf("Memorie insuficient.\n");
return;
}
strcpy(p->nume,Nume);
strcpy(p->prenume,Prenume);
p->varsta=Varsta;
p->urm=NULL;
ultim->urm=p;
p->ant=ultim;
ultim=p;
}

3. Problem rezolvat
S se creeze o list simplu nlnuit a persoanelor
dintr-o instituie n care s se memoreze numele,
prenumele i vrsta fiecruia. S se afieze persoanele
a cror vrst este mai mic de 40 de ani. Persoanele
care au vrsta de pensionare (65 de ani) vor fi
eliminate din list. Se va afia apoi lista persoanelor
rmase.

#include <stdio.h>
#include <string.h>
#include <alloc.h>
#include <conio.h>
struct nod {
char nume[15];
char prenume[15];
int varsta;
struct nod *urm;};
struct nod *prim,*ultim;

void adauga(char *Nume,char *Prenume,int Varsta)
{
struct nod *p;
p=(struct nod *)malloc(sizeof(struct nod));
if(p==NULL)
{
printf("Memorie insuficient.\n");
return;
}
strcpy(p->nume,Nume); strcpy(p->prenume,Prenume);
p->varsta=Varsta;
p->urm=NULL;
if(prim==NULL) prim=ultim=p;
else
{
ultim->urm=p;
ultim=p;
}
}
void sterge(struct nod *p)
{
struct nod *q;
if(!p) return;
if(prim==p)
{
prim=p->urm;
if(prim==NULL) ultim=NULL;
}
else {
for(q=prim;q->urm!=p&&q->urm!=NULL;q=q->urm)
if(q->urm==NULL)
{
printf("Elementul nu aparine listei.\n");
return;
}
q->urm=p->urm;
if(p==ultim) ultim=q;
}
free(p);
}
void main(void) {
char Nume[15],Prenume[15];
int Varsta;
int i,n;
struct nod *p,*q;
printf("Numrul de persoane:");scanf("%d",&n);
prim=ultim=NULL;
for(i=0;i<n;i++)
{
printf("Nume:");gets(Nume);
printf("Prenume:");gets(Prenume);
printf("Varsta:");scanf("%d",&Varsta);
adauga(Nume,Prenume,Varsta);
}
printf("Lista persoanelor sub 40 de ani :\n");
for(p=prim;p!=NULL;p=p->urm)
if(p->varsta <= 40) printf("%15s%15s - %d\n",
p->nume,p->prenume,p->varsta);
p=prim;
while(p!=NULL) {
if(p->varsta > 65)
{
q=p->urm;
sterge(p);
p=q;
}
else p=p->urm;
}
printf("Lista persoanelor ramase:\n");
for(p=prim;p!=NULL;p=p->urm)
printf("%15s%15s - %d\n",p->nume,p-> prenume,
p->varsta);
}



Limbaje de programare Liste
3
4. Probleme propuse
4.1 S se implementeze lista din problema rezolvat
3 cu ajutorul listelor dublu nlnuite.
4.2 S se creeze o list a studenilor prezeni la un
examen de admitere n care s se memoreze numele,
prenumele i media de admitere. S se afieze studenii
care primesc burs (cu media peste 9.50). Studenii cu
media de admitere sub 5.00 sunt considerai respini i
vor fi eliminai din list. Se va afia apoi lista
studenilor admii.















































5. Chestiuni de studiat
5.1 Studierea noiunilor teoretice i a exemplelor
prezentate.
5.2 Studierea problemelor rezolvate i identificarea
elementelor de limbaj i a algoritmilor utilizai.
5.3 Rezolvarea problemelor propuse













Limbaje de programare - Fiiere in limbajul C
1

Lucrarea nr.8


FIIERE IN LIMBAJUL C



1. Scopul lucrrii
Lucrarea are ca scop prezentarea utilizrii fiierelor n limbajul C.

2. Noiuni teoretice
Un fiier reprezint o colecie ordonat de
nregistrri. Majoritatea operaiilor de intrareieire se
bazeaz pe manipularea fiierelor. Datele introduse de
la tastatur formeaz un fiier de intrare, n timp ce
datele afiate pe display sau listate la imprimant
formeaz un fiier de ieire.
Exist dou tipuri de fiiere: text i binare. n timp
ce fiierele text conin caractere ASCII n gama 0-127
(informaie citibil), fiierele binare conin niruiri de
caractere, neinteligibile pentru utilizator. De exemplu,
fiierele surs sunt fiiere text, n timp ce fiierele
executabile sunt fiiere binare.
Prelucrarea unui fiier presupune o serie de operaii
precedate de deschiderea fiierului i finalizate cu
nchiderea acestuia.
n urma deschiderii unui fiier se genereaz un
pointer la o structur de tip FILE predeclarat n
stdio.h. Sintaxa de declarare a unui pointer la FILE
este: FILE*fptr;
fptr fiind numele variabilei pointer cu care se lucreaz
n continuare.
Deschiderea unui fiier se realizeaz cu funcia
fopen() cu sintaxa general:
FILE *fopen(const char*nume_fisier ,
const char *mod);
n care:
nume_fisier este numele fiierului care se va deschide
sau crea;
mod este modul n care este deschis fiierul:
r deschide fiierul pentru citire;
w deschide un fiier pentru scriere;
a deschide sau creeaz un fiier pentru scriere la
sfritul fiierului (adugare);
r+ deschide un fiier pentru actualizare
(citire + scriere);
w+ deschide un fiier pentru actualizare, coninutul
anterior se elimin;
a+ deschide un fiier pentru actualizare la sfrit.
Fiierele pot fi deschise n mod binar sau text, dup
cum este specificat n argumentul mod al funciei fopen
prin adugarea literei t pentru text sau b pentru binar.
Dac operaia de deschidere are succes, funcia
returneaz un pointer la FILE (pointer care va fi folosit
n continuare n operaiile asupra fiierului), iar dac
eueaz, fopen ntoarce valoarea NULL.

n exemplul urmtor:
FILE *fptr1, *fptr2;
fptr1=fopen(fist.txt,r+t);
fptr2=fopen(fisb.bin,wb);
sunt deschise dou fiiere: primul de tip text pentru
operaii de actualizare i cel de-al doilea de tip binar
pentru scriere.
nchiderea unui fiier se realizeaz cu funcia
fclose() avnd sintaxa general:
int fclose(FILE* fptr_fisier);
care va nchide fiierul specificat de fptr_fisier.
Funcia fclose() returneaz valoarea 0 n caz de
nchidere cu succes a fiierului i EOF dac a aprut o
eroare.
nchiderea fiierelor din exemplul precedent se va
face cu secvena:
fclose(fptr1);
fclose(fptr2);
Scrierea de date n fiier se realizeaz cu ajutorul
funciei fprintf():
int fprintf(FILE *fptr, const char *format,
arg1, arg2,,argn)
care scrie n fiierul pointat de fptr datele specificate de
arg1argn, n formatul specificat prin irul de
caractere format.
n exemplul:

FILE *fpt;
int i=5;
char c=B;
float f=2.7543;
fpt=fopen(fis.dat,w);
fprintf(fpt,%d,%c,%f,i,c,f);

prin utilizarea funciei fprintf(), se scriu n fiierul
fis.dat, descris de fpt, un ntreg, un caracter i o
variabil de tip float.
Citirea de date dintr-un fiier se realizeaz cu
ajutorul funciei fscanf():
int fscanf(FILE *fptr, const char *format,
arg1, arg2,,argn)
care citete din fiierul indicat de fptr date sub
controlul formatului specificat n format i le atribuie
variabilelor prin adresele specificate n arg1,
arg2,argn, care, de aceast dat, sunt pointeri.
Limbaje de programare - Fiiere in limbajul C
2
3. Problem rezolvat
S se creeze un fiier text ce conine informaii despre
produsele dintr-un magazin. S se scrie apoi o funcie de
adugare, apoi una de cutare n fiier dup nume i
modificarea numrului de buci . n final s se listeze
coninutul fiierului modificat.
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<process.h>
#define nf "produse.txt"
typedef struct {
char nume[10];
int nr;
float pret;
}prod;
FILE *fp;
void creare ()
{
if((fp=fopen(nf,"w"))==NULL)
{
printf("Eroare de creare\n");
exit(1);
}
fclose(fp);
}
void listare ()
{
prod s;
clrscr();
if((fp=fopen(nf,"r"))==NULL)
{
printf("Eroare de deschidere \n");
exit(1);
}
do
{
fread(&s,sizeof(prod),1,fp);
if(feof(fp)) break;
printf("\n%s",s.nume);
printf("\n%d",s.nr);
printf("\n%5.2f",s.pret);
}
while (!feof(fp));
fclose(fp);
}
void adaugare ()
{
char c;
prod s;
clrscr();
if((fp=fopen(nf,"a"))==NULL)
{
printf("Eroare de deschidere\n");
exit(1);
}
c='d';
while(c=='d')
{
printf("\n Nume:");
scanf("%s",s.nume);
printf("\nNumarul de bucati:");
scanf("%d",&(s.nr));
printf("\nPret: ");
scanf("%f",&(s.pret));
fwrite(&s,sizeof(prod),1,fp);
printf("\n\n Mai dorii adugare? (d/n): ");
c=getch();
}
fclose(fp);
}
void modificare()
{ prod s;
long int poz;
int gasit=0;
char n[10];
int nrnou;
printf("\n Dati numele dupa care se cauta: ");
scanf("%s",n);
printf("\n Dati noua cantitate: ");
scanf("%d",&nrnou);
if((fp=fopen(nf,"r+"))==NULL)
{
printf("Eroare de deschidere\n");
exit(1);
}
while((!gasit)&&(!feof(fp)))
{
poz=ftell(fp);
fread(&s,sizeof(prod),1,fp);
if(!strcmp(n,s.nume))
gasit++;
}
if(!gasit)
{
printf("\nNu s-a gasit inregistrarea ");
getch();
}
else
{
fseek(fp,poz,SEEK_SET);

fread(&s,sizeof(prod),1,fp);
s.nr=nrnou;
fseek(fp,poz,SEEK_SET);
fwrite(&s,sizeof(prod),1,fp);
}
fclose(fp);
}
void main()
{ creare();
adaugare();
listare();
modificare();
listare(); }
Limbaje de programare - Fiiere in limbajul C
3

4. Probleme propuse
4. 1. S se creeze i s se listeze un fiier binar cu
studeni, n care s se memoreze numele i dou note.
Datele se citesc dintr-un fiier text creat anterior.
4.2. S se scrie o procedur de creare a unui fiier
text ce conine nume de studeni i o alta de actualizare
prin adugare a acestui fiier. n final se va scrie o
procedur de listare a coninutului fiierului.

















































5. Chestiuni de studiat
5.1 Studierea noiunilor teoretice i a exemplelor
prezentate.
5.2 Studierea problemei rezolvate i identificarea
elementelor de limbaj i a algoritmilor utilizai.
5.3 Rezolvarea problemelor propuse


Limbaje de programare Rezolvarea ecuaiilor
1

Lucrarea nr. 9



REZOLVAREA ECUAIILOR

1. Scopul lucrrii
Lucrarea are ca scop prezentarea unei metode numerice de rezolvare a ecuaiilor algebrice i
transcendente cu ajutorul limbajului C++.


2. Noiuni teoretice
Exist mai multe metode numerice utilizate
pentru calculul rdcinilor reale ale unei ecuaii
algebrice: metoda biseciei, metoda poziiei false,
metoda aproximaiilor succesive, metoda lui
Newton, metoda lui Bairstow, etc..
Acestea sunt metode de calcul care presupun
utilizarea unor algoritmi numerici ce permit gsirea
rdcinilor. nainte de calculul propriu-zis al
rdcinilor (prin procedee iterative), trebuie
realizat o separarea a rdcinilor ce const n
gsirea acelor intervale care conin cel mult o
rdcin.

Metoda biseciei
Aceast metod mai este numit metoda
njumtirii intervalului sau metoda bipartiiei.
Metoda permite gsirea unei rdcini (cu o
anumit eroare ) a ecuaiei:
f(x)=0
n intervalul [a,b], unde f : [a,b] >R i f este
continu pe [a,b]. Se presupune c s-a realizat n
prealabil o separare a rdcinilor, astfel nct pe
intervalul [a,b] exist cel mult o rdcin .
Algoritmul ncepe prin analizarea urmtoarelor
patru situaii:
1. f(a)=0 i deci =a;
2. f(b)=0 i deci =b;
3. f(a)f(b)<0 i atunci aparine intervalului
(a,b)
4. f(a)f(b)>0 i atunci nu exist o rdcin n
intervalului [a,b].
Variantele 1,2 i 4 presupun ncheierea
procesului de gsire a rdcinii.
Algoritmul continu, n varianta 3, cu
njumtirea intervalului [a,b] i determinarea
valorii x
0
=(a+b)/2. Se verific dac x
0
este soluie a
ecuaiei, prin evaluarea |f(x
0
)| < . n caz contrar,
se alege semiintervalul [a
1
,b
1
] la capetele cruia
funcia are semne opuse (f(a
1
)f(b
1
)0) i se repet
paii de mai sus. Se obin intervale de tip [a
i
, b
i
] ca
fiind jumtate din intervalul [a
i-1
, b
i-1
] prin metoda
general:
x
i-1
=(a
i-1
+b
i-1
)/2;
a
i
=a
i-1
, b
i
=x
i-1
dac f(a
i-1
) f(x
i-1
)<0
a
i
=x
i-1
, b
i
=b
i-1
dac f(a
i-1
) f(x
i-1
)>0
Se obin astfel dou iruri convergente:
- irul a
n
al extremitilor stngi ale intervalelor,
care este monoton cresctor (a < a
1
< ... < a
n
)
- irul b
n
al extremitilor drepte ale intervalelor,
care este monoton descresctor (b > b
1
> ... > b
n
)
Se observ i c b
n
-a
n
=(b-a)/2
n
.
Aadar, a
n
i b
n
vor converge ambele ctre
soluia , deoarece exist o valoare n pentru care
|b
n
-a
n
| < , unde este eroarea impus pentru
calculul soluiei ecuaiei date. Se poate aproxima
soluia ecuaiei cu valoarea mijlocului intervalului
[a
n
, b
n
] .
n continuare, pe baza algoritmului prezentat, se
vor prezenta dou funcii n limbajul C++,
corespunztoare rezolvrii ecuaiilor algebrice i
respectiv transcendente.

Exemplul 1

int bisectiepol (double s, double d, int grad,
double coef[], double err, double *rad)
{
double xm ;
if(poly(s,grad,coef)*poly(d,grad,coef)>0) return 0;
if( poly (s,grad,coef) == 0 )
{
*rad=s;
return 1;
}
if(poly(d,grad,coef)==0)
{
*rad=d;
return 1;
}
xm=0.5*(s+d);
Limbaje de programare Rezolvarea ecuaiilor
2
while((fabs(d-s)>err) &&(poly(xm,grad,coef)!=0))
{
xm=0.5*(d+s);
if(poly(s,grad,coef)*poly(xm,grad,coef)<0)
d=xm;
else s=xm;
}
*rad=xm;
return 1;
}
n acest exemplu s i d reprezint limitele
stnga i respectiv dreapta ale intervalelor de lucru,
iar xm mijlocul acestora. Este utilizat funcia
matematic poly() din math.h, care permite aflarea
valorii unui polinom ntr-un punct (primul
parametru al funciei) cunoscndu-se gradul
polinomului (al doilea parametru) i vectorul
coeficienilor acestuia (al treilea parametru).
Funcia ntoarce valoarea 0 n cazul n care nu
este gsit o rdcin n intervalul specificat i
valoarea 1 n caz de succes, valoarea soluiei fiind
transferat n variabila *rad.


Exemplul 2.

int bisectiefct(double(*f)(double),double s,
double d, double err, double *rad)
{
double xm;
if(f(s)*f(d)>0) return 0;
if(f(s)==0)
{ *rad=s;
return 1;
}
if(f(d)==0)
{
*rad=d;
return 1;
}
xm=0.5*(s+d);
while( (fabs(d-s)>err)&&(f(xm)!=0) )
{
xm=0.5*(s+d);
if( f(s)*f(xm)<0) d=xm;
else s=xm;
}
*rad=xm;
return 1;
}
Implementarea acestei funcii s-a realizat n
mod asemntor cu funcia din exemplul 1. Primul
parametru al acestei funcii este un pointer ce
conine adresa funciei matematice pentru care se
caut soluiile.


3. Probleme rezolvate
3.1 S se afle dac ecuaia: x
3
-9x
2
+23x-15=0
are o rdcin n intervalul (-4.5,6), i s se afle
valoarea acesteia (n cazul n care exist) cu o
eroare de 0.000001.

#include<math.h>
#include<iostream.h>
int bisectiepol (double s, double d, int grad,
double coef[], double err, double *rad)
{
double xm ;
if(poly(s,grad,coef)*poly(d,grad,coef)>0) return 0;
if( poly (s,grad,coef) == 0 )
{
*rad=s;
return 1;
}
if(poly(d,grad,coef)==0)
{
*rad=d;
return 1;
}
xm=0.5*(s+d);
while((fabs(d-s)>err) &&(poly(xm,grad,coef)!=0))
{
xm=0.5*(d+s);
if(poly(s,grad,coef)*poly(xm,grad,coef)<0)
d=xm;
else s=xm;
}
*rad=xm;
return 1;
}

void main(void)
{
double *rad;
double f[]={-15,23,-9,1};
if (bisectiepol(4.5,6,3,f,0.000001,rad)==1)
{cout<<"Functia are o radacina in intervalul (4.5,6)
egala cu:";
cout<<*rad;}
else
cout<<"Functia nu are radacina in intervalul
specificat";
}
Limbaje de programare Rezolvarea ecuaiilor
3
3.2. S s afle soluia ecuaiei transcendente
0 e x
x


n intervalul (0.1,1), aplicnd metoda
biseciei cu o eroare de calcul de
0000000001 . 0

#include<math.h>
#include<iostream.h>
double fct(double x)
{
double val_fct;
val_fct=x-exp(-x);
return (val_fct);
}
int bisectiefct(double(*f)(double),double s,
double d, double err, double *rad)
{
double xm;
if(f(s)*f(d)>0) return 0;
if(f(s)==0)
{ *rad=s;
return 1;
}
if(f(d)==0)
{
*rad=d;
return 1;
}
xm=0.5*(s+d);
while( (fabs(d-s)>err)&&(f(xm)!=0) )
{
xm=0.5*(s+d);
if( f(s)*f(xm)<0) d=xm;
else s=xm;
}
*rad=xm;
return 1;
}

void main(void)
{
double s=0.1,d=1.0,err=0.00000001,*sol;
bisectiefct(fct,s,d,err,sol);
cout<<"Solutia ecuatiei f(x)=0 pe intervalul:
("<<s<<","<<d<<") este: "<<*sol;
}







4. Probleme propuse
4.1 S se afle dac ecuaia x
3
6x
2
+8x=0 are o
rdcin n intervalul (1,3), iar n caz afirmativ s
se gseasc aceast soluie.
4.2 S se gseasc o rdcin a ecuaiei
0 25 . 0 ) x sin( x n intervalul (1,2) cu o
precizie de 0.000001 .

5. Chestiuni de studiat
5.1 Studierea noiunilor teoretice i a
exemplelor prezentate.
5.2 Studierea problemelor rezolvate i
identificarea elementelor de limbaj i a
algoritmilor utilizai.
5.3 Rezolvarea problemelor propuse
Limbaje de programare Interpolarea funciilor
1

Lucrarea nr. 10



INTERPOLAREA FUNCIILOR

1. Scopul lucrrii
Lucrarea are ca scop prezentarea unei metode numerice de aproximare a funciilor tabelate i a
implementrii acesteia n limbajul C++.

2. Noiuni teoretice
Interpolarea reprezint o metod numeric de
aproximare a funciilor date sub form tabelar.
Avnd un set discret de date [x
i
,y
i
] (i=0,1,,n)
(obinut n urma unor experimente, msurtori
etc.), metoda presupune gsirea unei funcii f(x)
continu care s verifice y
i
=f(x
i
) (i=0,1,,n).
Funcia f(x) se numete funcie de interpolare, iar
punctele x
i
noduri ale reelei de interpolare.
Uzual, funcia de interpolare are o form simpl
pentru a permite cu uurin aflarea valorilor n
orice punct al domeniului de definiie i pentru a
putea fi uor prelucrat (derivat, integrat etc.).
De aceea, interpolarea este utilizat i n cadrul
metodelor numerice de derivare, integrare etc..
Calculul funciei f(x) pentru valori ale lui x
cuprinse ntre nodurile reelei de interpolare se
numete interpolare, iar dac x se afl n afara
reelei, extrapolare.

2.1 Interpolarea polinomial
Cea mai utilizat funcie de interpolare este
funcia polinomial. Interpolarea polinomial
presupune gsirea unui polinom P(x) care s
verifice:
P(x
i
)=y
i
,

i=0,1,,n (1)
Dac polinomul P(x) are expresia:
0 1
1 n
1 n
n
n
a x a ... x a x a ) x ( P + + + + =

(2)
condiiile din relaia (1) sunt echivalente cu:

= + + + +
= + + + +
= + + + +

n 0 n 1
1 n
n 1 n
n
n n
1 0 1 1
1 n
1 1 n
n
1 n
0 0 0 1
1 n
0 1 n
n
0 n
y a x a ... x a x a
....... .......... .......... .......... .......... ..........
y a x a ... x a x a
y a x a ... x a x a
(3)
Deoarece determinantul acestui sistem (de tip
Vandermonde):
[

>
=
=
1 n
i j
0 j , i
i j
) x x ( D (4)
este diferit de zero (nodurile x
i
sunt distincte),
sistemul va avea o soluie unic pentru coeficienii
a
0
, a
1
..a
n
i deci pentru polinomul de interpolare.
Se obine aa numitul polinomul de interpolare
al lui Lagrange, care are forma:
j i
i
n
i j , 0 j
n
0 i
i
x x
x x
y ) x ( P

=
H

= = =
(5)
Deci, cu ajutorul acestui polinom, se poate
calcula valoarea funciei n orice punct necunoscut
cuprins ntre x
0
si x
n.
Implementarea polinomului de interpolare
Lagrange se poate face cu funcia C++:

double lagrange(int n, float x[],
float y[],float point)
{
int i,j;
float sum=0, prod;
for(i=0; i<n; i++)
{
prod = 1;
for(j=0;j<n;j++)
if (j!=i)
prod*=(point-x[j])/(x[i]-x[j]);
sum+=y[i]*prod;
}
return sum;
}

n cazul n care reeaua de interpolare are doar
dou puncte, interpolarea devine liniar:
1 2
1
2
2 1
2
1
x x
x x
y
x x
x x
y y ) x ( f

= = (6)
Ultima egalitate din relaia (6) reprezint chiar
ecuaia unei drepte care trece prin punctele (x
1
,y
1
)
i (x
2
,y
2
).




Limbaje de programare Interpolarea funciilor
2

3. Problem rezolvat
n urma unor msurtori s-au obinut
urmtoarele date memorate n variabilele x i y:
x 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
y 7 14 17 20 22 25 26 28 29 30
Se cere s se determine puncte ntre nodurile
reelei de interpolare ( de exemplu pentru:
x=0.35 ; x=0.64 ; x=0.89)

#include<iostream.h>
double lagrange(int n, float x[],
float y[],float point)
{
int i,j;
float sum=0, prod;
for(i=0; i<n; i++)
{
prod = 1;
for(j=0;j<n;j++)
if (j!=i)
prod*=(point-x[j])/(x[i]-x[j]);
sum+=y[i]*prod;
}
return sum;
}

void main(void)
{
int n=10;
float val;
float x[]={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9};
float y[]={7,14,17,20,22,25,26,28,29,30};
float p=0.64;
val=lagrange(n,x,y,p);
cout<<"Valoarea functiei de interpolare in
punctul x="<<p<<" este: "<<val;
}
















4. Problem propus
Plecnd de la datele problemei rezolvate 3, s
se scrie un program care realizeaz interpolarea,
ns pentru un numr mai mic de noduri ale reelei
de interpolare. De exemplu, pentru 7 noduri alese
n mod diferit: uniform distribuit, mai multe n
prima parte sau mai multe n a doua parte. S se
compare rezultatele obinute pentru aflarea
valorilor funciei n punctele x=0.35, x=0.64 i
x=0.89 . S se comenteze rezultatele obinute.

5. Chestiuni de studiat
5.1 Studierea noiunilor teoretice i a
exemplelor prezentate.
5.2 Studierea problemelor rezolvate i
identificarea elementelor de limbaj i a
algoritmilor utilizai.
5.3 Rezolvarea problemei propuse.

S-ar putea să vă placă și