Microsoft Word - CarteC.doc

Documente similare
L7

SUBPROGRAME

Limbaje de Programare Curs 5 – Siruri de caractere

Microsoft Word - PCLP2_Curs_4_2019.doc

Limbaje de Programare Curs 6 – Functii de intrare-iesire

Object Oriented Programming

Laborator 2 Incompatibilităţi/Diferenţe între C şi C++ Completări C++ Supraîncărcarea (redefinirea) numelui de funcţii În C nu este permisă existenţa

Microsoft Word - CarteC.doc

Limbaje de programare Pointeri. Alocare dinamică (continuare) 26 noiembrie 2012

Slide 1

LUCRAREA NR

Microsoft PowerPoint - Curs_SDA_4_RO_2019_v2.pptx

Microsoft PowerPoint - ImplementareLimbaj [Read-Only] [Compatibility Mode]

Slide 1

Microsoft PowerPoint - Curs_SDA_3_RO_2019_v2.pptx

E_d_Informatica_sp_MI_2015_bar_02_LRO

E_d_Informatica_sp_SN_2014_bar_10_LRO

Programarea şi utilizarea calculatoarelor

Limbaje de Programare Curs 8 – Fisiere

Microsoft Word - CarteC.doc

Microsoft Word _POO_Lab_1_Modificari_v01.htm

Slide 1

Microsoft PowerPoint - Curs_SDA_9_RO_2019_v2.pptx

Top

Paradigme de Programare

Laborator 3

Procesarea Imaginilor - Laborator 1: Introducere în utilizarea bibliotecii OpenCV 1 1. Introducere în utilizarea bibliotecii OpenCV 1.1. Introducere S

Laborator 2 - Încapsularea Programare Orientată pe Obiecte Tema 2.1 Să se analizeze programul EX2.C Indicatii 2.1 A nu se uita de fisierul EX2.H Tema

PCLPII-C16(9)

proiectarea bazelor de date

Microsoft PowerPoint - Curs_SDA_10_RO_2019_v1.pptx

Laborator 2: Instrucţiuni Java şi lucru cu şiruri de caractere Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 18 octombrie 2011

Paradigme de programare

Microsoft Word - Cuprins_LP.doc

Propunator: Morar Florin Colegiul National Silvania Zalau Discipina: Informatica Nivel liceal, cls. XII 1.Să se scrie în limbajul C/C++ definiţia comp

Microsoft Word - 2 ES RO.doc

Microsoft Word - c6.doc

Programarea calculatoarelor. Note de curs Marius Minea 1 Introducere în programarea în C 1.1 Funcţii în limbajul C Calcule şi funcţii La origine, rolu

Microsoft Word - O problema cu bits.doc

Operatorii in C Expresii Operatori aritmetici Operatori de asignare Operatori de incrementare si decrementare Operatori relationali Operatori logici O

-

Subiectul 1

Tablouri (continuare)

1. Operatii cu matrici 1 Cerinte: Sa se realizeze functii pentru operatii cu matrici patratice (de dimensiune maxima 10x10). Operatiile cerute sunt: A

Programarea şi utilizarea calculatoarelor

PRELEGERE XIII PROGRAMAREA CALCULATOARELOR ŞI LIMBAJE DE PROGRAMARE Noţiunea de funcţie - continuare VI. Funcţii recursive O funcţie se poate activa n

PROGRAMARE ORIENTATA PE OBIECTE

Interfețe și Protocoale de Comunicații Arduino-Port Paralel Arduino. Laborator 1- Portul Paralel 1 Caracteristici generale Arduino UNO este o placă de

Microsoft PowerPoint - Curs_TPI_22_v01.ppt

Tipuri de date abstracte 30 noiembrie 2005 Programarea calculatoarelor 2. Curs 9 Marius Minea

Lab6LCD

Declaraţii. Instrucţiuni 19 octombrie 2005 Programarea calculatoarelor 2. Curs 3b Marius Minea

