Laborator 5 - Pointeri. Abordarea lucrului cu tablouri folosind pointeri

Obiectivele laboratorului

În acest laborator vom studia:

Materiale utile

Exerciții

  1. Pentru fiecare subpunct, realizați un program prin care să aflați/confirmați soluția.

    1.1. Cât este valoarea adresei lui a după executarea codului de mai jos? Dar a lui b?

    De ce primim segmentation fault dacă încercăm să dereferentiem pointerii?

Exemplu

int *a = 0x00;
int *b = a;
++a;

    1.2. Citiți un vector v cu n elemente. Realizați un program care să printeze pe ecran, pe câte o linie, un element și adresa acestuia.

Exemplu

// exemplu de afișare pentru o linie
v[3] = 5, &v[3] = 0x123

Care este relația între adresele printate? Justificați.

    1.3. Fie a o matrice cu n linii și m coloane, unde elemente sale sunt de tipul double. Folosind calcul de pointeri, setați un pointer double *p; să pointeze la a[2][3] (NU aveți voie să folosiți operatorul [] pentru a accesa respectivul element din matrice). Testați modificând elementul și comparând p cu adresa lui a[2][3].

  1. Scrieți o funcție care realizează citirea unui vector (dimensiune + elemente). Funcția va primi ca parametri:

    Tipul de return al funcției este void.

    2.1. Cum arată semnătură? De ce primul parametru e tot un pointer?

    2.2. Implementați funcția.

  1. Realizați o funcție care interschimbă două variabile de tip int.

    3.1. Ce tip trebuie să aibă cei 2 parametri și cum se va apela funcția?

    3.2. Implementați funcția și demonstrați că funcționează.

Exemplu

int p = 3, q = 9;
// print p, q => 3, 9
swap_int(&p, &q);
//print p, q => 9, 3
  1. Realizați o funcție care interschimbă două variabile de tip int * (pointer la întreg). Demonstrați că funcționează.

Exemplu

int *p = 0x123, *q = 0x456;
// print p, q => 0x123, 0x456
swap_ptr(&p, &q);
// print p, q => 0x456, 0x123
  1. Realizati funcția my_memcpy care va copia un număr num de bytes dintr-o locație sursă (src) într-o locație destinație (dst).

Exemplu

void my_memcpy(void *dst, const void *src, int num);

    5.1. De ce dst si src sunt pointeri la void*?

    5.2. De ce src pointează către o zonă constantă de memorie? De ce nu se întâmplă același lucru și pentru dst?

    5.3. Implementați și testați funcția folosind mai multe tipuri de date.

Exemplu

// exemplu cu int
int a = 123; // initializat
int b; 	     // neinitializat
my_memcpy(&b, &a, sizeof(a));
// print b

// exemplu cu vector de int
int src[100] = {1, 2, 3}; // initializat
int dst[100];             // neinitializat
my_memcpy(dst, src, sizeof(src));
// afisare elemente din vector destinatie

// exemplu cu vector de double
int n;
double src[100];
// scanf n, src => initializare
double dst[100];               // neinitializat
my_memcpy(dst, src, n * sizeof(double));
// afisare elemente din vector destinatie
  1. [BONUS] În reprezentarea unui număr întreg pe mai mulți octeți (de exemplu un short int sau un int), se pune problema de ordine pentru octeți în memorie. Astfel, există două moduri de reprezentare:

Mai multe informații aici: https://www.techtarget.com/searchnetworking/definition/big-endian-and-little-endian

Se cere să se scrie un program (oricât de simplu) care să determine endianness-ul calculatorului pe care este compilat și rulat. Să se afișeze un mesaj corespunzător pe ecran.

 

Studiu de caz

Pentru aprofundarea lucrului cu pointeri și înțelegerea mai bună a conceptelor prezentate în acest laborator, vă recomandăm să parcurgeți acasă toate materialele din arhiva demo_ptr.zip de pe moodle. Aceasta conține exerciții rezolvate și explicate, dar și alte programe demonstrative.