Microsoft Word - PCLP2_Curs_4_2019.doc

Documente similare
Microsoft Word - CarteC.doc

L7

Limbaje de Programare Curs 6 – Functii de intrare-iesire

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

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

SUBPROGRAME

Limbaje de Programare Curs 5 – Siruri de caractere

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

Slide 1

Programarea şi utilizarea calculatoarelor

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

Microsoft Word - CarteC.doc

Top

Microsoft PowerPoint - Curs_SDA_3_RO_2019_v2.pptx

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

Object Oriented Programming

-

Microsoft PowerPoint - Curs_SDA_4_RO_2019_v2.pptx

E_d_Informatica_sp_SN_2014_bar_10_LRO

LUCRAREA NR

Microsoft PowerPoint - Curs_SDA_10_RO_2019_v1.pptx

Limbaje de Programare Curs 8 – Fisiere

Microsoft PowerPoint - Curs_SDA_9_RO_2019_v2.pptx

Subiectul 1

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

E_d_Informatica_sp_MI_2015_bar_02_LRO

Slide 1

Microsoft Word - O problema cu bits.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 - CarteC.doc

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

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

Paradigme de Programare

Diapositive 1

proiectarea bazelor de date

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

Laborator 3

Paradigme de programare

Programarea şi utilizarea calculatoarelor

Microsoft Word - c6.doc

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

Microsoft Word - Cuprins_LP.doc

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

PCLPII-C16(9)

tehnologii web

Microsoft Word _POO_Lab_1_Modificari_v01.htm

PowerPoint-Präsentation

Slide 1

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

1

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

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

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

ALGORITHMICS

Slide 1

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

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

Laborator 1-Teoria probabilitatilor si statistica matematica Sef lucrari dr.mat. Daniel N.Pop Departamentul de calculatoare si inginerie electrica 1 P

Lab6LCD

Probleme proiect TP BITPERM Implementați un algoritm care citește de la intrarea standard două numere naturale și scrie la ieșirea standard da

Microsoft Word - Curs_08.doc

Slide 1

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

Metode de programare Proiectarea algoritmilor

Declararea variabilelor

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

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

Programarea şi utilizarea calculatoarelor

O NOUA PROBLEMA DE CONCURS OLIMPIADA MUNICIPALA DE INFORMATICA, IASI 2019 V-am promis într-un articol mai vechi ca vom prezenta pe acest blog câteva p

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

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

PHP (II)

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

LUCRAREA 8 PROGRAMAREA NELINIARĂ ÎN REZOLVAREA PROBLEMELOR DIN ENERGETICĂ. METODE DE ORDINUL Aspecte generale Programarea neliniară are o foart

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

Logică și structuri discrete Limbaje regulate și automate Marius Minea marius/curs/lsd/ 24 noiembrie 2014

Analiză statică Analiza fluxului de date 23 octombrie 2014

Poo Laboratoare 1 Contents Laborator7 2 1 Colecţii de obiecte în Java Interfaţa Iterator Interfaţa C

Microsoft PowerPoint - Curs_TPI_22_v01.ppt

Microsoft Word - 2 ES RO.doc

Propunator: Morar Florin Colegiul National Silvania Zalau Discipina: Informatica Nivel liceal, cls. XI 1.Fişierul text bac.in conţine cel mult 1000 de

Procesarea Imaginilor Laborator 3: Histograma nivelurilor de intensitate 1 3. Histograma nivelurilor de intensitate 3.1. Introducere În această lucrar

Logică și structuri discrete Logică propozițională Marius Minea marius/curs/lsd/ 3 noiembrie 2014

LUMINIŢA SCRIPCARIU

PowerPoint Presentation

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

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

Analiză de flux de date 29 octombrie 2012

Aggregating Data

Capitole Speciale de Informatică Curs 1: Extragerea informaţiilor. Modelul boolean şi modelul boolean extins 27 septembrie 2018 Extragerea informaţiil

Logică și structuri discrete Relații. Funcții parțiale Marius Minea marius/curs/lsd/ 20 octombrie 2014

1

Modelarea si Simularea Sistemelor de Calcul

Secţiunea 7-8 începători Concurs online de informatică Categoria PROGRAMARE PROBLEMA 1 ID 100 puncte Calculatoarele trebuie să se recunoască în rețeau

PPSD

Tablouri (continuare)

Introducere în limbajul JavaScript

PROGRAMARE ORIENTATA PE OBIECTE