Laborator 4: Continuare Programare Orientată pe Obiecte Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 29 octombrie 2011

SIRURI DE CARACTERE in C++ O constanta de tip sir de caractere de declara intre doua caractere. In memoria interna, o constanta de acest tip este reti

LUMINIŢA SCRIPCARIU

Laborator 04: Apeluri de funcții

Analiză statică Analiza fluxului de date 23 octombrie 2014

Programarea şi utilizarea calculatoarelor

Slide 1

Laborator 9: Fire de execuţie Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 20 noiembrie 2011

Diapositive 1

Matrici și vectori în VBA În VBA, o matrice este un grup de variabile de același tip. De ce ar trebui să utilizați o matrice? Presupunem că ați vrut s

Scrieţi pe foaia de examen răspunsul pentru fiecare dintre cerinţele următoare

ALGORITMII ŞI REPREZENTAREA LOR Noţiunea de algoritm Noţiunea de algoritm este foarte veche. Ea a fost introdusă în secolele VIII-IX de către Abu Ja f

Analiză de flux de date 29 octombrie 2012

Tablouri unidimensionale Problema 1 Să se determine mulţimea cifrelor unui număr natural n > 0, dat. Exemplu: n= Cifre = {1,2,3,7} Se cere să s

Adresarea memoriei Modurile de adresare constituie un instrument principal pentru reprezentarea în memorie a imaginii datelor, aşa cum este ace

tehnologii web

Platformăde e-learning și curriculăe-content pentru învățământul superior tehnic Sisteme de operare 13. Planificarea proceselor

Grile si probleme siruri de caractere in C++ ŞIRURI DE CARACTERE Itemii următori sunt preluaţi din variantele de bacalaureat În secvenţa de i

Managementul Resurselor Umane

Metode de programare Proiectarea algoritmilor

Microsoft Word - lab4.doc

Slide 1

Lucrarea 10

PowerPoint Presentation

PowerPoint-Präsentation

Slide 1

-

Anexa nr. 2 FIŞA DISCIPLINEI 1. Date despre program 1.1 Instituţia de învăţământ superior UNIVERSITATEA DE VEST TIMISOARA 1.2 Facultatea FIZICA 1.3 De

Fişiere 11 ianuarie 2004 Utilizarea şi programarea calculatoarelor. Curs 13 Marius Minea

Concepte fundamentale ale limbajelor de programare

Declararea variabilelor

CURS

Backtracking_2018

PPSD

Microsoft Word - Software pentru ordonarea multirang a componentelor unei colectivitati.doc

Lucrarea nr. 4 - Algoritmi de sortare şi ordonare Breviar teoretic Un algoritm de sortare este o metoda prin care se aranjează elementele unui tablou

ALGORITMICĂ. Seminar 3: Analiza eficienţei algoritmilor - estimarea timpului de execuţie şi notaţii asimptotice. Problema 1 (L) Să se determine număru

