Documente Academic
Documente Profesional
Documente Cultură
Lucrarea nr. 2
1. Scopul lucrării
Lucrarea are ca scop prezentarea elementelor de bază ale limbajului C.
2. Noţiuni teoretice
2.2 Variabile. Tipuri de variabile. Declarare În urma execuţiei acestui program se va afişa:
Limbajul C permite utilizarea de variabile (nume
simbolice) pentru memorarea datelor, calculelor sau Evenimentul S are numărul 5 şi a avut loc la
rezultatelor. 11.300000
1
Limbajul C cu aplicații în analiza numerică – Elemente generale ale limbajului C
2
Limbajul C cu aplicații în analiza numerică – Elemente generale ale limbajului C
cu printf(), apelul funcţiei scanf() implică utilizarea
Ex. 3 unui şir de caractere de control urmate de o listă de
#include<stdio.h> argumente. Dar, în timp ce printf() utilizează nume de
main() variabile, constante şi expresii, scanf() utilizează
{ pointeri la variabile.
float valoare; Exemplul 4 este o variantă a programului din
valoare = 20.13301; exemplul 2 în care, în plus, se utilizează funcţia scanf().
printf ("%8.1f%8.1f\n”, 22.5,425.7);
printf ("% -8.1f % -8.1f\n.", 22.5,425.7); Ex. 4
printf ("%f\n",valoare); #include<stdio.h>
printf ("%5.2f\n", valoare); main()
printf (" %012f\n", valoare) ; {
printf ("%10f\n”, valoare); int nr;
} char ev;
În urma executării programului din ex.3, va rezulta: float timp;
printf ("Introduceţi pozitia, evenimentul, timp:");
2 2 . 5 4 2 5 . 7 scanf ("%c %d %f", &ev, &nr, &timp);
2 2 . 5 4 2 5 . 7 printf ("Evenimentul %c are numărul %d ", ev, nr);
2 0 . 1 3 3 0 1 1 printf (" şi a avut loc la %5.2f", timp);
2 0 . 1 3 }
2 0 . 1 3
0 0 0 2 0 . 1 3 3 0 1 1 Execuţia programului poate fi:
2 0 . 1 3 3 0 1 1 Introduceţi pozitia, evenimentul şi timpul: A 6 11.30
Evenimentul A are numărul 6 şi a avut loc la 11.30
Se observă că prezenţa unui zero înaintea numărului
care specifică dimensiunea câmpului de scriere Valorile variabilelor ev, nr şi timp au fost introduse
determină la afişare umplerea cu zero a spaţiilor goale. de la tastatură. Pentru separarea lor a fost utilizat spaţiu
(blank). Putea fi folosit return sau tab; orice alt
2.4. Secvenţe de evitare (escape) separator (linie, virgula) nu realizează această separare.
În exemplul 3, caracterul "\n" inserat în şirul de
caractere din apelul funcţiei printf() a determinat 3. Problemă rezolvată
afişarea pe o linie nouă (carriage return-linefeed).
Acest caracter este un exemplu de secvenţă escape, 3.1 Să se scrie un program care permite aflarea
numită aşa deoarece simbolul (\) backslash este codului numeric al unei taste în zecimal, hexa si octal.
considerat caracter escape, care determină o abatere de
la interpretarea normală a şirului. Aceste secvenţe #include<stdio.h>
escape sunt: #include<conio.h>
\a beep alarmă-sonoră; void main(void)
\b backspace spaţiu înapoi; {char caracter;
\f formfeed linie nouă, dar pe coloana următoare clrscr();
celei curente; printf("Acest program afiseaza codul unei taste in
\n newline determină trecerea la linie nouă, pe zecimal, hexa si octal.\n");
prima coloană; printf("Apasati o tasta:");
\r carriage return determină revenirea la începutul scanf("%c",&caracter);
liniei; printf("Codul tastei \”%c\” este %d (in decimal),
\t tab determină saltul cursorului din 8 in 8 coloane; %x (in hexa), %o (in octal)\n", caracter, caracter,
\\ backslash ; caracter, caracter);
\' apostrof simplu; getch();
\" ghilimele; }
\0 null ;
\ddd valoare caracter în notaţie octală 4. Chestiuni de studiat
(fiecare d reprezintă un digit); 4.1 Studierea noţiunilor teoretice şi a exemplelor
\xdd valoare caracter în notaţie hexazecimală; prezentate.
4.2 Studierea problemelor rezolvate şi identificarea
2.5. Funcţia scanf() elementelor de limbaj şi a algoritmilor utilizaţi.
O altă funcţie des utilizată a limbajului C este
funcţia de introducere a datelor scanf(). În mod similar
3
Limbajul C cu aplicații în analiza numerică – Pointeri în limbajul C
Lucrarea nr. 3
POINTERI ÎN LIMBAJUL C
1. Scopul lucrării
Lucrarea are ca scop prezentarea utilizării variabilelor pointer în limbajul C.
2. Noţiuni teoretice
Variabilele pointer (indicator) reprezintă adrese În această secvenţă de program, variabila iptr
ale unor zone de memorie. Pointerii sunt utilizaţi este un pointer de obiecte int, iar variabila fptr un
pentru a face referire la date cunoscute, prin pointer de obiecte float. Tot aici, tabptr este un
adresele lor. Puterea şi flexibilitate în utilizarea tablou de 10 pointeri de tip int, iar dptr va putea
pointerilor, specifică limbajului C, reprezintă un conţine adresa unui pointer de obiecte float (se
avantaj faţă de celelalte limbaje (de ex. Pascal). realizează o dublă indirectare, pointer la pointer).
Există 2 categorii de pointeri: Deoarece, la compilare sau în timpul execuţiei
pointeri de date (obiecte) care conţin adrese programului nu se fac verificări ale validităţii
ale unor variabile sau constante din valorilor pointerilor, orice variabilă pointer trebuie
memorie; iniţializată cu o valoare validă, 0 sau adresa unui
pointeri de funcţii care conţin adresa obiect sau a unei funcţii, înainte de a fi utilizată.
codului executabil al unei funcţii. Iniţializarea cu valoarea 0 a unei variabile
În plus, există şi pointeri de tip void (o a treia pointer indică faptul ca aceasta nu conţine adresa
categorie), care pot conţine adresa unui obiect unui obiect sau a unei funcţii. Uzual, în aceste
oarecare. cazuri, se foloseşte pentru atribuire identificatorul
Declararea unui pointer de date se face cu NULL(=0), care este declarat în fişierele antet
sintaxa: (stdio.h, stdlib.h etc.).
tip *var_ptr; Utilizarea variabilelor pointer implică folosirea
a doi operatori unari: operatorul & ce permite
Prezenţa caracterului * defineşte variabila aflarea adresei unei variabile oarecare şi
var_ptr ca fiind de tip pointer, în timp ce tip este operatorul * care permite accesul la variabila
tipul obiectelor a căror adresă o va conţine (numit adresată de un pointer.
şi tipul de bază al variabilei pointer var_ptr). Astfel, în cazul unei variabile var de tipul tip,
Pentru pointerii de tip void se foloseşte expresia:
declaraţia: &var se citeşte: “adresa variabilei var”
void * v_ptr; iar rezultatul este un pointer de obiecte tip şi are
valoarea adresei obiectului var.
Exemplul următor conţine un set de declaraţii În cazul unei variabile pointer de obiecte tip,
de variabile pointer: numită ptr, expresia:
Ex.1: *ptr se citeşte: “la adresa ptr”
iar rezultatul este de tipul tip şi reprezintă obiectul
int *iptr; adresat de variabila pointer ptr. Expresia *ptr
float *fptr, val; poate fi utilizată atât pentru a aflarea valorii
void *v_adr; obiectului, dar şi în cadrul unei operaţii de
int * tabptr [10]; atribuire.
float ** dptr;
1
Limbajul C cu aplicații în analiza numerică – Pointeri în limbajul C
Utilizarea acestor operatori este prezentată în if(ptr1<ptr2)
exemplul următor, în care, pentru afişarea adreselor printf(“ptr1=%p <ptr2=%p”,ptr1,ptr2);
în hexazecimal se foloseşte funcţia printf() ………………
împreună cu specificatorul de format %p: În multe situaţii este necesară compararea unui
pointer cu 0, pentru a verifica dacă adresează sau
Ex.2: nu un obiect:
#include <stdio.h> …………..
void main(void) if(ptr1==NULL)…/* ptr1 este un pointer nul*/
{ else… /* ptr1 este un pointer nenul*/
int var=5, *ptr; …………..
printf(“\n Variabila var se află la adresa:%p”, sau, sub forma:
&var); ………
printf(“\n şi are valoarea var=%d”,var); if(!ptr1)… /* ptr1 este un pointer nul*/
ptr=&var; else … /* ptr1 este un pointer nenul*/
printf(“\n Variabila ptr are valoarea:%p”, ptr); …………
printf(“\n şi conţine adresa obiectului: %d”,*ptr); Pot fi efectuate operaţii de adunare sau de
*ptr=10; scădere între un pointer de obiecte şi un întreg.
printf(“\nAcum, variabila var are valoarea Deoarece un pointer este o valoare care indică o
%d\n”,var); anumită locaţie din memorie, dacă adăugăm
} numărul 1 acestei valori, pointerul va indica
următoarea locaţie din memorie. Deci, în cadrul
În urma execuţiei programului se afişează: acestor operaţii intervine şi tipul variabilei.
Regula după care se efectuează aceste operaţii
Variabila var se află la adresa: 1A56 este următoarea:
şi are valoarea var=5 în cazul unei variabile pointer ptr:
Variabila ptr are valoarea: 1A56 tip *ptr;
şi conţine adresa obiectului: 5 operaţiile aritmetice:
Acum, variabila var are valoarea 10 ptr+n şi ptr-n
corespund adăugării/scăderii la adresa ptr a valorii
În urma operaţiei de atribuire ptr=&var, n*sizeof(tip).
variabila pointer ptr preia adresa variabilei var,
astfel încât cele două obiecte *iptr şi var devin De exemplu:
identice, reprezentând un întreg cu valoarea 5 de la ……………..
adresa 1A56. În aceste condiţii, expresia *ptr int *ip; /* sizeof(int)=2 */
poate fi folosită în locul variabilei var, cu efecte float *fp; /* sizeof(float)=4 */
identice. De aceea, atribuirea *ptr=10 are ca efect double *dp1, *dp2; /* sizeof(double)=8 */
modificarea valorii variabilei var din 5 în 10. ………….
dp2=dp1+5; /* dp2<-- adresa_dp1+5*8 */
2.2 Operaţii arimetice cu pointeri fp=fp-2; /* fp<-- adresa_fp-2*4 */
ip++; /* ip<-- adresa_ip+1*2 */
Operaţiile aritmetice ce se pot efectua cu dp1--; /* dp<-- adresa_dp-1*8 */
pointeri sunt: compararea, adunarea şi scăderea.
Aceste operaţii sunt supuse unor reguli şi restricţii În acelaşi context, se poate efectua scăderea a
specifice. În cazul în care tipurile asociate doi pointeri de obiecte de acelaşi tip, având ca
operanzilor pointer nu sunt identice, pot apare rezultat o valoare întreagă ce reprezintă raportul
erori, care nu sunt întotdeauna semnalate de dintre diferenţa celor două adrese şi dimensiunea
compilator. În acest sens, se recomandă conversia tipului de bază, ca în exemplul:
de tip explicită cu operatorul cast, de forma (tip*).
Operatorii relaţionali permit compararea int i;
valorilor a doi pointeri: float *fp1,*fp2; /*sizeof(float)=4*/
……….. i=fp2-fp1;
int *ptr1,*ptr2; /*i=(adresa_fp2-adresa_fp1)/sizeof(float)*/
2
Limbajul C cu aplicații în analiza numerică – Pointeri în limbajul C
Având în vedere importanţa tipului pointerilor void free(void*ptr);
în cadrul operaţiilor de adunare şi scădere,
operanzii nu pot fi pointeri de funcţii sau pointeri Parametrul funcţiei free() este un pointer ce
void. conţine adresa zonei care trebuie eliberată şi care
obligatoriu este rezultatul unui apel al unei funcţii
2.3 Variabile dinamice de alocare dinamică (de tip malloc()).
Astfel, zona alocată anterior poate fi eliberată
Pentru tipurile de date la care se cunoaşte prin apelul:
dimensiunea zonei de memorie necesară, aceasta …………….
este fixată în urma declaraţiei, înaintea lansării în free(fp);
execuţie a programului. ……………….
În cazul structurilor de date a căror dimensiune Zona de memorie alocată astfel este echivalentă
nu este cunoscută sau se modifică în timpul cu un tablou. Elementele acestuia pot fi referite
execuţiei programului, este necesară o alocare prin indexat. De exemplu fp[5] este obiectul float de la
program a memoriei, în timpul execuţiei. Memoria adresa fp+5.
alocată este folosită, iar atunci când nu mai este
utilă, se eliberează tot în timpul execuţiei 3. Problemă rezolvată
programului. 3.1 Acest program exemplifică regulile specifice
Variabilele create astfel se numesc dinamice. operaţiilor aritmetice cu pointeri.
Prototipurile funcţiilor utilizate pentru alocarea
şi eliberarea memoriei în timpul execuţiei #include <stdio.h>
programului se află în fişierele alloc.h şi stdlib.h. void main(void)
O funcţie des utilizată pentru alocarea dinamică {
a memoriei este malloc() şi are prototipul: int a=5,b=10, *iptr1, *iptr2,i;
float m=7.3, *fptr;
void*malloc(unsigned nr_octeţi); iptr1=&a;iptr2=&b;
fptr=&m;
Prin parametrul funcţiei malloc() se precizează printf("\n fptr=%u, *fptr=%2.1f, &fptr=%u", fptr,
dimensiunea în octeţi a zonei de memorie *fptr, &fptr);
solicitate. Dacă operaţia de alocare reuşeşte, fptr++;printf("\n Incrementare fptr:");
funcţia întoarce un pointer care conţine adresa printf("\n fptr=%u, *fptr=%2.1f, &fptr=%u", fptr,
primului octet al zonei de memorie alocate. În caz *fptr, &fptr);
contrar (spaţiul disponibil este insuficient) printf("\n iptr1=%u, *iptr1=%d, iptr2=%u,
pointerul rezultat este NULL (=0). *iptr2=%d", iptr1, *iptr1, iptr2,*iptr2);
Pentru o bună portabilitate a programelor, este i=iptr1-iptr2;
recomandabil, în apelul funcţiei malloc(), să se printf("\n Diferenta pointerilor iptr1 si iptr2
utilizeze operatorii cast (pentru conversie de tip la este=%d",i);
atribuire) şi sizeof (pentru precizarea dimensiunii iptr2=iptr1+8;
zonei solicitate). printf("\n iptr1=%u, *iptr1=%d, iptr2=%u,
De exemplu, dacă se doreşte alocarea unei zone *iptr2=%d", iptr1, *iptr1,iptr2,*iptr2);
de memorie pentru 10 valori de tipul float, se poate }
proceda astfel:
…………. 4. Chestiuni de studiat
float *fp; 4.1 Studierea şi însuşirea noţiunilor teoretice şi
fp=(float*)malloc(10*sizeof(float)); a exemplelor prezentate.
…………. 4.2 Identificarea elementelor de limbaj şi a
Eliberarea memoriei (rezultate în urma unei algoritmilor utilizaţi.
alocări dinamice) se face atunci când variabila
dinamică nu mai este utilă, iar spaţiul alocat poate
fi refolosit. În acest caz se poate folosi funcţia
free() care are prototipul:
3
Limbajul C cu aplicații în analiza numerică – Tablouri şi pointeri în limbajul C
Lucrarea nr. 4
1. Scopul lucrării
Lucrarea are ca scop prezentarea legăturii dintre tablouri şi pointeri în limbajul C
1
Limbajul C cu aplicații în analiza numerică – Tablouri şi pointeri în limbajul C
2
Limbajul C cu aplicații în analiza numerică – Tablouri şi pointeri în limbajul C
3
Limbajul C cu aplicații în analiza numerică – Funcţii in limbajul C
Lucrarea nr. 5
FUNCŢII ÎN LIMBAJUL C
1. Scopul lucrării
Lucrarea are ca scop prezentarea funcţiilor în limbajul C.
2. Noţiuni teoretice
În general, un program C este alcătuit din una Formatul general al apelului unei funcţii este:
sau mai multe funcţii. Întotdeauna există cel puţin nume_fct (param1, param2…)
o funcţie, funcţia main() care este apelată la Numim parametrii formali identificatorii din
lansarea în execuţie a programului. lista_declaraţii_parametrii din definiţia funcţiei
Sintaxa generală a definirii unei funcţii este : şi parametrii efectivi acele variabile, constante
sau expresii din lista unui apel al funcţiei.
tip_fct nume_fct(listă_declaraţii_parametrii) Se observă ca parametrii formali reprezintă
{ variabilele locale ale funcţiei. Timpul lor de viaţă
<lista_declaraţii_locale> corespunde duratei de execuţie a funcţiei.
listă_instrucţiuni Transmiterea parametrilor (în urma unui apel al
} funcţiei) se realizează prin încărcarea valorii
parametrilor efectivi în zona de memorie a
tip_fct este tipul rezultatului returnat de funcţie. parametrilor formali. Acest procedeu se numeşte
Dacă o funcţie nu întoarce un rezultat, tipul transfer prin valoare.
folosit este void. În cazul în care parametrul efectiv este o
În exemplul următor funcţia max primeşte doi variabilă, operaţiile efectuate în cadrul funcţiei
parametrii de tip float şi afişează valoarea maximă asupra parametrului formal nu o afectează. În Ex.1,
şi media acestora. Deoarece funcţia nu întoarce atribuirea a1=7.5 din finalul funcţiei nu modifică
niciun rezultat, tipul său este void: valoarea variabilei r din apelul max(r,4.53); .
Ex.1: Dacă se doreşte modificarea valorii unei
………. variabile indicate ca parametru efectiv într-o
void max(float a1,float a2) funcţie, trebuie ca parametrul formal să fie de tip
{ pointer. La apelare, trebuie să i se ofere explicit
float maxim; /* declaratie locală */ adresa unei variabile. Acest procedeu se numeşte
if(a1>a2) maxim=a1; transfer prin referinţă.
else maxim=a2; În cazul transferului prin referinţă, modificarea
printf realizată de funcţie asupra parametrilor efectivi
(“Maxim=%f;Medie=%f\n”,maxim,(a1+a2)/2); este valabilă atât în interiorul cât şi în exteriorul
a1=7.5; funcţiei.
} Atunci când se doreşte ca funcţia să returneze
main() un rezultat se foloseşte instrucţiunea return cu
{ … sintaxa:
float r; return (expresie)
… Valoarea expresiei este rezultatul întors de
max(r,4.53); /*apel al functiei afmax*/ funcţie, iar parantezele sunt opţionale.
}
1
Limbajul C cu aplicații în analiza numerică – Funcţii in limbajul C
2
Limbajul C cu aplicații în analiza numerică – Structuri
Lucrarea nr.6
STRUCTURI
1. Scopul lucrării
Lucrarea are ca scop prezentarea utilizării tipurilor de date de tip structură în limbajul C.
2
Limbajul C cu aplicații în analiza numerică – Structuri
4.1 Pentru o grupă de studenţi se cunosc numele 5.1 Studierea noţiunilor teoretice şi a
studenţilor şi 5 note obţinute la sfârşitul exemplelor prezentate.
semestrului. Se cere să se afişeze studenţii care nu 5.2 Studierea problemelor rezolvate şi
au nici o restanţă. identificarea elementelor de limbaj şi a
algoritmilor utilizaţi.
4.2. Să se folosească structuri de tip punct, 5.3 Rezolvarea problemelor propuse.
pentru a determina daca trei puncte A,B,C (date
prin coordonatele lor) pot forma un triunghi şi de
ce tip (oarecare, isoscel, echilateral).
3
Limbajul C cu aplicații în analiza numerică –Liste
Lucrarea nr. 7
LISTE
1. Scopul lucrării
Lucrarea are ca scop prezentarea listelor în limbajul C, punând accentul pe reprezentarea acestora cu ajutorul
structurilor de date dinamice.
1
Limbajul C cu aplicații în analiza numerică –Liste
2
Limbajul C cu aplicații în analiza numerică –Liste
3
Limbajul C cu aplicații în analiza numerică - Fişiere in limbajul C
Lucrarea nr.8
FIŞIERE IN LIMBAJUL C
1. Scopul lucrării
Lucrarea are ca scop prezentarea utilizării fişierelor în limbajul C.
2. Noţiuni teoretice
Un fişier reprezintă o colecţie ordonată de În exemplul următor:
înregistrări. Majoritatea operaţiilor de intrare–ieşire se FILE *fptr1, *fptr2;
bazează pe manipularea fişierelor. Datele introduse de fptr1=fopen(“fist.txt”,”r+t”);
la tastatură formează un fişier de intrare, în timp ce fptr2=fopen(”fisb.bin”,”wb”);
datele afişate pe display sau listate la imprimantă sunt deschise două fişiere: primul de tip text pentru
formează un fişier de ieşire. operaţii de actualizare şi cel de-al doilea de tip binar
Există două tipuri de fişiere: text şi binare. În timp pentru scriere.
ce fişierele text conţin caractere ASCII în gama 0-127 Închiderea unui fişier se realizează cu funcţia
(informaţie citibilă), fişierele binare conţin înşiruiri de fclose() având sintaxa generală:
caractere, neinteligibile pentru utilizator. De exemplu, int fclose(FILE* fptr_fisier);
fişierele sursă sunt fişiere text, în timp ce fişierele care va închide fişierul specificat de fptr_fisier.
executabile sunt fişiere binare. Funcţia fclose() returnează valoarea 0 în caz de
Prelucrarea unui fişier presupune o serie de operaţii închidere cu succes a fişierului şi EOF dacă a apărut o
precedate de deschiderea fişierului şi finalizate cu eroare.
închiderea acestuia. Închiderea fişierelor din exemplul precedent se va
În urma deschiderii unui fişier se generează un face cu secvenţa:
pointer la o structură de tip FILE predeclarată în fclose(fptr1);
stdio.h. Sintaxa de declarare a unui pointer la FILE fclose(fptr2);
este: FILE*fptr; Scrierea de date în fişier se realizează cu ajutorul
fptr fiind numele variabilei pointer cu care se lucrează funcţiei fprintf():
în continuare. int fprintf(FILE *fptr, const char *format,
Deschiderea unui fişier se realizează cu funcţia arg1, arg2,…,argn)
fopen() cu sintaxa generală: care scrie în fişierul pointat de fptr datele specificate de
FILE *fopen(const char*nume_fisier , arg1…argn, în formatul specificat prin şirul de
const char *mod); caractere format.
în care: În exemplul:
nume_fisier este numele fişierului care se va deschide
sau crea; FILE *fpt;
mod este modul în care este deschis fişierul: int i=5;
“r” deschide fişierul pentru citire; char c=’B’;
“w” deschide un fişier pentru scriere; float f=2.7543;
“a” deschide sau creează un fişier pentru scriere la fpt=fopen(“fis.dat”,”w”);
sfârşitul fişierului (adăugare); fprintf(fpt,”%d,%c,%f”,i,c,f);
“r+” deschide un fişier pentru actualizare
(citire + scriere); prin utilizarea funcţiei fprintf(), se scriu în fişierul
“w+” deschide un fişier pentru actualizare, conţinutul fis.dat, descris de fpt, un întreg, un caracter şi o
anterior se elimină; variabilă de tip float.
“a+” deschide un fişier pentru actualizare la sfârşit. Citirea de date dintr-un fişier se realizează cu
Fişierele pot fi deschise în mod binar sau text, după ajutorul funcţiei fscanf():
cum este specificat în argumentul mod al funcţiei fopen int fscanf(FILE *fptr, const char *format,
prin adăugarea literei t pentru text sau b pentru binar. arg1, arg2,…,argn)
Dacă operaţia de deschidere are succes, funcţia care citeşte din fişierul indicat de fptr date sub
returnează un pointer la FILE (pointer care va fi folosit controlul formatului specificat în format şi le atribuie
în continuare în operaţiile asupra fişierului), iar dacă variabilelor prin adresele specificate în arg1,
eşuează, fopen întoarce valoarea NULL. arg2,……argn, care, de această dată, sunt pointeri.
1
Limbajul C cu aplicații în analiza numerică - Fişiere in limbajul C
3. Problemă rezolvată {
Să se creeze un fişier text ce conţine informaţii despre printf("\n Nume:");
produsele dintr-un magazin. Să se scrie apoi o funcţie de scanf("%s",s.nume);
adăugare, apoi una de căutare în fişier după nume şi printf("\nNumarul de bucati:");
modificarea numărului de bucăţi . În final să se listeze scanf("%d",&(s.nr));
conţinutul fişierului modificat.
printf("\nPret: ");
#include<stdio.h>
scanf("%f",&(s.pret));
#include<string.h>
fwrite(&s,sizeof(prod),1,fp);
#include<conio.h>
printf("\n\n Mai doriţi adăugare? (d/n): ");
#include<process.h>
c=getch();
#define nf "produse.txt"
}
typedef struct {
fclose(fp);
char nume[10];
}
int nr;
void modificare()
float pret;
{ prod s;
}prod;
long int poz;
FILE *fp;
int gasit=0;
void creare ()
char n[10];
{
int nrnou;
if((fp=fopen(nf,"w"))==NULL)
printf("\n Dati numele dupa care se cauta: ");
{
scanf("%s",n);
printf("Eroare de creare\n");
printf("\n Dati noua cantitate: ");
exit(1);
scanf("%d",&nrnou);
}
if((fp=fopen(nf,"r+"))==NULL)
fclose(fp);
{
}
printf("Eroare de deschidere\n");
void listare ()
exit(1);
{
}
prod s;
while((!gasit)&&(!feof(fp)))
clrscr();
{
if((fp=fopen(nf,"r"))==NULL)
poz=ftell(fp);
{
fread(&s,sizeof(prod),1,fp);
printf("Eroare de deschidere \n");
if(!strcmp(n,s.nume))
exit(1);
gasit++;
}
}
do
if(!gasit)
{
{
fread(&s,sizeof(prod),1,fp);
printf("\nNu s-a gasit inregistrarea ");
if(feof(fp)) break;
getch();
printf("\n%s",s.nume);
}
printf("\n%d",s.nr);
else
printf("\n%5.2f",s.pret);
{
}
fseek(fp,poz,SEEK_SET);
while (!feof(fp));
fclose(fp);
fread(&s,sizeof(prod),1,fp);
}
s.nr=nrnou;
void adaugare ()
fseek(fp,poz,SEEK_SET);
{
fwrite(&s,sizeof(prod),1,fp);
char c;
}
prod s;
fclose(fp);
clrscr();
}
if((fp=fopen(nf,"a"))==NULL)
void main()
{
{ creare();
printf("Eroare de deschidere\n");
adaugare();
exit(1);
listare();
}
modificare();
c='d';
listare(); }
while(c=='d')
2
Limbajul C cu aplicații în analiza numerică - Fişiere in limbajul C
3
Limbajul C cu aplicații în analiza numerică – Rezolvarea ecuaţiilor
Lucrarea nr. 9
REZOLVAREA ECUAŢIILOR
1. Scopul lucrării
Lucrarea are ca scop prezentarea unei metode numerice de rezolvare a ecuaţiilor algebrice şi
transcendente cu ajutorul limbajului C++.
1
Limbajul C cu aplicații în analiza numerică – Rezolvarea ecuaţiilor
while((fabs(d-s)>err) &&(poly(xm,grad,coef)!=0)) parametru al acestei funcţii este un pointer ce
{ conţine adresa funcţiei matematice pentru care se
xm=0.5*(d+s); caută soluţiile.
if(poly(s,grad,coef)*poly(xm,grad,coef)<0)
d=xm;
else s=xm; 3. Probleme rezolvate
} 3.1 Să se afle dacă ecuaţia: x3-9x2+23x-15=0
*rad=xm; are o rădăcină în intervalul (-4.5,6), şi să se afle
return 1; valoarea acesteia (în cazul în care există) cu o
} eroare de 0.000001.
În acest exemplu s şi d reprezintă limitele
stânga şi respectiv dreapta ale intervalelor de lucru, #include<math.h>
iar xm mijlocul acestora. Este utilizată funcţia #include<iostream.h>
matematică poly() din math.h, care permite aflarea int bisectiepol (double s, double d, int grad,
valorii unui polinom într-un punct (primul double coef[], double err, double *rad)
parametru al funcţiei) cunoscându-se gradul {
polinomului (al doilea parametru) şi vectorul double xm ;
coeficienţilor acestuia (al treilea parametru). if(poly(s,grad,coef)*poly(d,grad,coef)>0) return 0;
Funcţia întoarce valoarea 0 în cazul în care nu if( poly (s,grad,coef) == 0 )
este găsită o rădăcină în intervalul specificat şi {
valoarea 1 în caz de succes, valoarea soluţiei fiind *rad=s;
transferată în variabila *rad. return 1;
}
if(poly(d,grad,coef)==0)
Exemplul 2. {
*rad=d;
int bisectiefct(double(*f)(double),double s, return 1;
double d, double err, double *rad) }
{ xm=0.5*(s+d);
double xm; while((fabs(d-s)>err) &&(poly(xm,grad,coef)!=0))
if(f(s)*f(d)>0) return 0; {
if(f(s)==0) xm=0.5*(d+s);
{ *rad=s; if(poly(s,grad,coef)*poly(xm,grad,coef)<0)
return 1; d=xm;
} else s=xm;
if(f(d)==0) }
{ *rad=xm;
*rad=d; return 1;
return 1; }
}
xm=0.5*(s+d); void main(void)
while( (fabs(d-s)>err)&&(f(xm)!=0) ) {
{ double *rad;
xm=0.5*(s+d); double f[]={-15,23,-9,1};
if( f(s)*f(xm)<0) d=xm; if (bisectiepol(4.5,6,3,f,0.000001,rad)==1)
else s=xm; {cout<<"Functia are o radacina in intervalul (4.5,6)
} egala cu:";
*rad=xm; cout<<*rad;}
return 1; else
} cout<<"Functia nu are radacina in intervalul
Implementarea acestei funcţii s-a realizat în specificat";
mod asemănător cu funcţia din exemplul 1. Primul }
2
Limbajul C cu aplicații în analiza numerică – Rezolvarea ecuaţiilor
3.2. Să să afle soluţia ecuaţiei transcendente 4. Probleme propuse
x e x
0 în intervalul (0.1,1), aplicând metoda 4.1 Să se afle dacă ecuaţia x3 –6x2+8x=0 are o
bisecţiei cu o eroare de calcul de rădăcină în intervalul (1,3), iar în caz afirmativ să
0.0000000001 se găsească această soluţie.
4.2 Să se găsească o rădăcină a ecuaţiei
#include<math.h> x sin( x ) 0.25 0 în intervalul (1,2) cu o
#include<iostream.h> precizie de 0.000001 .
double fct(double x)
{ 5. Chestiuni de studiat
double val_fct; 5.1 Studierea noţiunilor teoretice şi a
val_fct=x-exp(-x); exemplelor prezentate.
return (val_fct); 5.2 Studierea problemelor rezolvate şi
} identificarea elementelor de limbaj şi a
int bisectiefct(double(*f)(double),double s, algoritmilor utilizaţi.
double d, double err, double *rad) 5.3 Rezolvarea problemelor propuse
{
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;
}
3
Limbajul C cu aplicații în analiza numerică – Interpolarea funcţiilor
Lucrarea nr. 10
INTERPOLAREA FUNCŢIILOR
1. Scopul lucrării
Lucrarea are ca scop prezentarea unei metode numerice de aproximare a funcţiilor tabelate şi a
implementării acesteia în limbajul C++.
1
Limbajul C cu aplicații în analiza numerică – Interpolarea funcţiilor
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;
}
2
Limbajul C cu aplicații în analiza numerică – Integrarea ecuaţiilor diferenţiale ordinare
Lucrarea nr. 11
1. Scopul lucrării
Lucrarea are ca scop prezentarea unei metode numerice de integrarea a ecuaţiilor diferenţiale ordinare
cu ajutorul limbajului C++.
1
Limbajul C cu aplicații în analiza numerică – Integrarea ecuaţiilor diferenţiale ordinare
cout<<"\n"<<(i)*h<<" "<<sol[i]; 5. Chestiuni de studiat
} 5.1 Studierea noţiunilor teoretice şi a
} exemplelor prezentate.
void main(void) 5.2 Studierea problemei rezolvate şi
{ identificarea elementelor de limbaj şi a algoritmilor
float x0=0,y0=1,h=0.1,sol[10]; utilizaţi.
cout<<"\n0 1,000000"; 5.3 Rezolvarea problemelor propuse
RK4(F,x0,y0,h,10,sol);
}
4. Probleme propuse
4.1Să se scrie un program sursă în limbajul
C++ prin care să se găsească soluţiile ecuaţiei
diferenţiale y’=x2+y2 în punctele x=0.1; 0.2, 0.3;
0.4; 0.5, 0.6; 0.7, 0.8, 0.9 şi 1 ştiind că y(0)=1.
4.2 Se consideră un circuit R,L in serie
alimentat de la o sursa de curent alternativ
e=5cos(100πt)V. Cunoscând R=5Ω, L=5mH și că
la t=0 i=0, să se calculeze valorile curentului la
t=0.001, 0.002, 0.003, 0.004, 0.005, 0.006; 0.007,
0.008, 0.009 și 0.01 s.
Ecuaţia diferenţială asociată circuitului electric
di
este L Ri e .
dt
2
Limbajul C cu aplicații în analiza numerică – Rezolvarea sistemelor de ecuații liniare
Lucrarea nr. 12
1. Scopul lucrării
Lucrarea are ca scop prezentarea unei metode numerice de rezolvare a sistemelor de ecuații liniare cu
ajutorul limbajului C++.
(de exemplu toate zero sau coloana termenilor
2. Noţiuni teoretice liberi) şi se construiesc şirurile:
Se consideră sistemul liniar de n ecuaţii cu n x1(1) , x (21) ,..., x (n1)
necunoscute:
x1( 2) , x (22) ,..., x (n2)
a11x1 a12 x 2 ... a1n x n b1
a x a x ... a x b ………………..
21 1 22 2 2n n 2
x1( k ) , x (2k ) ,..., x (nk )
a n1x1 a n2x 2 ... a nn x n bn pe baza condiţiei de recurenţă:
sau matriceal AX=B unde: X (k ) CX ( k 1)
D
x1 b1 unde:
a 11 a 12 ... a 1n b1
x2 b2
a 21 a 22 ... a 2n xk
a 11
A ; X . ; B . 1
. . ... . xk b2
. . Xk 2
; D
a n1 a n2 ... a nn a 22
xn bn ...
...
x kn bn
a nn
Una dintre cele mai vechi metode iterative de
rezolvare a sistemelor de ecuaţii liniare este a 12 a 13 a 1n
0 ...
metoda lui Jacobi. Aceasta presupune explicitarea a 11 a 11 a 11
fiecărei necunoscute din sistem, de pe diagonala a 21 a 23 a 2n
0 ...
C a 22 a 22 a 22 ;
principală, în funcţie de celelalte necunoscute ale
sistemului: a n1 a n2 a n3
b1 a a 13 a ... 0
x1 0 12 x 2 x 3 ... 1n x n a nn a nn a nn
a 11 a 11 a a 11
11 O condiţie suficientă de convergenţă a metodei
b2 a 21 a 23 a 2n Jacobi este:
x2 x1 0 x 3 ... xn
a 22 a 22 a 22 a 22 a ii max a ij pentru i 1,2,..., n
j i
1
Limbajul C cu aplicații în analiza numerică – Rezolvarea sistemelor de ecuații liniare
3. Problemă rezolvată }
Metoda Jacobi prezentată mai sus este }
implementată în programul următor: void main (void)
#include<stdlib.h> {
#include<iostream.h> int i,j,n;
#include<math.h> char conv;
void Jacobi(float a[20][20],float b[20],float x[20], float x[10];
int n,char *conv) float a[10][20];
{ float b[10];
int max=10000; cout<<"Dati numarul de ecuatii: n=";
float eps=1.0e-6; cin>>n;
int i,j,it; cout<<"Dati elementele matricei A:";
float dif,eroare,s,xi[20]; for (i=0;i<n;i++)
for (i=0; i<n; i++) for (j=0;j<n;j++)
xi[i]=0.0; {cout<<"a["<<i<<","<<j<<"]=";
*conv='y'; cin>>a[i][j];
i=0; }
while (i<n) for (i=0;i<n;i++)
{ {
if (a[i][i]==0.0) cout<<"b["<<i<<"]=";
*conv='n'; cin>>b[i];
i = i+1; }
} Jacobi(a,b,x,n,&conv);
if (*conv=='y') }
{
it=1;
do 4. Probleme propuse
{ 4.1Să se rezolve, cu ajutorul metodei Jacobi,
for (i=0; i<n; i++) sistemul de ecuaţii:
{s = 0.0; 6 x1 2 x 2 2 x 3 x 4 12
for (j=0; j<n; j++)
x1 4 x 2 2
if (i!=j) s = s + a[i][j]*xi[j];
x[i] = (b[i]-s)/a[i][i]; x1 4 x 2 8x 3 2
} 2 x1 x 2 x 3 5x 4 4
eroare =0.0; și să se compare rezultatele obținute cu soluția
for (i=0; i<n; i++) exactă a sistemului.
{ dif = fabs(x[i]-xi[i]); 4.2 Studiați influența valorii erorii maxim
if (fabs(dif)>1e20) it=max+1; admisibile asupra soluțiilor obținute.
if (dif>eroare) eroare = dif;
} 5. Chestiuni de studiat
for (i=0; i<n; i++) xi[i] = x[i]; 5.1 Studierea noţiunilor teoretice şi a
it = it+1; exemplelor prezentate.
} while ((it<max)&&(eroare>eps)); 5.2 Studierea problemei rezolvate şi
if (it>max) identificarea elementelor de limbaj şi a
{ algoritmilor utilizaţi.
*conv='n'; 5.3 Rezolvarea problemelor propuse
cout<<"\n Metoda nu este convergenta!";
}
else
cout<<"Solutiile sistemului sunt:";
for(i=0;i<n;i++)
cout<<x[i]<<" ";
2
Limbajul C cu aplicații în analiza numerică – Vectori și valori proprii
Lucrarea nr. 13
2. Noţiuni teoretice
Se consideră o matrice pătrată A de ordinul n cu sistemelor de ecuaţii diferenţiale şi în alte operaţii
elemente din corpul K (K=R sau K=C): Scalarul mai complicate.
K pentru care există un vector nenul Cea mai simplă metodă de calcul a valorilor
T proprii şi ale vectorilor proprii asociate este
x x1 x2 x 3 ... x n , x K n ce verifică
metoda puterii.
A·x=λ·x se numeşte valoare proprie a matricei A Pentru matricea pătrată A de ordinul n se
iar vectorul x se numeşte vector propriu asociat presupune existenţa a n valori proprii distincte λ1 ,
valorii proprii λ. λ2,… λn, şi a n vectori proprii x1, x2,…xn
Relaţia: A·x=λ·x poate fi scrisă matriceal: independenţi. În aceste condiţii, un vector oarecare
a11 a12 ... a1n x1 x1 y K n poate fi scris ca o combinaţie liniară de cei
a 21 a 22 ... a 2n x 2 x2 n vectori proprii ai matricei A:
... ...
y a 1x1 a 2 x 2 ... a n x n
a x
n1 a n 2 ... a nn x n n Dacă înmulţim această egalitate cu matricea A
echivalentă cu: rezultă:
a 11 a 12 ... a1n x1 Ay Aa 1x1 Aa 2 x 2 ... Aa n x n
a 21 a 22 ...a 2n x 2 a 1λ1x1 a 2 λ 2 x 2 ... a n λ n x n
0
... iar dacă se continuă înmulţirea cu A a noilor
egalităţi, după pasul k se obţine :
a a n2 ... a nn x n
n1
A k y A k a 1x1 A k a 2 x 2 ... A k a n x n
care reprezintă un sistem omogen ce admite
întotdeauna soluţia banală: a 1λ1k x1 a 2 λ k2 x 2 ... a n λ kn x n
x1 x 2 x3 ... x n 0. care poate fi rescrisă :
k k
În plus, sistemul liniar omogen admite soluţii k k λ λ
A y λ a x a 2 2 x 2 ... a n n x n
nenule dacă şi numai dacă: 1 1 1
λ1 λ1
det (A-λ·In)=0 unde In este matricea
a 1λ1k x1
unitate de ordinul n.
Determinantul în necunoscuta λ reprezintă un dacă se consideră λ1 ca fiind cea mai mare valoare
polinom de grad n şi se numeşte polinomul proprie şi k este mare.
caracteristic al matricei A, iar egalarea sa cu zero Aceiaşi aproximare poate fi făcută şi pentru
ecuaţie caracteristică a matricei A. ecuaţia :
k 1 k 1
Orice matrice de ordinul n cu coeficienţi k 1 k 1 λ λ
complecşi are exact n valori proprii (nu neapărat A y λ a x a 2 2 x 2 ... a n n x n
1 1 1
λ1 λ1
distincte) care sunt rădăcinile ecuaţiei
caracteristice. a 1λ1k 1 x 1
Calculul vectorilor şi a valorilor proprii Din împărţirea ultimelor două egalităţi se obţine
simplifică operaţiile cu matrice în rezolvarea valoarea proprie de valoare maximă λ1:
1
Limbajul C cu aplicații în analiza numerică – Vectori și valori proprii
Ak y yk y[i]=0;
1 for(j=0;j<n;j++)
A k 1y y k 1
y[i]+=a[i][j]*x[j];
unde cu yk s-a notat Ak·y.
}
Se observă că y k a1k1 x1 şi deci este un for(i=0;i<n;i++)
aproximant al vectorului propriu x1 corespunzător x[i]=y[i];
variabilei proprii λ1. temp=val;
Deoarece yk are componente mari în valoare
absolută se consideră ca vector propriu val=0;
yk for(i=0;i<n;i++)
corespunzător lui λ1 vectorul .
yk {
if(fabs(x[i])>fabs(val))
val=x[i];
3. Problemă rezolvată
}
Această metodă este implementată în exemplul
for(i=0;i<n;i++)
următor:
x[i]/=val;
}while(fabs(val-temp)>0.0001);
#include<iostream.h>
cout<<"Valoarea proprie este : "<<val<<endl;
#include<conio.h>
cout<<"Vectorul propriu este: ";
#include<math.h>
for(i=0;i<n;i++)
#include<stdlib.h>
cout<<endl<<x[i];
int main()
getch();
{
}
float a[20][20],x[20],y[20],val=0,temp;
int n,i,j;
clrscr(); 4. Probleme propuse
4.1Să se calculeze, cu ajutorul metodei puterii,
cout<<"Dati dimensiunea matricei: ";
valoarea proprie și vectorul propriu asociat pentru
cin>>n;
cout<<"\nDati elementele matricei \n "; 2 1 1
for(i=0;i<n;i++) matricea: 1 2 1 şi vectorul iniţial (1 0 0)T
{ 1 1 2
for(j=0;j<n;j++) 4.2 Repetati calculul pentru vectorul iniţial
(-1 -1 -1)T
{
cout<<"a["<<i+1<<"]["<<j+1<<"]=" ; 5. Chestiuni de studiat
cin>>a[i][j]; 5.1 Studierea noţiunilor teoretice şi a
} exemplelor prezentate.
} 5.2 Studierea problemei rezolvate şi
cout<<"Dati vectorul initial: \n "; identificarea elementelor de limbaj şi a
for(i=0;i<n;i++) algoritmilor utilizaţi.
{ 5.3 Rezolvarea problemelor propuse
cout<<"x["<<i+1<<"]= ";
cin>>x[i];
}
do
{
for(i=0;i<n;i++)
{