Laborator 7: PROIECTAREA BAZELOR DE DATE SUBPROGRAME in PL/SQL (partea I - proceduri) Un subprogram este un bloc PL/SQL cu nume (spre deosebire de blo

Transcriere:

12. Tipuri de date derivate direct - Tipul pointer Tipurile de date derivate direct sunt tipuri de date create pe baza unor tipuri de date existente. In limbajul C, un astfel de tip, nestructurat (simplu), este tipul pointer. Pointerii reprezintă adrese ale unor zone de memorie. Ei se utilizează pentru a face referire la entităţi (variabile, funcţii) din memorie cunoscute prin adresele lor. Pentru termenul de pointer se mai folosesc şi următoarele denumiri echivalente : referinţă, reper, localizator, indicator de adresă. Noţiunea de pointer joacă un rol extrem de important în programarea în C deoarece permite efectuarea de calcule complexe folosind adrese, operaţii care, până la apariţia C-ului, erau proprii doar limbajelor de asamblare. Dintre beneficiile care s-au obţinut prin introducerea pointerilor amintim: - transferul adecvat al parametrilor de ieşire ai funcţiilor - posibilitatea alocării dinamice de memorie; - posibilitatea folosirii funcţiilor ca parametri ai unor altor funcţii; - înlocuirea expresiilor cu indici prin expresii cu pointeri. 12.1. Declaraţia de pointer şi tipul pointer Un pointer este asociat unui tip de date sau tipului void. În general dacă tip este un tip de date, un pointer identificator către tipul tip se introduce printr-o declaraţie de forma: declaratie_variabila_pointer tip * identificator ; Figura 12.1 Declaraţia de variabilă de tip pointer Tipul tip precizează în acest caz tipul datelor stocate la adresele specificate de variabila de tip pointer. Comparând forma declaraţiei anterioare cu sintaxa generală a declaraţiei unei variabile, rezultă faptul că tip* reprezintă un nou tip de date, numit tip derivat, tipul pointer către tip.

În consecinţă o variabilă de tip pointer are ca valori adrese ale unor date de tipul tip (sau ca exprimare echivalentă, pointează spre tipul tip). În cazul în care o variabilă de tip pointer conţine adresa zonei de memorie alocată unei alte variabile x (evident de tipul tip) se mai spune că ea pointează spre x. Operatorul * se numeşte operator de dereferenţiere (indirectare) şi el este opusul operatorului de referenţiere (adresă), &. Aplicat unei variabile de tip pointer, operatorul * furnizează valoarea stocată în zona de memorie a cărei adresă este conţinută în pointer. Operatorul * are aceeaşi prioritate cu operatorii unari şi se asociază de la dreapta la stânga. Reamintim faptul că operatorul adresă, &, se aplică unei variabile, furnizând adresa acesteia (adresa zonei de memorie în care ea este depozitată). Există situaţii în care dorim ca un pointer să poată fi utilizat cu tipuri diferite de date, astfel încât în declaraţia de pointer nu putem specifica explicit un tip, ca în cazurile de mai sus. De aceea se utilizează în poziţia tipului, tipul void. Specificatorul de format pentru afişarea pointerilor este %p. Pointerii către void nu pot fi utilizaţi ca atare pentru a referi conţinutul zonelor de memorie către care pointează. Este necesară în prealabil o conversie explicită de tip pentru a preciza tipul datei către care pointează un astfel de pointer. Utilizarea tipului pointer către void asigură o flexibilitate mare în utilizarea pointerilor. Cu toate acestea ea poate constitui o potenţială sursă de erori în cazul unor utilizări abuzive. Programatorul trebuie să ştie în orice moment ce fel de tip de pointer este valoarea atribuită variabilei pointer de tip pointer către void. 12.2. Transferul parametrilor de ieşire în C Aşa cum s-a arătat transferul parametrilor în C se realizează prin valoare, parametrilor formali, pentru care se rezervă separat spaţiu de memorie, li se atribuie valorile parametrilor efectivi de apel corespunzători. Când se doreşte modificarea valorii parametrului efectiv ca urmare a apelului unei funcţii, deci practic când acesta este un parametru de ieşire, trebuie să transmitem funcţiei adresa variabilei ce reprezintă parametrul efectiv, iar în corpul funcţiei să folosim operatorul de dereferenţiere.

Atunci când parametrul este nume de tablou, acest deziderat este îndeplinit, deoarece în C numele unui tablou este o adresă, respectiv adresa primului element al tabloului. Folosind deci pointeri putem obţine efectele apelului prin referinţă: parametrul formal este un pointer căruia îi corespunde la apel o adresă. Facem observaţia că transferul parametrilor rămâne în continuare prin valoare, dar ceea ce se transmite funcţiei este valoarea adresei parametrului cu care se operează. 12.3. Legătura dintre pointeri şi tablouri Aşa cum s-a arătat, în C numele unui tablou este o adresă şi anume adresa primului element al tabloului. Rezultă deci că numele unui tablou este un pointer, dar, în acest caz, un pointer constant. În consecinţă, un parametru formal ce corespunde unui parametru efectiv care este un tablou unidimensional de tipul tip poate fi declarat fie ca tablou cu elemente de tipul tip, fie ca un pointer către tipul tip. 12.4. Aritmetica pointerilor Operaţiile aritmetice permise asupra pointerilor sunt : 1. incrementarea/decrementarea 2. adunarea/scăderea unui întreg la/dintr-un pointer 3. compararea a doi pointeri 4. diferenţa a doi pointeri 12.4.1. Operaţia de incrementare/decrementare Operatorii corespunzători acestor operaţii sunt ++ respectiv -- care se pot folosi atât în notaţie prefixată cât şi în notaţie postfixată. Efectul aplicării acestor operatori asupra unor operanzi de tip pointer este creşterea/micşorarea adresei ce reprezintă valoarea operandului cu un număr de octeţi egal cu cel necesar pentru a memora o dată de tipul celei către care pointează operandul. În general, în cazul unui pointer către tip declarat cu : tip *p, incrementarea sau decrementarea presupune modificarea valorii p cu sizeof(tip) octeţi.

12.4.2. Operaţia de adunare/scădere a unui întreg la/dintr-un pointer În cazul în care p este un pointer către tipul tip şi n este un număr întreg, cum adunarea/scăderea lui n din p poate fi privită ca o adunare/scădere repetată de n ori a unei unităţi, rezultă că,în acest caz, valoarea lui p se modifică cu n*sizeof(tip) octeţi. Rezultă deci că variabilele indexate se pot înlocui cu expresii cu pointeri, ceea ce conduce la optimizarea codului. Observaţie : Operaţiile 3 şi 4 sunt garantate în ANSII C în cazul în care pointerii se menţin în limitele unui aceluiaşi tablou. Este permisă poziţionarea pointerului pe poziţia imediat următoare ultimului element al tabloului. 12.4.3. Operaţia de comparare a doi pointeri Doi pointeri care pointează spre elementele unui aceluiaşi tablou pot fi comparaţi folosind operatorii de relaţie şi de egalitate. Se poate de asemenea face comparaţia cu pointerul NULL. Astfel dacă p pointează către t[i] şi q către t[j], i şi j strict mai mici decât dimensiunea maximă a tabloului, sunt legale comparaţiile : p<q p>q p==q p<=q p>=q p!=q 12.4.4. Operaţia de scădere a doi pointeri Operaţia de diferenţă a doi pointeri rezultă imediat din cea de adunare/scădere a unui întreg dintr-un pointer. Astfel dacă p pointează către t[i] şi q către t[i+n] unde n este un întreg, diferenţa q - p este egală cu n.

Un parametru formal ce corespunde unui parametru efectiv care este un tablou unidimensional de tipul tip poate fi declarat fie ca tablou cu elemente de tipul tip, fie ca un pointer către tipul tip. Exemplu : Să se proiecteze o funcţie care să calculeze lungimea unui şir de caractere. #include <stdio.h> #include <string.h> int lung(char s[]) int i; for(i=0;s[i]!='\0';i++) ; return i; int lung_p(char *p) char *q; for(q=p;*q!='\0';q++) ; return q-p; int main(void) char a[]="acesta este un sir"; printf("i %d\tii %d\tiii %d\n",lung(a),lung_p(a),strlen(a)); return 0 ;

12.5. Alocarea dinamică de memorie Limbajul C oferă utilizatorului posibilitatea de a aloca memorie, prin comenzi specifice, în timpul execuţiei programului, într-o zonă de memorie specială numită memoria heap, rezervarea de memorie numindu-se în acest caz alocare dinamică. Cea mai utilizată funcţie în acest scop este malloc cu prototipul (în stdlib.h): void * malloc(unsigned n) ; Funcţia malloc alocă în memoria heap o zonă contiguă de n octeţi, returnând un pointer către void ce reprezintă adresa de început a zonei astfel alocate, sau pointerul NULL în cazul în care alocarea nu a fost posibilă. Zona de memorie alocată în urma apelului funcţiei malloc se eliberează cu ajutorul funcţiei free al cărei prototip este (în stdlib.h): void free(void * p) ; unde p este un pointer nenul rezultat în urma apelului funcţiei malloc. Memento : Un parametru formal ce corespunde unui parametru efectiv care este un tablou unidimensional de tipul tip poate fi declarat fie ca tablou cu elemente de tipul tip, fie ca un pointer către tipul tip Exemplul 1. Să se proiecteze şi apeleze adecvat o funcţie care citeşte un vector cu n elemente de tip double. Funcţia va avea un parametru suplimentar, numele vectorului şi va returna numărul de elemente citite corect.

#include <stdio.h> #include <stdlib.h> #define MAX 100 int pndcit(double *p, int n, const char *s) int j=0; double *q=p+n; while (p<q) printf("elementul %s[%d]= ",s,j); if (scanf("%lf",p)!=1) fflush(stdin); break; p++; j++; return j;

int main(void) int i,n,nr; double x[max],*p; printf("numarul de elemente ale vectorului x (<=%d)= ", MAX); if(scanf("%d",&n)!=1 n<=0 n>max) printf("date eronate!\n"); exit(1); printf("elementele vectorului\n"); if ((nr=pndcit(x,n,"x"))!=n) printf("atentie : S-au citit doar %d elemente\n",nr); printf("vectorul x\n"); for (i=0;i<nr;i++) printf("%10g %c",x[i],i%6==5 i==nr-1?'\n':' '); printf("vectorul x\n"); p=x; for (i=0;i<nr;i++) printf("%10g %c",*p++,i%6==5 i==nr-1?'\n':' '); double *pv; int nd; printf("nr. de elem. ale vectorului alocat dinamic, nd= "); if(scanf("%d",&nd)!=1 nd<=0) printf("date eronate!\n"); exit(1); pv=(double *)malloc(nd*sizeof(double)); if(!pv) printf("memorie insuficienta!\n"); exit(1); printf("elementele vectorului\n"); if ((nr=pndcit(pv,nd,"v"))!=nd) printf("atentie : S-au citit doar %d elemente\n",nr); printf("vectorul V\n"); for (i=0;i<nr;i++) printf("%10g %c",pv[i],i%6==5 i==nr-1?'\n':' '); printf("vectorul V\n"); p=pv; for (i=0;i<nr;i++) printf("%10g %c",*p++,i%6==5 i==nr-1?'\n':' '); free(pv); return 0;

12.6. Tablouri de pointeri Pointerii fiind tipuri de date, cu ajutorul lor se pot forma tipuri de date structurate, ca de exemplu tablouri. Tablourile de pointeri se utilizează frecvent la prelucrarea şirurilor de caractere, permiţând o tratare a acestora în mod unitar. Este mult mai avantajos să se definească un tablou de pointeri, fiecare element al tabloului fiind un pointer către un şir de caractere decât să se definească direct un tablou de şiruri de caractere. Exemplul 2. Să se scrie un program care să permită memorarea şi afişarea ulterioară a maximum 50 de cuvinte preluate de la consolă. Sfârşitul sesiunii este marcat prin acţionarea sfârşitului de fişier de la consolă.

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCUV 50 char *MemSir(char *); int main(void) char *tabptr[maxcuv]; int i,j; char temp[255]; printf("introduceti cuvintele ") ; printf(" (max %d, CTRL/Z pt. a incheia)\n", MAXCUV); for (i=0;scanf("%s",temp)==1 && i<maxcuv; i++) if((tabptr[i]=memsir(temp))==0) printf("memorie insuficienta la alocarea sirului %d\n",i); break; for (j=0;j<i;j++) printf("%s\n",tabptr[j]); if((j+1)%23==0) printf("actionati o tasta pt. a continua..\n"); getch(); for(i=0;j<i;j++) free(tabptr[j]); return 0; void strcopy(char *d, char *s) while ( (*d++ = *s++)!= '\0') ; char *MemSir(char *s) char *p; if((p=(char *)malloc(strlen(s)+1))!=0) strcopy(p,s); return p; return NULL;

12.7. Pointeri către tablouri Evident un pointer va putea indica adresa de început a unei zone de memorie ce conţine un tablou. De exemplu, declaraţia unui pointer p către un tablou cu 10 elemente de tipul tip se scrie ca mai jos : tip (*p)[10]; Prezenţa parantezelor este obligatorie. Astfel de pointeri către tablouri vor avea ca unitate de operare în cazul operaţiilor cu pointeri numărul de octeţi necesari pentru memorarea tabloului (10*sizeof tip în cazul exemplului de mai sus).