/*

1

ALGORITHMICS

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Programare în limbaj de asamblare 42. Utilizare Debug şi TurboDebug

Microsoft Word - Ivan, Boja.doc

Modelarea si Simularea Sistemelor de Calcul

Curs 2 Programare modulară în C - Funcții Test driven development, Code Coverage - Module Programare modulara, TAD - Gestiunea memoriei in C/C++ Curs

Capitole Speciale de Informatică Curs 2: Determinarea vocabularului de termeni şi a listelor de postări 4 octombrie 2018 Reamintim că listele de indec

Preprocesorul C Funcţii cu numǎr variabil de argumente 6 decembrie 2005 Programarea calculatoarelor 2. Curs 10 Marius Minea

Microsoft Word - Algoritmi genetici.docx

Transcriere:

Transmiterea parametrilor unei funcții Parametrii se transmit de la funcţia apelantă la funcţia apelată prin intermediul stivei. La apelul unei funcţii, pe stivă se crează o înregistrare de activare, care cuprinde, de jos în sus: adresa de revenire din funcţie, valorile parametrilor actuali şi variabilele locale. Parametrii se transmit prin valoare în ordinea inversă celei din lista de parametrii, astfel încât primul parametru din listă să fie întotdeauna sub adresa de revenire. Dacă funcţia apelată are şi variabile locale, acestea se crează tot pe stivă în ordinea declarării. Zona de pe stivă în care se plasează valoarea parametrilor actuali, adresa de revenire şi variabilele locale poartă denumirea de context de apel, iar acest mod de transmitere a parametrilor către funcţia apelată poartă denumirea de convenţie de apel C. În afara apelului prin valoare, care transferă valorile parametrilor efectivi, mai există şi apelul prin referinţă. În acest caz, la apel nu se transferă valorile parametrilor efectivi, ci adresele acestor valori. Deci, între cele două tipuri de apel există o diferenţă esenţială, şi anume: dacă în cazul apelului prin valoare, funcţia apelată nu poate modifica parametri efectivi din funcţia care a făcut apelul, neavând acces la ei, în cazul apelului prin referinţă, funcţia apelată, dispunând de adresa parametrilor efectivi, îi poate modifica. Dacă se doreşte ca o funcţie să modifice valoarea unei variabile, apelul trebuie să conţină ca parametru pointerul la variabila respectivă. Apel prin referinţă utilizând parametrii de tip pointer La apelul unei funcţii dacă parametrul efectiv este numele unui tablou, apelul prin valoare devine prin referinţă, parametrul formal corespunzător va primi ca valoare 1

adresa primului element al tabloului. Deci, putem spune că parametrii formali declaraţi ca tablouri sunt pointeri. Exemplu: int tab[];... f(tab);... şi f are antetul void f (int v[]); La apel v are aceeaşi valoare cu tab, adică tab[0] şi v[0] exprimă acelaşi lucru, valoarea lui tab [0]. Dacă x este o variabilă simplă, atunci putem transfera la un apel, în locul valorii lui x, adresa lui x: int x;... h(x); /* se transferă valoarea lui x */... g(&x); /* se transferă adresa lui x */... În acest caz, antetele funcţiilor sunt: void h(int i) şi void g(int * p) Exemplu: Programul realizează interschimbarea a două variabile folosind o funcţie: #include <stdio.h> void interschimba(int *, int *); 2

int main() { int a=3, b=7; printf()=( %d %d \n, a,b); interschimbă (&a, &b); printf( %d %d \ n, a,b); return 0; } void interschimba(int *p, int *q) { int tmp; tmp=*p; *p=*q; *q=tmp; } Efectul apelului prin adresă este realizat prin: 1. Declararea parametrului funcţiei ca fiind un pointer; 2. Folosirea unui pointer de indirectare în corpul funcţiei. 3. Transmiterea adresei unui argument când funcţia este apelată. Alocarea dinamică a memoriei Limbajul C permite utilizatorului să aloce date atât pe stivă (date automatice) cât şi în zone de memorie care nu aparţin stivei (date globale şi statice). Alocarea datelor pe stivă se face la execuţie şi ea nu este permanentă. Astfel, dacă declaraţia : 3

