This is an old revision of the document!


Laboratorul 07 - Funcții cu pointeri; Șiruri de caractere

În acest laborator veţi învăţa să:

  • Trimiteţi parametri prin adresă.
  • Utilizaţi şiruri de caractere şi funcţii pentru şiruri de caractere.
  • Definiţi funcţii care prelucrează şiruri de caractere.

Pointeri

Atunci când definiţi o variablilă, compilatorul va fi informat despre 2 lucruri:

  • numele variabilei
  • tipul variabilei

De exemplu, în declaraţia:

int n;

compilatorul va rezerva o zonă de memorie pentru această variabilă, de dimensiune sizeof(int) (4 Bytes, pe arhitecturi de 32bit), şi va asocia respectivei zone de memorie numele n.

Atunci când se face o atribuire,

n = 7;

în respectiva zonă de memorie va fi înscrisă noua valoare, 7.

Numele variabilelor în C au sens doar în domeniul în care au fost definite acele variabile. Acest domeniu de definiţie al unei variabile poartă numele de scope. De exemplu, în programul de mai jos, există 4 variabile distincte, toate purtând numele n!

#include <stdio.h>
 
int n; /* Variabila 1 */
 
int f(int n /* Variabila 2 */) {
   n = 42; /* Variabila 2 */
}
 
int g() {
   int n; /* Variabila 3 */
   n = 42; /* Variabila 3 */
}
 
int h() {
   n = 42; /* Variabila 1 */
}
 
int main() {
   int n; /* Variabila 4 */
   n = 42; /* Variabila 4 */
   return 0;
}

Observăm astfel, că nu putem accesa direct prin nume variabile definite într-o altă funcţie, deoarece numele nu au sens decât în interiorul funcţiei în care au fost declarate. Parametrii formali ai unei funcţii nu sunt altceva decât nişte variabile locale, care în momentul apelului primesc o copie a valorilor cu care a fost apelată funcţia. O funcţie de incrementare scrisă astfel:

void incorrect_increment(int n) {
   /* Se va incrementa doar o copie a valorii cu care a fost apelată funcţia! */
   n++;
}

Nu face decât să incrementeze o variaiblă locală funcţiei, efect ce nu poate fi observat din exterior!

Pentru a accesa un obiect definit într-o altă funcţie, îl putem referi, totuşi, folosindu-ne de adresa acestuia în memorie. Adresele în C poartă numele de pointeri.

Pentru a obţine adresa unei variabile, vom folosi operatorul & pus în faţa numelui variabilei, iar pentru a ne referi la valoarea memorată la o anumită adresă, vom folosi operatorul *.

Să ne amintim că pentru a citi valori cu ajutorul funcţiei scanf, trebuia să precedăm numele variabilelor citite cu operatorul &. Acest lucru se întâmplă deoarece din interiorul funcţiei scanf, unde se produce citirea, nu sunt accesibile prin nume variabilele definite în funcţia apelantă.

O funcţie care incrementează în mod corect o valoare se va scrie astfel:

void correct_increment(int* pn) {
   /* Vom incrementa aici variabila care este memorată la adresa pn */
   (*pn)++;
}

iar pentru a incrementa o variabilă numită n, va trebui să comunicăm funcţiei de incrementare locaţia acestei variabile astfel:

int main() {
   int n;
   n = 0;
   correct_increment(&n); /* Incrementăm valoarea memorată la adresa variabilei n. */
   return 0;
}

Putem să ne imaginăm memoria virtuală a calculatorului ca pe un vector foarte lung de Bytes, iar un pointer ca pe un indice în acel vector. Dimensiunea unui pointer (deci a unei adrese de memorie) depinde de tipul sistemului de operare.

Pe sistemele de operare de 32bit, fie ele Windows, Linux, Mac OS, sau altele, dimensiunea oricărui pointer va fi de 32 biţi, adică 4 Bytes, cu valori acceptate între 0 şi 2^32-1, adică un total de 4GB.

programare-cc/laboratoare/07.1605040648.txt.gz · Last modified: 2020/11/10 22:37 by bogdan.nutu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0