tip nume ; se utilizează în corpul unei funcţii, atunci variabila nume se alocă pe stivă la fiecare apel al funcţiei respective. La revenirea din funcţie, stiva se curăţă (se readuce la starea avută înaintea apelului) şi prin aceasta variabila nume nu mai este alocată (devine nedefinită). O alocare de acest fel a memoriei se spune că este dinamică. Pentru datele globale sau statice, memoria este alocată în fazele precedente execuţiei şi alocarea rămâne valabilă până la terminarea execuţiei programului. De aceea pentru datele de acest fel se spune că alocarea este statică ( nu este dinamică). Limbajele C şi C++ oferă utilizatorului posibilitatea de a aloca dinamic memorie şi în alt mod decât cel indicat mai sus pentru datele automatice. Aceasta se realizează într-o zonă de memorie specială, distinctă de stivă. Această zonă de memorie se numeşte memorie heap. Ea poate fi gestionată prin funcţii standard. Biblioteca standard a limbajului C pune la dispoziţia utilizatorului funcţii care permit alocarea de zone de memorie în timpul execuţiei programului. O astfel de zonă de memorie poate fi utilizată pentru a păstra date temporare. Zona respectivă poate fi eliberată în momentul în care nu mai sunt necesare datele care au fost păstrate în ea. Alocarea de zone de memorie şi eliberarea lor în timpul execuţiei programelor permite gestionarea optimă a memoriei de către programator. Un astfel de mijloc de gestionare a memoriei îl vom numi alocare dinamică a memoriei. Funcţiile standard pentru gestiunea memoriei heap au prototipurile în fişierul alloc.h. Alocarea unei zone de memorie în memoria heap se realizează cu ajutorul funcţiei malloc care are prototipul: void *malloc ( unsigned n) ; Această funcţie alocă o zonă de memorie contiguă de n octeţi. Ea returnează adresa de început a zonei alocate. Această adresă reprezintă un pointer de tip void (void *). Prin intermediul acestui pointer se pot păstra date în zona de memorie alocată în acest fel. Pentru a păstra o dată de un tip dat într-o zonă de memorie alocată prin malloc este necesar să convertim 4

adresa returnată de funcţie spre tipul datei respective. Exemplu: Se cere să se aloce în memoria heap o zonă de memorie pentru a păstra n valori de tip int. În acest scop declarăm un pointer spre tipul int: int *p ; apoi apelăm funcţia malloc cu ajutorul expresiei de atribuire : p = ( int *) malloc( n*sizeof( int)) Valoarea returnată de funcţia malloc a fost convertită spre tipul int*, adică pointer spre tipul int. În continuare putem pastra şi utiliza date de tip int, folosind variabila pointer p. Funcţia malloc are ca parametru un întreg fără semn, adică acesta aparţine intervalului [0, 65.535]. În cazul în care în memoria heap nu se poate aloca o zonă de memorie contiguă de atâţia octeţi cât este valoarea parametrului de la apel, se va returna pointerul nul, adică valoarea zero. De aceea, după apelul funcţiei malloc se va testa valoarea returnată pentru a ne asigura că aceasta nu este zero. Zonele alocate prin funcţia malloc pot fi eliberate, pentru a putea fi eventual realocate, folosind funcţia standard free. Aceasta are prototipul : void free ( void *p) ; Prin apelul ei, se eliberază zona de memorie din memoria heap, spre care pointează p. (variabila p trebuie să fie obţinută printr-un apel al unei funcţii standard de alocare, cum este de exemplu malloc) Se recomandă ca această funcţie să fie apelată de îndată ce datele dintr-o zonă de memorie heap nu mai sunt necesare, astfel zona respectivă poate fi ulterior realocată. O altă funcţie standard utilă pentru a aloca zone de memorie în memoria heap este funţia calloc, cu prototipul : void *calloc ( unsigned nrelem, unsigned dimelem) ; Funcţia alocă o zonă de memorie egală cu nrelem*dimelem octeţi. Ea returnează adresa de început a zonei de memorie alocată, adresă care reprezintă un ppinter spre void. În 5

cazul în care nu se pot aloca nrelem*dimelem octeţi, funcţia returnează zero. Zona de memorie alocată cu calloc, se eliberează folosind funcţia free. Vectori alocaţi dinamic Un tablou poate fi alocat dinamic printr-o secvenţă de tipul: TIP * p; p= (TIP *) malloc(n*sizeof(tip)); Pointerul p va indica un bloc suficient de mare pentru a conţine N elemente de tipul TIP. În continuare, variabila p poate fi utilizată ca şi cum ar fi fost declarată ca un tablou de forma: TIP p[ N ]; Avantajul alocării dinamice a unui tablou este că dimensiunea sa poate fi specificată doar în timpul execuţiei. Un vector alocat dinamic se declară ca variabilă pointer care se iniţializează cu rezultatul funcţiei de alocare. Tipul variabilei pointer este determinat de tipul componentelor vectorului. Exemplul 1 : Alocarea dinamică de memorie pentru un tablou de n numere întregi: #include <stdlib.h> #include <stdio.h> int main() { int n; int * tab; int i; printf("introduceti numarul de elemente: \n"); scanf("%d", &n); 6

} if ((tab=(int *)malloc(n * sizeof(int)))==null) { printf("eroare alocare dinamica memorie!\n"); exit(1); } for (i=0; i<n; i++) printf("%d ", tab[ i ]); free(tab); return 0; Exemplu 2: Definirea și utilizarea unui vector alocat dinamic (varianta 2) #include <stdlib.h> #include <stdio.h> int main() { int n, i; int * a; // adresa vector alocat dinamic printf ("n="); scanf ("%d", &n); // dimensiune vector a=(int *) calloc (n,sizeof(int)); // aloca memorie pentru vector // sau: a=(int*) malloc (n*sizeof(int)); // citire component vector: printf ("componente vector: \n"); for (i=0;i<n;i++) scanf ("%d", &a[i]); // sau scanf ( %d, a+i); // afisare vector: for (i=0;i<n;i++) printf ("%d ",a[i]); return 0; } 7

Modificatorul CONST Constantele se pot defini prin: caracterele care o compun construcţia #define intermediul modificatorului const Formatele posibile ale unei declaraţii cu ajutorul modificatorului const sunt: 4. tip const nume = valoare; 5. tip *const nume = valoare; 6. tip const *nume = valoare; 7. const tip nume = valoare; 8. const tip *nume=valoare; Exemplu: 1) int const i = 10; y = i + 3; 2) char *const s = şir ; este un pointer constant spre zona în care se păstrază şirul de caractere format din literele s, i, r şi caracterul NUL. În acest caz valoarea lui s nu poate fi schimbată; el fiind pointer, va avea ca valoare o adresă a unei zone de memorie de dimensiune egală cu 4 octeţi. În această zonă se păstrează şirul de caractere indicat mai sus. Conţinutul acestei zone poate fi modificat. O atribuire de forma s = t; unde t este un pointer spre tipul caracter, nu este acceptată de compilator, dar atribuirile: *s = 1 ; *(s+1) = 2 ; sunt corecte. Cu ajutorul lor se schimbă caracterul s cu 1 şi i cu 2 în zona spre care pointează s; 8

Declaraţia tip const *nume = valoare; defineşte pe nume ca un pointer spre o zonă constantă. În acest caz, valoarea pointerului nume se poate schimba. De exemplu pentru: char const *s = şir ; atribuirea s = t; unde t este un pointer spre char, este corectă. În schimb, atribuirile *s = a ; *(s+1) = b ; sunt eronate, deoarece s pointează spre o zonă în care se păstrează o dată constantă. Constanta respectivă poate fi modificată, folosind un pointer diferit de s: char *p; p = (char*)s; /*p ca şi s pointează spre zona în care se păstrează şirul de caractere şir */ *p = a ; *(p+1) = b ; Declaraţia const tip nume = valoare este identică cu declaraţia (1), dacă tip nu este un tip pointer. Dacă tip este un tip pointer, adică declaraţia (4) este de forma const tip *nume = valoare; atunci ea este identică cu declaraţia (3) De obicei se foloseşte formatul (5), în locul formatului (3) pentru a declara un pointer spre o zonă constantă, a cărui valoare nu poate fi modificată direct, adică prin atribuiri în care se foloseşte nume: *nume = val ; *(nume +k) =val; Declaraţia const tip *nume; 9

se utilizează pentru a declara un parametru formal. Fie funcţia f de antet : tip f (tip *nume) La apelul funcţiei f, parametrului formal nume i se atribuie ca valoare o adresă. În acest caz, funcţia f poate modifica data păstrată în zona de memorie spre care pointează nume, folosind o atribuire de forma: *nume = valoare Dacă se doreşte protejarea datei faţă de eventualele atribuiri neautorizate, vom declara parametrul formal respectiv ca un pointer spre o dată constantă. În acest caz, antetul funcţiei devine tip f (const tip *nume) O atribuire de forma *nume=valoare este interzisă. Se recomandă declaraţia const tip *nume pentru orice parametru formal, care la apel are ca valoare adresa unei zone de memorie, al cărui conţinut nu poate fi modificat de funcţia apelată. Şiruri de caractere Limbajul C nu defineşte tipul de dată şir (String în Pascal), dar există două posibilităţi de definire a şirurilor: ca tablou de caractere: Exemplu: 1) char sir1 [30]; 2) char sir2 [10] = exemplu ; ca pointer la caractere Exemplu: 1) char *sir3; sir3= &sir1; sir3 =&sir1[0]; sir3 = sir1; sir3 = (char *) malloc(100); 2) char *sir 4 = test ; 10

folosirea unui pointer spre un şir const. Diferenţa dintre un şir iniţializat cu o constantă şir şi un pointer iniţializat tot cu o constantă şir este că şirul conţine caractere individuale, urmate de caracterul \0, iar pointerul este asigurat cu adresa şirului constant din memorie 3) char tab [ ] = Acesta este un sir ; În acest caz, avem următoarele corespondenţe : tab indică adresa caracterului A, tab + 1 indică adresa caracterului c, tab [0] indică codul ASCII al caracterului A, tab [1] indică codul ASCII al caracterului c, * tab indică codul ASCII al caracterului A, * (tab + 1) indică codul ASCII al caracterului c O constantă şir de caractere se reprezintă între ghilimele. Ultimul caracter din şir este caracterul nul ( \ ). Limbajul C pune la dispoziţia programatorului o mulţime de funcţii de prelucrare a şirurilor. Câteva dintre cele mai des utilizate le vom prezenta în continuare. Funcţiile declarate în stdio.h pentru prelucrarea şirurilor se referă la operaţii de intrare/ieşire asupra şirurilor, adică citire/afişare şir de caractere. Funcţia char *gets (char *s); citeşte caracterele de intrare până la întâlnirea caracterului Enter, care nu se adaugă în şir (în s); în plus, funcţia plasează \0 la sfârşitul şirului s şi returnează adresa primului caracter din şir; dacă se tastează CTRL/Z returnează NULL; codul lui Enter este scos din bufferul de intrare. Funcţia 11

int puts (char *s); tipăreşte şirul s, trecând cursorul pe rând nou. Funcţia scanf ( %s, s); citeşte caracterele de la tastatură până la întâlnirea primului blanc sau Enter, care nu se adaugă în şir. Această funcţie plasează \0 la sfârşitul şirului s; dacă se tastează CTRL/Z, ea returnează EOF. Codul lui blanc sau Enter rămâne în buffer-ul de intrare. Funcţia printf ( %s, s); tipăreşte şirul s. Funcţiile pentru prelucrarea şirurilor de caractere din biblioteca string.h se referă la compararea a două şiruri, copiere de şiruri, determinarea lungimii şirurilor şi altele. Funcţia unsigned strlen (const char *s); returnează lungimea unui şir de caractere. Lungimea şirului este numărul de caractere proprii, care intră în compunerea şirului respectiv, fără caracterul NUL. Exemple: 1) char *const p = Acesta este un sir ; unsigned n; n = strlen (p); n = 18 şi reprezintă numărul caracterelor proprii din compunerea şirului spre care pointează p. 2) char tab [ ] = Acesta este un sir ; int n; n = strlen (tab); 3) int n; n = strlen ( Acesta este un sir ); 12