<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ro">
	<id>http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cbira</id>
	<title>WikiLabs - Contribuții utilizator [ro]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cbira"/>
	<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php/Special:Contribu%C8%9Bii/Cbira"/>
	<updated>2026-04-12T16:03:43Z</updated>
	<subtitle>Contribuții utilizator</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_4_:_Memoria_ROM&amp;diff=8322</id>
		<title>CID aplicatii 4 : Memoria ROM</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_4_:_Memoria_ROM&amp;diff=8322"/>
		<updated>2026-04-06T13:12:43Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Anexa1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Memoria ROM==&lt;br /&gt;
Memoria este un dispozitiv electronic utilizat pentru stocarea datelor. Aceasta poate fi de mai multe feluri, având diverse caracteristici, cum ar fi capacitatea de a-și păstra sau nu conținutul după întreruperea alimentării sau capacitatea de a-și modifica sau nu conținutul după terminarea procesului de producție. &lt;br /&gt;
&lt;br /&gt;
Memoria  ROM (Read-Only  Memory) este un circuit combinațional folosit pentru stocarea unor date ce pot fi accesate cu ajutorul unei intrări de adresă. Asa cum sugerează și numele, memoria ROM clasică nu poate fi modificată. În plus, datorită modului în care este implementată, ea își păstrează conținutul după întreruperea alimentării (este nevolatilă).  &lt;br /&gt;
&lt;br /&gt;
Pentru a înțelege termenul de memorie, putem face următorul exercițiu de imaginație: să ne gândim la un dulap cu mai multe sertare. Conținutul memoriei este reprezentat de conținutul sertarelor, iar adresele sunt reprezentate de etichetele lipite pe aceste sertare pentru a le identifica. Dacă avem nevoie de conținutul unui sertar, va trebui să știm eticheta aferentă acestuia (adresa).&lt;br /&gt;
&lt;br /&gt;
O memorie ROM are următorii parametri: numărul de biți ai adresei, care este legat de numarul de locații de memorie (cu n biți de adresă putem forma 2&amp;lt;sup&amp;gt;𝑛&amp;lt;/sup&amp;gt; combinații diferite, deci putem accesa maxim 2&amp;lt;sup&amp;gt;𝑛&amp;lt;/sup&amp;gt; locații de memorie) și dimensiunea locației de memorie, care ne spune cât de multă informație poate stoca o locație de memorie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Să urmărim exemplul din figura următoare:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:ROM memory.PNG ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aici, adresa are dimensiunea de 4 biți, asadar putem accesa cu aceasta 16 locații diferite de memorie. Dimensiunea fiecărei locații este de 8 biți, așadar fiecare locație de memorie poate stoca numere de 8 biți. Spunem că memoria ROM este o memorie 16x8.  Capacitatea acestei memorii este de 16 x 8 biți = 128 biți.&lt;br /&gt;
&lt;br /&gt;
== Exemple ==&lt;br /&gt;
&lt;br /&gt;
Următoarele circuite pot fi văzute în 2 moduri: ca memorii de tip ROM, cu date de ieșire care depind de adresa (data de intrare) de la care citești cât și ca circuite combinationale a căror ieșire este generată prin porți din intrare.&lt;br /&gt;
&lt;br /&gt;
=== Exemplul 1: Decodorul ===&lt;br /&gt;
Decodorul este circuitul care, pentru o anumită valoare a intrării, va genera la ieșire un șir binar care conține 1 pe poziția cu indicele egal cu valorea intrării și 0 in rest. De exemplu, decodorul de mai jos pe 2 biți va avea următoarea corespondență intrare-iesire:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;in&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;out&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2&amp;#039;b00 || 4&amp;#039;b0001&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b01 || 4&amp;#039;b0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b10 || 4&amp;#039;b0100&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b11 || 4&amp;#039;b1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Decoder.PNG ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Vom implementa acest circuit ca memorie ROM. &amp;quot;in&amp;quot; are rolul de adresa iar out are rolul de date de la adresa respectiva. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Decoder(&lt;br /&gt;
  input logic [1:0] in,&lt;br /&gt;
  output logic [3:0] out&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  always_comb begin&lt;br /&gt;
    case(in)&lt;br /&gt;
      2&amp;#039;b00: out = 4&amp;#039;b0001; //la adresa 0 avem valoarea 1&lt;br /&gt;
      2&amp;#039;b01: out = 4&amp;#039;b0010; //la adresa 1 avem valoarea 2&lt;br /&gt;
      2&amp;#039;b10: out = 4&amp;#039;b0100; //la adresa 2 avem valoarea 4&lt;br /&gt;
      2&amp;#039;b11: out = 4&amp;#039;b1000; //la adresa 3 avem valoarea 8&lt;br /&gt;
      default: out = 4&amp;#039;b0000;&lt;br /&gt;
    endcase&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a modulului de test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Decoder_TB();&lt;br /&gt;
  logic [1:0] in_tb;&lt;br /&gt;
  logic [3:0] out_tb;&lt;br /&gt;
  &lt;br /&gt;
  integer idx;&lt;br /&gt;
&lt;br /&gt;
  initial begin&lt;br /&gt;
    for(idx=0; idx&amp;lt;4; idx = idx + 1) begin&lt;br /&gt;
      in_t = idx;&lt;br /&gt;
      #1;&lt;br /&gt;
    end &lt;br /&gt;
    #2 $stop();&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  Decoder DUT(&lt;br /&gt;
    .in(in_tb),&lt;br /&gt;
    .out(out_tb)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observații:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Circuitul Decoder va avea o intrare pe 2  biți, care va reprezenta adresa memoriei ROM și o iesire pe 4 biți, reprezentând conținuturile memoriei ROM corespunzătoare fiecărei combinații de la intrare.&lt;br /&gt;
* Chiar dacă în interiorul instrucțiunii &amp;#039;&amp;#039;case&amp;#039;&amp;#039; se acoperă toate cazurile posibile (toate combinațiile de 2 biți), este bine sa punem și un &amp;#039;&amp;#039;default&amp;#039;&amp;#039; pentru a evita inserarea în locul circuitului combinațional dorit (aici, memoria ROM) a unui latch.&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Transcodorul===&lt;br /&gt;
Trancodorul este o memorie ROM care asociază unui anumit cod de intrare, reprezentat de adresă, un anumit cod de ieșire, reprezentat de conținutului locației de memorie asociată acelei adrese.&lt;br /&gt;
&lt;br /&gt;
In acest exemplu, vom folosi transcodorul pentru a realiza un modul ce controlează afișajul cu 7 segmente. Acest dispozitiv de afișare este format, așa cum sugerează și numele, din 7 segmente ce pot fi controlate separat. Putem aprinde sau stinge fiecare segment controlând tensiunea aplicată pe acesta. Pentru acest afișaj, comanda este în logică negativă: aplicând  0  logic pe un segment acesta se va aprinde, iar aplicând 1 logic, acesta se va stinge.&lt;br /&gt;
&lt;br /&gt;
Structura unui afisaj cu 7 segmente este prezentată în imaginea de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:7LED display.PNG | 200px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza controlul afișării, avem nevoie de o memorie ROM ce trebuie să asocieze codului binar al fiecărui element ce poate fi afișat un șir de biți care sting sau aprind diversele segmente ale afișajului, astfel încât să apară imaginea elementului dorit.&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta, de exemplu, cele 16 numere hexa, segmentele  trebuie  aprinse  conform Anexei 1. De exemplu, pentru primele 8 numere (0 până la 7), tabelul de asociere este următorul:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Număr&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Cod intrare&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Șir de afisare&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 4&amp;#039;b0000 || 7&amp;#039;b100_0000&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 4&amp;#039;b0001 || 7&amp;#039;b111_1001&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 4&amp;#039;b0010 || 7&amp;#039;b010_0100&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 4&amp;#039;b0011 || 7&amp;#039;b011_0000&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 4 || 4&amp;#039;b0100 || 7&amp;#039;b001_1001&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 5 || 4&amp;#039;b0101 || 7&amp;#039;b001_0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 6 || 4&amp;#039;b0110 || 7&amp;#039;b000_0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 7 || 4&amp;#039;b0111 || 7&amp;#039;b111_1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a modulului Display7Seg&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Display7Seg(&lt;br /&gt;
  input logic [3:0] in,&lt;br /&gt;
  output logic [6:0] out&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  always_comb begin&lt;br /&gt;
    case(in)&lt;br /&gt;
      4&amp;#039;d0: out = 7&amp;#039;b1000000;&lt;br /&gt;
      4&amp;#039;d1: out = 7&amp;#039;b1111001;&lt;br /&gt;
      4&amp;#039;d2: out = 7&amp;#039;b0100100;&lt;br /&gt;
      4&amp;#039;d3: out = 7&amp;#039;b0110000;&lt;br /&gt;
      4&amp;#039;d4: out = 7&amp;#039;b0011001;&lt;br /&gt;
      4&amp;#039;d5: out = 7&amp;#039;b0010010;&lt;br /&gt;
      4&amp;#039;d6: out = 7&amp;#039;b0000010;&lt;br /&gt;
      4&amp;#039;d7: out = 7&amp;#039;b1111000;&lt;br /&gt;
      default: out = 7&amp;#039;b0000110;&lt;br /&gt;
    endcase &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții:==&lt;br /&gt;
=== Exercițiul 1===&lt;br /&gt;
Completați codul din Exemplul 2 astfel încât să se poată reprezenta toate numerele în bază 16 (hexazecimal), conform Anexei 1&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2===&lt;br /&gt;
Un procesor are nevoie de un șir de biți numit instrucțiune pentru a știi ce trebuie să facă. Această instrucțiune codează în șirul său de biți toate informațiile necesare. &lt;br /&gt;
&lt;br /&gt;
De exemplu, pentru un grup de instrucțiuni care operează cu registre, aceste informații pot fi:&lt;br /&gt;
* codul instrucțiunii (operation code - opcode): un șir de biți care ne spune ce operație se execută.&lt;br /&gt;
* destinația: un șir de biți care codează numărul registrului destinație.&lt;br /&gt;
* sursa1: un șir de biți care codează numărul registrului folosit ca operand 1.&lt;br /&gt;
* sursa2: un șir de biți care codează numărul registrului folosit ca operand 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vom considera codul operației pe 4 biți, ceea ce inseamnă ca putem avea 16 instrucțiuni diferite. In plus, câmpurile care codează destinația și cei doi operanzi vor avea fiecare câte 4 biți, ceea ce inseamnă că vom avea 16 registre cu care putem lucra (R0 ... R15). Adunând dimensiunile fiecărui câmp, vom obține o instrucțiune pe 16 biți.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Instrucțiunile și codul operațiilor:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Vom considera ca procesorul nostru elementar poate suporta următoarele instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Operație&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Cod operație&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Sintaxă&amp;#039;&amp;#039;&amp;#039; ||&amp;#039;&amp;#039;&amp;#039;Descriere&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| ADD || 4&amp;#039;b0000 || ADD Rd Rs1 Rs2 || Rd = Rs1 + Rs2 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| SUB || 4&amp;#039;b0001 || SUB Rd Rs1 Rs2 || Rd = Rs1 - Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| OR || 4&amp;#039;b0010 || OR Rd Rs1 Rs2 || Rd = Rs1 OR Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| AND || 4&amp;#039;b0011 || AND Rd Rs1 Rs2 || Rd = Rs1 AND Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| LOADC || 4&amp;#039;b0100 || LOADC Rd, const || Rd = const&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pentru instrucțiunile prezentate mai sus, vom avea următoarele moduri de codare (de împărțire a informației în cadrul instrucțiunii):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Codare instructiune.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Registrele:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Cele 16 registre vor fi codate cu un număr egal cu indexul său. De exemplu, R0 va avea codul 4&amp;#039;b000, R1 va avea codul 4&amp;#039;b0001 și așa mai departe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Considerând cele spuse mai sus, vom avea următoarele exemple de instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Exemple codare instructiuni.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Având toate informațiile de mai sus, descrieți o memorie ROM cu adresă pe 4 biți și locații pe 16 biți, care să conțină următorul program, începând cu adresa 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LOADC R0, 2h&lt;br /&gt;
LOADC R1, 5h&lt;br /&gt;
LOADC R2, 7h&lt;br /&gt;
ADD R3, R1, R0&lt;br /&gt;
SUB R4, R2, R1&lt;br /&gt;
OR R5, R3, R4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3===&lt;br /&gt;
Proiectați un Codor Cezar cu cheie fixă sub forma unei memorii ROM. &lt;br /&gt;
&lt;br /&gt;
Un Codor Cezar preia un mesaj și codează independent fiecare literă a acestuia pentru a obține un mesaj cifrat. El se folosește de o cheie fixă care se adună la fiecare literă a mesajului. De exemplu, pentru cheia &amp;quot;+3&amp;quot;: a-&amp;gt;d; b-&amp;gt;e; c-&amp;gt;f;...; y-&amp;gt;b; z-&amp;gt;c. Observați că atunci când alfabetul a ajuns la capăt, se reia de la început. &lt;br /&gt;
Pentru decodare, se va folosi procedura inversă: pentru fiecare literă, vom aplica cheia cu semn invers (în exemplul nostru, cheia de decodare este &amp;quot;-3&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
Observații, sfaturi, task-uri suplimentare:&lt;br /&gt;
* Codorul va putea prelucra doar litere mici și spațiu gol (acesta rămâne neschimbat).&lt;br /&gt;
* Cel mai usor mod de a scrie această funcționalitate este folosind un bloc de tip &amp;#039;&amp;#039;case&amp;#039;&amp;#039;.&lt;br /&gt;
* Pentru testare, se pot folosi în testbench variabile de tip &amp;#039;&amp;#039;logic&amp;#039;&amp;#039; pe 8 biți, astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [7:0] litera;&lt;br /&gt;
litera = &amp;quot;A&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Avansat: În SystemVerilog există și tipul de date &amp;#039;&amp;#039;string&amp;#039;&amp;#039;, ceea ce permite parcurgerea cu un &amp;#039;&amp;#039;for&amp;#039;&amp;#039; a mesajului. În Verilog clasic, astfel de parcurgeri sunt posibile, dar sintaxa este mai complicată.&lt;br /&gt;
* Se va folosi codul ASCII pentru valori. Pentru o ușoara vizualizare a datelor în simulare, se poate schimba radix-ul în ASCII. &lt;br /&gt;
* Avansat: Pentru a testa automat codul, se poate instanția încă un modul în testbench cu aceeași funcționalitate pe post de &amp;quot;golden model&amp;quot;. Acest modul nu trebuie să fie sintetizabil și atunci sintaxa permite mai multă libertate (cum ar fi operația de modulo &amp;quot;%&amp;quot;, utilă pentru testare, dar care determină un circuit complicat dacă ar fi sintetizată). Ieșirile celor două module din testbench sunt apoi comparate pentru a se verifica că ambele implementări oferă același rezultat.&lt;br /&gt;
* Implementați și Decodorul Cezar și testați Codorul împreună cu acesta. Aveți grijă ca cele două module să aibă aceeași cheie.&lt;br /&gt;
&lt;br /&gt;
==Anexa1== &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Anexa1modificat9.png | 800px]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_4_:_Memoria_ROM&amp;diff=8321</id>
		<title>CID aplicatii 4 : Memoria ROM</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_4_:_Memoria_ROM&amp;diff=8321"/>
		<updated>2026-04-06T13:12:13Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Anexa1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Memoria ROM==&lt;br /&gt;
Memoria este un dispozitiv electronic utilizat pentru stocarea datelor. Aceasta poate fi de mai multe feluri, având diverse caracteristici, cum ar fi capacitatea de a-și păstra sau nu conținutul după întreruperea alimentării sau capacitatea de a-și modifica sau nu conținutul după terminarea procesului de producție. &lt;br /&gt;
&lt;br /&gt;
Memoria  ROM (Read-Only  Memory) este un circuit combinațional folosit pentru stocarea unor date ce pot fi accesate cu ajutorul unei intrări de adresă. Asa cum sugerează și numele, memoria ROM clasică nu poate fi modificată. În plus, datorită modului în care este implementată, ea își păstrează conținutul după întreruperea alimentării (este nevolatilă).  &lt;br /&gt;
&lt;br /&gt;
Pentru a înțelege termenul de memorie, putem face următorul exercițiu de imaginație: să ne gândim la un dulap cu mai multe sertare. Conținutul memoriei este reprezentat de conținutul sertarelor, iar adresele sunt reprezentate de etichetele lipite pe aceste sertare pentru a le identifica. Dacă avem nevoie de conținutul unui sertar, va trebui să știm eticheta aferentă acestuia (adresa).&lt;br /&gt;
&lt;br /&gt;
O memorie ROM are următorii parametri: numărul de biți ai adresei, care este legat de numarul de locații de memorie (cu n biți de adresă putem forma 2&amp;lt;sup&amp;gt;𝑛&amp;lt;/sup&amp;gt; combinații diferite, deci putem accesa maxim 2&amp;lt;sup&amp;gt;𝑛&amp;lt;/sup&amp;gt; locații de memorie) și dimensiunea locației de memorie, care ne spune cât de multă informație poate stoca o locație de memorie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Să urmărim exemplul din figura următoare:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:ROM memory.PNG ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aici, adresa are dimensiunea de 4 biți, asadar putem accesa cu aceasta 16 locații diferite de memorie. Dimensiunea fiecărei locații este de 8 biți, așadar fiecare locație de memorie poate stoca numere de 8 biți. Spunem că memoria ROM este o memorie 16x8.  Capacitatea acestei memorii este de 16 x 8 biți = 128 biți.&lt;br /&gt;
&lt;br /&gt;
== Exemple ==&lt;br /&gt;
&lt;br /&gt;
Următoarele circuite pot fi văzute în 2 moduri: ca memorii de tip ROM, cu date de ieșire care depind de adresa (data de intrare) de la care citești cât și ca circuite combinationale a căror ieșire este generată prin porți din intrare.&lt;br /&gt;
&lt;br /&gt;
=== Exemplul 1: Decodorul ===&lt;br /&gt;
Decodorul este circuitul care, pentru o anumită valoare a intrării, va genera la ieșire un șir binar care conține 1 pe poziția cu indicele egal cu valorea intrării și 0 in rest. De exemplu, decodorul de mai jos pe 2 biți va avea următoarea corespondență intrare-iesire:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;in&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;out&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2&amp;#039;b00 || 4&amp;#039;b0001&lt;br /&gt;
|- align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b01 || 4&amp;#039;b0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b10 || 4&amp;#039;b0100&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
|2&amp;#039;b11 || 4&amp;#039;b1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Decoder.PNG ‎| 400px]]&lt;br /&gt;
&lt;br /&gt;
Vom implementa acest circuit ca memorie ROM. &amp;quot;in&amp;quot; are rolul de adresa iar out are rolul de date de la adresa respectiva. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a circuitului&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Decoder(&lt;br /&gt;
  input logic [1:0] in,&lt;br /&gt;
  output logic [3:0] out&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  always_comb begin&lt;br /&gt;
    case(in)&lt;br /&gt;
      2&amp;#039;b00: out = 4&amp;#039;b0001; //la adresa 0 avem valoarea 1&lt;br /&gt;
      2&amp;#039;b01: out = 4&amp;#039;b0010; //la adresa 1 avem valoarea 2&lt;br /&gt;
      2&amp;#039;b10: out = 4&amp;#039;b0100; //la adresa 2 avem valoarea 4&lt;br /&gt;
      2&amp;#039;b11: out = 4&amp;#039;b1000; //la adresa 3 avem valoarea 8&lt;br /&gt;
      default: out = 4&amp;#039;b0000;&lt;br /&gt;
    endcase&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a modulului de test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
`timescale 1ns/1ps&lt;br /&gt;
&lt;br /&gt;
module Decoder_TB();&lt;br /&gt;
  logic [1:0] in_tb;&lt;br /&gt;
  logic [3:0] out_tb;&lt;br /&gt;
  &lt;br /&gt;
  integer idx;&lt;br /&gt;
&lt;br /&gt;
  initial begin&lt;br /&gt;
    for(idx=0; idx&amp;lt;4; idx = idx + 1) begin&lt;br /&gt;
      in_t = idx;&lt;br /&gt;
      #1;&lt;br /&gt;
    end &lt;br /&gt;
    #2 $stop();&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  Decoder DUT(&lt;br /&gt;
    .in(in_tb),&lt;br /&gt;
    .out(out_tb)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Observații:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Circuitul Decoder va avea o intrare pe 2  biți, care va reprezenta adresa memoriei ROM și o iesire pe 4 biți, reprezentând conținuturile memoriei ROM corespunzătoare fiecărei combinații de la intrare.&lt;br /&gt;
* Chiar dacă în interiorul instrucțiunii &amp;#039;&amp;#039;case&amp;#039;&amp;#039; se acoperă toate cazurile posibile (toate combinațiile de 2 biți), este bine sa punem și un &amp;#039;&amp;#039;default&amp;#039;&amp;#039; pentru a evita inserarea în locul circuitului combinațional dorit (aici, memoria ROM) a unui latch.&lt;br /&gt;
&lt;br /&gt;
===Exemplul 2: Transcodorul===&lt;br /&gt;
Trancodorul este o memorie ROM care asociază unui anumit cod de intrare, reprezentat de adresă, un anumit cod de ieșire, reprezentat de conținutului locației de memorie asociată acelei adrese.&lt;br /&gt;
&lt;br /&gt;
In acest exemplu, vom folosi transcodorul pentru a realiza un modul ce controlează afișajul cu 7 segmente. Acest dispozitiv de afișare este format, așa cum sugerează și numele, din 7 segmente ce pot fi controlate separat. Putem aprinde sau stinge fiecare segment controlând tensiunea aplicată pe acesta. Pentru acest afișaj, comanda este în logică negativă: aplicând  0  logic pe un segment acesta se va aprinde, iar aplicând 1 logic, acesta se va stinge.&lt;br /&gt;
&lt;br /&gt;
Structura unui afisaj cu 7 segmente este prezentată în imaginea de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:7LED display.PNG | 200px]]&lt;br /&gt;
&lt;br /&gt;
Pentru a realiza controlul afișării, avem nevoie de o memorie ROM ce trebuie să asocieze codului binar al fiecărui element ce poate fi afișat un șir de biți care sting sau aprind diversele segmente ale afișajului, astfel încât să apară imaginea elementului dorit.&lt;br /&gt;
&lt;br /&gt;
Pentru a reprezenta, de exemplu, cele 16 numere hexa, segmentele  trebuie  aprinse  conform Anexei 1. De exemplu, pentru primele 8 numere (0 până la 7), tabelul de asociere este următorul:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Număr&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Cod intrare&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Șir de afisare&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 0 || 4&amp;#039;b0000 || 7&amp;#039;b100_0000&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 1 || 4&amp;#039;b0001 || 7&amp;#039;b111_1001&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 2 || 4&amp;#039;b0010 || 7&amp;#039;b010_0100&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 3 || 4&amp;#039;b0011 || 7&amp;#039;b011_0000&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 4 || 4&amp;#039;b0100 || 7&amp;#039;b001_1001&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 5 || 4&amp;#039;b0101 || 7&amp;#039;b001_0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 6 || 4&amp;#039;b0110 || 7&amp;#039;b000_0010&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| 7 || 4&amp;#039;b0111 || 7&amp;#039;b111_1000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Implementarea SystemVerilog a modulului Display7Seg&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module Display7Seg(&lt;br /&gt;
  input logic [3:0] in,&lt;br /&gt;
  output logic [6:0] out&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  always_comb begin&lt;br /&gt;
    case(in)&lt;br /&gt;
      4&amp;#039;d0: out = 7&amp;#039;b1000000;&lt;br /&gt;
      4&amp;#039;d1: out = 7&amp;#039;b1111001;&lt;br /&gt;
      4&amp;#039;d2: out = 7&amp;#039;b0100100;&lt;br /&gt;
      4&amp;#039;d3: out = 7&amp;#039;b0110000;&lt;br /&gt;
      4&amp;#039;d4: out = 7&amp;#039;b0011001;&lt;br /&gt;
      4&amp;#039;d5: out = 7&amp;#039;b0010010;&lt;br /&gt;
      4&amp;#039;d6: out = 7&amp;#039;b0000010;&lt;br /&gt;
      4&amp;#039;d7: out = 7&amp;#039;b1111000;&lt;br /&gt;
      default: out = 7&amp;#039;b0000110;&lt;br /&gt;
    endcase &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
endmodule&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții:==&lt;br /&gt;
=== Exercițiul 1===&lt;br /&gt;
Completați codul din Exemplul 2 astfel încât să se poată reprezenta toate numerele în bază 16 (hexazecimal), conform Anexei 1&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 2===&lt;br /&gt;
Un procesor are nevoie de un șir de biți numit instrucțiune pentru a știi ce trebuie să facă. Această instrucțiune codează în șirul său de biți toate informațiile necesare. &lt;br /&gt;
&lt;br /&gt;
De exemplu, pentru un grup de instrucțiuni care operează cu registre, aceste informații pot fi:&lt;br /&gt;
* codul instrucțiunii (operation code - opcode): un șir de biți care ne spune ce operație se execută.&lt;br /&gt;
* destinația: un șir de biți care codează numărul registrului destinație.&lt;br /&gt;
* sursa1: un șir de biți care codează numărul registrului folosit ca operand 1.&lt;br /&gt;
* sursa2: un șir de biți care codează numărul registrului folosit ca operand 2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Vom considera codul operației pe 4 biți, ceea ce inseamnă ca putem avea 16 instrucțiuni diferite. In plus, câmpurile care codează destinația și cei doi operanzi vor avea fiecare câte 4 biți, ceea ce inseamnă că vom avea 16 registre cu care putem lucra (R0 ... R15). Adunând dimensiunile fiecărui câmp, vom obține o instrucțiune pe 16 biți.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Instrucțiunile și codul operațiilor:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Vom considera ca procesorul nostru elementar poate suporta următoarele instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
||&amp;#039;&amp;#039;&amp;#039;Operație&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Cod operație&amp;#039;&amp;#039;&amp;#039; || &amp;#039;&amp;#039;&amp;#039;Sintaxă&amp;#039;&amp;#039;&amp;#039; ||&amp;#039;&amp;#039;&amp;#039;Descriere&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| ADD || 4&amp;#039;b0000 || ADD Rd Rs1 Rs2 || Rd = Rs1 + Rs2 &lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| SUB || 4&amp;#039;b0001 || SUB Rd Rs1 Rs2 || Rd = Rs1 - Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| OR || 4&amp;#039;b0010 || OR Rd Rs1 Rs2 || Rd = Rs1 OR Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| AND || 4&amp;#039;b0011 || AND Rd Rs1 Rs2 || Rd = Rs1 AND Rs2&lt;br /&gt;
|-  align=&amp;quot;center&amp;quot;&lt;br /&gt;
| LOADC || 4&amp;#039;b0100 || LOADC Rd, const || Rd = const&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pentru instrucțiunile prezentate mai sus, vom avea următoarele moduri de codare (de împărțire a informației în cadrul instrucțiunii):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Codare instructiune.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Registrele:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Cele 16 registre vor fi codate cu un număr egal cu indexul său. De exemplu, R0 va avea codul 4&amp;#039;b000, R1 va avea codul 4&amp;#039;b0001 și așa mai departe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Considerând cele spuse mai sus, vom avea următoarele exemple de instrucțiuni:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Exemple codare instructiuni.png | 400px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Având toate informațiile de mai sus, descrieți o memorie ROM cu adresă pe 4 biți și locații pe 16 biți, care să conțină următorul program, începând cu adresa 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
LOADC R0, 2h&lt;br /&gt;
LOADC R1, 5h&lt;br /&gt;
LOADC R2, 7h&lt;br /&gt;
ADD R3, R1, R0&lt;br /&gt;
SUB R4, R2, R1&lt;br /&gt;
OR R5, R3, R4&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exercițiul 3===&lt;br /&gt;
Proiectați un Codor Cezar cu cheie fixă sub forma unei memorii ROM. &lt;br /&gt;
&lt;br /&gt;
Un Codor Cezar preia un mesaj și codează independent fiecare literă a acestuia pentru a obține un mesaj cifrat. El se folosește de o cheie fixă care se adună la fiecare literă a mesajului. De exemplu, pentru cheia &amp;quot;+3&amp;quot;: a-&amp;gt;d; b-&amp;gt;e; c-&amp;gt;f;...; y-&amp;gt;b; z-&amp;gt;c. Observați că atunci când alfabetul a ajuns la capăt, se reia de la început. &lt;br /&gt;
Pentru decodare, se va folosi procedura inversă: pentru fiecare literă, vom aplica cheia cu semn invers (în exemplul nostru, cheia de decodare este &amp;quot;-3&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
Observații, sfaturi, task-uri suplimentare:&lt;br /&gt;
* Codorul va putea prelucra doar litere mici și spațiu gol (acesta rămâne neschimbat).&lt;br /&gt;
* Cel mai usor mod de a scrie această funcționalitate este folosind un bloc de tip &amp;#039;&amp;#039;case&amp;#039;&amp;#039;.&lt;br /&gt;
* Pentru testare, se pot folosi în testbench variabile de tip &amp;#039;&amp;#039;logic&amp;#039;&amp;#039; pe 8 biți, astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
logic [7:0] litera;&lt;br /&gt;
litera = &amp;quot;A&amp;quot;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Avansat: În SystemVerilog există și tipul de date &amp;#039;&amp;#039;string&amp;#039;&amp;#039;, ceea ce permite parcurgerea cu un &amp;#039;&amp;#039;for&amp;#039;&amp;#039; a mesajului. În Verilog clasic, astfel de parcurgeri sunt posibile, dar sintaxa este mai complicată.&lt;br /&gt;
* Se va folosi codul ASCII pentru valori. Pentru o ușoara vizualizare a datelor în simulare, se poate schimba radix-ul în ASCII. &lt;br /&gt;
* Avansat: Pentru a testa automat codul, se poate instanția încă un modul în testbench cu aceeași funcționalitate pe post de &amp;quot;golden model&amp;quot;. Acest modul nu trebuie să fie sintetizabil și atunci sintaxa permite mai multă libertate (cum ar fi operația de modulo &amp;quot;%&amp;quot;, utilă pentru testare, dar care determină un circuit complicat dacă ar fi sintetizată). Ieșirile celor două module din testbench sunt apoi comparate pentru a se verifica că ambele implementări oferă același rezultat.&lt;br /&gt;
* Implementați și Decodorul Cezar și testați Codorul împreună cu acesta. Aveți grijă ca cele două module să aibă aceeași cheie.&lt;br /&gt;
&lt;br /&gt;
==Anexa1== &lt;br /&gt;
&lt;br /&gt;
[[Fișier:Anexa1modificat9.PNG | 800px]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Anexa1modificat9.png&amp;diff=8320</id>
		<title>Fișier:Anexa1modificat9.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Anexa1modificat9.png&amp;diff=8320"/>
		<updated>2026-04-06T13:11:56Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Anexa1.png&amp;diff=8319</id>
		<title>Fișier:Anexa1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Anexa1.png&amp;diff=8319"/>
		<updated>2026-04-06T13:03:33Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8296</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8296"/>
		<updated>2026-03-23T13:02:34Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Teorie: Parametrizare */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi necesara descrierea aceluiasi modul de mai multe ori (daca circuitul isi schimba o dimensiune). &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu parametri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosi parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Unitate aritmetico-logică (ALU)===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/85/Subiect_ALU_pentru_wiki.pdf Unitate_aritmetico-logica]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8295</id>
		<title>CID aplicatii 5 : Exercitii cu circuite combinationale</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=CID_aplicatii_5_:_Exercitii_cu_circuite_combinationale&amp;diff=8295"/>
		<updated>2026-03-23T13:01:55Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Teorie: Parametrizare */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Teorie==&lt;br /&gt;
&lt;br /&gt;
Acest laborator are rolul de a sedimenta cunostiintele dobandite anterior. &lt;br /&gt;
&lt;br /&gt;
El consta in exercitii separate, unele date ca subiect la lucrarea 1 in anii anteriori si cateva notiuni de teorie si sintaxa ajutatoare.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: Parametrizare==&lt;br /&gt;
Parametrizarea este un mod de a generaliza codul scris pentru a nu fi necesara descrierea aceluiasi modul de mai multe ori (daca circuitul isi schimba o dimensiune). &lt;br /&gt;
&lt;br /&gt;
Pentru a intelege mai clar avantajele si sintaxa urmariti urmatorul exemplu:&lt;br /&gt;
&lt;br /&gt;
Fisierul sumator.sv:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator # // &amp;lt;= diez deoarece urmeaza lista cu paramteri&lt;br /&gt;
				( // parametri &lt;br /&gt;
					parameter data_size = 4 // valoare default 4&lt;br /&gt;
					// alti parametri aici daca este nevoie, separati prin virgula&lt;br /&gt;
				)&lt;br /&gt;
				( // interfata &lt;br /&gt;
					input logic [data_size-1:0] in0, // si pot folosii parametrul &amp;quot;data_size&amp;quot; pentru dimensiunea bus-ului&lt;br /&gt;
					input logic [data_size-1:0] in1,&lt;br /&gt;
					output logic [data_size-1:0] out0&lt;br /&gt;
				);&lt;br /&gt;
&lt;br /&gt;
assign out0 = in0 + in1;				&lt;br /&gt;
				&lt;br /&gt;
endmodule &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Cand se instantiaza un modul parametrizat, se specifica valorile parametrilor astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(8)   // se genereaza un sumator pe 8b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_0&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out0)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator # ( // parametri &lt;br /&gt;
		.data_size(32)  // se genereaza un sumator pe 32b&lt;br /&gt;
	) &lt;br /&gt;
        nume_instanta_1&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out1)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
 sumator nume_instanta_2 // se genereaza un sumator de dimensiune default, aici 4, asa cum e scris in modulul &amp;quot;sumator&amp;quot;&lt;br /&gt;
	( // interfata &lt;br /&gt;
		.in0(fir_in0), &lt;br /&gt;
		.in1(fir_in1),&lt;br /&gt;
		.out0(fir_out2)&lt;br /&gt;
	);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puteti folosi parametrizarea in exercitiul 3 de mai jos. Acolo sunt 2 tipuri de multiplexoare, unul cu intrarile pe 1 bit si unul cu intrarile pe 2 biti. Poate fi scris un singur modul parametrizat care sa acopere ambele situatii.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Concatenarea==&lt;br /&gt;
&lt;br /&gt;
Pentru o mai usoara conectare a firelor sau pentru o mai buna organizare si expresivitate a codului, de multe ori este util ca fire individuale sa fie grupate impreuna sau ca un bus de mai multi biti sa fie separat in fire individuale. Acest lucru se face folosind concatenarea, prin simbolurile &amp;quot;{ }&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Un exemplu de folosire a concatenarii este oferit mai jos.&lt;br /&gt;
Un sumator pe 8b are rezultatul pe maxim 9b, in cazul in care ambele numere sunt mari. Astfel apare un bit de carry out. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
module sumator ( &lt;br /&gt;
            input logic [7:0] in0,&lt;br /&gt;
            input logic [7:0] in1,&lt;br /&gt;
            output logic [7:0] out0,&lt;br /&gt;
            output logic carry_out&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
assign {carry_out,out0} = in0 + in1; // fac suma intre in0 si in1 iar rezultatul il pun pe cei 9b alcatuiti din: 1b carry_out si 8b out0, in ordinea asta&lt;br /&gt;
&lt;br /&gt;
endmodule       &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Se pot concatena oricat de multe semnale, puse in &amp;quot;{ }&amp;quot; si separate prin virgula. Atentie la dimensiunile firelor care se concateneaza.&lt;br /&gt;
&lt;br /&gt;
Se poate de asemenea face concatenare si la dreapta egalului, astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Verilog&amp;quot;&amp;gt;&lt;br /&gt;
assign fir_pe_10_b = {fir_pe_3b,fir_pe_5b,fir_pe_1b,fir_pe_1b};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In exemplul anterior ultimi 2b ai &amp;quot;fir_pe_10_b&amp;quot; vor avea mereu aceeasi valoare, provenind din acelasi fir. Sintaxa SystemVerilog permite asta.&lt;br /&gt;
&lt;br /&gt;
Puteti folosii concatenarea, in exercitiul 2, la flag-ul de overflow.&lt;br /&gt;
&lt;br /&gt;
==Teorie: Constante ca intrari in circuite==&lt;br /&gt;
In cazul in care se doreste scrierea unor constante la intrarea unor module, acestea se pun direct intre paranteze la instantiere. &lt;br /&gt;
De exemplu, pentru multiplexorul de jos din subiectul &amp;quot;alu structural&amp;quot;, intrarea &amp;quot;in3&amp;quot; este conectata la valoarea &amp;quot;1&amp;quot;. Sintaxa pentru aceasta este: &amp;quot;.in3(1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Teorie: &amp;quot;_&amp;quot;==&lt;br /&gt;
Simbolul &amp;quot;_&amp;quot; (underscore) este ignorat de SystemVerilog si ajuta vizual la citirea semnalelor pe mai multi biti. De exemplu 16&amp;#039;b1010010111110000 este identic cu 16&amp;#039;b1010_0101_1111_0000, al doilea fiind totusi mai usor de citit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Exercitii==&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 0: Repararea erorilor===&lt;br /&gt;
Arhiva de mai jos contine mai multe proiecte in Vivado, fiecare avand cate o eroare de sintaxa sau de logica. In vederea aprofundari cunostiintelor voastre (si pentru lucrarea de saptamana urmatoare), incercati sa le parcurgeti si sa rezolvati toate problemele. &lt;br /&gt;
Pe langa proiecte in sine, in arhiva se afla si un fisier text cu o introducere, rezolvarile si explicatiile pentru fiecare situatie.&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/file/d/1cNTpQC54_JEeSk8SxgHTEdGtobCn_-EI/view?usp=drive_link Arhiva_proiecte_cu_erori.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 1: ALU - descriere comportamentala===&lt;br /&gt;
Descrieți comportamental o unitate aritmetico-logică (ALU) care are la intrare 2 numere binare de câte 8 biți și poate calcula următoarele funcții:&lt;br /&gt;
:- suma celor două numere&lt;br /&gt;
:- diferența celor două numere&lt;br /&gt;
:- operații logice bit cu bit (bitwise): SI, SAU, XOR și inversele lor&lt;br /&gt;
:- operandul din stanga trece neschimbat&lt;br /&gt;
:- operandul din dreapta trece neschimbat&lt;br /&gt;
:- numărul din stânga este deplasat la stânga cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
:- numărul din stânga este deplasat la dreapta cu nr. de poziții indicat de numărul din dreapta&lt;br /&gt;
&lt;br /&gt;
Funcția executată la un anumit moment este determinată de configurația binară de pe intrarea de comandă (function).&lt;br /&gt;
&lt;br /&gt;
ALU are de asemenea intrare de carry și ieșire de carry, plus alte două ieșiri - indicatori - pentru cazurile când rezultatul este zero și când cei doi operanzi sunt egali.&lt;br /&gt;
&lt;br /&gt;
Intrarea de control va fi facuta pe 4 biti ca sa permita existenta a 16 operatii posibile. Fiecare numar de pe intrarea de control (combinatie de 0 si 1) va reprezenta o operatie din cele de mai sus. Scrierea se va face folosind un bloc &amp;quot;case&amp;quot; in functie de aceasta intrare. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 2: ALU - descriere structurala===&lt;br /&gt;
 &lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/8f/Subiect_big_alu.pdf subiect_alu.pdf]&lt;br /&gt;
	&lt;br /&gt;
Daca se doreste selectarea doar a anumitor biti dintr-un bus (cum se vrea din instruction) acest lucru se poate face in 2 feluri:&lt;br /&gt;
&lt;br /&gt;
a) cu fir aditional:&lt;br /&gt;
:&amp;#039;&amp;#039;wire [1:0] fir_aditional1;&amp;#039;&amp;#039;&lt;br /&gt;
:&amp;#039;&amp;#039;assign fir_aditional1 = instruction[11:10];&amp;#039;&amp;#039;&lt;br /&gt;
:// apoi la instantiere: &amp;#039;&amp;#039;.sel(fir_aditional1),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
b) direct in instantiere;&lt;br /&gt;
:la instantierea celor 2 mux4 din stanga, direct: &lt;br /&gt;
::&amp;#039;&amp;#039;.sel(instruction[11:10]),&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pentru a scrie mai putin (a nu face toate modulele de calcul separat + instantierea lor) si pentru ca e vorba de operatii simple, se poate pune operatia cu assign direct in top pe un fir declarat acolo, sau si mai prescurtat, direct operatia dorita cand se intantiaza modulul in care aceasta intra. De exemplu, pentru operatia de shift la dreapta care intra in primul multiplexor, se poate pune:  &amp;quot;.in0(data0 &amp;gt;&amp;gt; data1),&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 3: Multiplexoare===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/3/3a/Subiect_muxes.pdf subiect_muxes.pdf]&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 4: Rom/Look-up table===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/2/2e/Subiect_rom_luts.pdf rom_luts.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 5: Sumator cu reprezentare in cifre zecimale===&lt;br /&gt;
Proiectati si verificati un sumator zecimal pentru numere cu 2 cifre&lt;br /&gt;
&lt;br /&gt;
Modulul de top (Figura 1) este alcatuit din 2 blocuri de tip &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;. Fiecare bloc aduna cifrele de pe aceasi pozitie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 1&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
   Top level&lt;br /&gt;
&lt;br /&gt;
[[Fișier: bcdsum.png]]&lt;br /&gt;
&lt;br /&gt;
Blocul &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; (Figura 2) este alcatuit din 4 blocuri, 2 sumatoare binare pe 4 biti (de tip &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039;), o instanta de &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039; si un multiplexor elementar mux2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figura 2&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
   Blocul DIGIT SUM &lt;br /&gt;
&lt;br /&gt;
[[Fișier: digit.png]]&lt;br /&gt;
&lt;br /&gt;
Primul sumator aduna cifrele din domeniul [0...9] avand un rezultat intre [0 ... 18] &lt;br /&gt;
&lt;br /&gt;
Comparatorul are la iesire 1 daca rezultatul este mai mare decat 9.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mic decat 9, acesta este trimis in mod direct la iesirea &amp;#039;&amp;#039;&amp;#039;digit&amp;#039;&amp;#039;&amp;#039; a blocului &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Daca rezultatul este mai mare decat 9, o crectie este necesara si se aduna 6 la rezultat.&lt;br /&gt;
&lt;br /&gt;
Comparatorul cu valoarea 9 este descris structural din porti in figura de mai jos: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 3&amp;#039;&amp;#039;&amp;#039;   &lt;br /&gt;
   the comparator &lt;br /&gt;
&lt;br /&gt;
[[Fișier: cmp.png]]&lt;br /&gt;
&lt;br /&gt;
Testbench-ul va genera stimuli pentru &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
Intrarea b0 a &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; se schimba la fiecare 5 pasi de simulare .&lt;br /&gt;
&lt;br /&gt;
b1, a0 si a1 se schimba sincron cu b0 ca in Figura 4.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Figure 4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Fișier: teststimuli.png]]&lt;br /&gt;
&lt;br /&gt;
Cerinte:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;cmp&amp;#039;&amp;#039;&amp;#039;- descris structural la nivel de porti ca in Figura 3.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;sum4&amp;#039;&amp;#039;&amp;#039; descris comportamental cu un assign continuu.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;mux&amp;#039;&amp;#039;&amp;#039; descris comportamental cu always.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;digitsum&amp;#039;&amp;#039;&amp;#039; descris strctural ca in Figura 2.&lt;br /&gt;
# modulul de top numit &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039;, descris structural ca in Figure 1.&lt;br /&gt;
# modulul de testbench, &amp;#039;&amp;#039;&amp;#039;bcdsum_tb&amp;#039;&amp;#039;&amp;#039;, instantiaza &amp;#039;&amp;#039;&amp;#039;bcdsum&amp;#039;&amp;#039;&amp;#039; cu numele &amp;#039;&amp;#039;&amp;#039;dut&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# in testbench, generati stimuli pentru intrarile circuitului testat.&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 6: Codor Cezar===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/9/92/Cid_L1_codor_Cezar.pdf Codor_Cezar.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 7: Calcul si Flag-uri===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/c/c2/L1_calcul_si_flaguri.pdf Calcul_si_flaguri.pdf]&lt;br /&gt;
&lt;br /&gt;
===Exercitiul 8: Unitate aritmetico-logică (ALU)===&lt;br /&gt;
&lt;br /&gt;
[https://wiki.dcae.pub.ro/images/8/85/Subiect_ALU_pentru_wiki.pdf Unitate_aritmetico-logica]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Performance_analysis_and_optimization&amp;diff=8287</id>
		<title>Performance analysis and optimization</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Performance_analysis_and_optimization&amp;diff=8287"/>
		<updated>2026-03-09T08:38:02Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Lab sessions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Results =&lt;br /&gt;
&lt;br /&gt;
https://docs.google.com/spreadsheets/d/1GvZ-P-MEA9iPuBFx2onQ8qg0o2cDQSoWFV2Y0T11Fls/edit?usp=sharing&lt;br /&gt;
&lt;br /&gt;
= Support materials =&lt;br /&gt;
&lt;br /&gt;
http://www.agner.org/optimize/optimizing_cpp.pdf&lt;br /&gt;
&lt;br /&gt;
https://www.arm.com/files/pdf/AT_-_Better_C_Code_for_ARM_Devices.pdf&lt;br /&gt;
&lt;br /&gt;
= Lab sessions =&lt;br /&gt;
&lt;br /&gt;
Contact: calin.bira_AT_upb.ro&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Lab_1&amp;diff=8286</id>
		<title>PC Lab 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Lab_1&amp;diff=8286"/>
		<updated>2026-03-09T08:36:49Z</updated>

		<summary type="html">&lt;p&gt;Cbira: Ștergerea conținutului paginii&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8285</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8285"/>
		<updated>2026-03-06T13:04:00Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Pointerii și structurile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare/dereferentiere. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    (*structPointer).intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    (*structPointer).intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; (incrementând-o de n ori) : &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_12&amp;diff=8284</id>
		<title>PC Laborator 12</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_12&amp;diff=8284"/>
		<updated>2026-03-06T13:03:01Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Pointerii și structurile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic;&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie; &lt;br /&gt;
* să utilizeze &amp;lt;code&amp;gt;valgrind&amp;lt;/code&amp;gt; pentru a diagnostica pierderile de memorie.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    (*structPointer).intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    (*structPointer).intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Evitarea pierderilor de memorie - &amp;lt;code&amp;gt;valgrind&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Pierderile de memorie (memory leaks) apar atunci când programatorul alocă memorie, dar uită să o elibereze. Aceasta este o problemă foarte delicată pentru că aplicația va continua să aloce până când va depăși limitele permise și sistemul de operare va opri procesul forțat. Chiar și dacă nu se ajunge acolo, ocuparea de cantități mari de memorie va face ca tot sistemul să se miște din ce în ce mai greu (vezi versiunile vechi de Firefox):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * buffer = (char*) malloc(100 * sizeof(char));&lt;br /&gt;
    buffer = NULL;&lt;br /&gt;
    printf(&amp;quot;Done!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În exemplul de mai sus este alocat un buffer de 100 de bytes, iar adresa către zona respectivă se pierde când pointerului buffer i se atribuie valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Astfel, acea memorie nu mai poate fi nici accesată și nici eliberată. Cu toate acestea, programul compilează și rulează fără probleme. Pentru a verifica că nu există pierderi de memorie, se poate folosi programul &amp;lt;code&amp;gt;valgrind&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;rhobincu@IronMan&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/work/pc/test $&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt; valgrind --leak-check=full ./test&lt;br /&gt;
 ==6076== Memcheck, a memory error detector&lt;br /&gt;
 ==6076== Copyright (C) 2002-2013, and GNU GPL&amp;#039;d, by Julian Seward et al.&lt;br /&gt;
 ==6076== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info&lt;br /&gt;
 ==6076== Command: ./test&lt;br /&gt;
 ==6076== &lt;br /&gt;
 Done!&lt;br /&gt;
 ==6076== &lt;br /&gt;
 ==6076== HEAP SUMMARY:&lt;br /&gt;
 ==6076==     in use at exit: 100 bytes in 1 blocks&lt;br /&gt;
 ==6076==   total heap usage: 1 allocs, 0 frees, 100 bytes allocated&lt;br /&gt;
 ==6076== &lt;br /&gt;
 ==6076== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1&lt;br /&gt;
 ==6076==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)&lt;br /&gt;
 ==6076==    by 0x40058E: main (test.c:5)&lt;br /&gt;
 ==6076== &lt;br /&gt;
 ==6076== LEAK SUMMARY:&lt;br /&gt;
 ==6076==    definitely lost: 100 bytes in 1 blocks&lt;br /&gt;
 ==6076==    indirectly lost: 0 bytes in 0 blocks&lt;br /&gt;
 ==6076==      possibly lost: 0 bytes in 0 blocks&lt;br /&gt;
 ==6076==    still reachable: 0 bytes in 0 blocks&lt;br /&gt;
 ==6076==         suppressed: 0 bytes in 0 blocks&lt;br /&gt;
 ==6076== &lt;br /&gt;
 ==6076== For counts of detected and suppressed errors, rerun with: -v&lt;br /&gt;
 ==6076== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Observație: &amp;lt;/span&amp;gt; Ca valgrind să poată afișa numărul liniei și fișierul sursă unde apare eroarea, codul trebuie compilat cu simboluri de debug (-g).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru un cod corect, ieșirea lui &amp;#039;&amp;#039;&amp;#039;valgrind&amp;#039;&amp;#039;&amp;#039; este:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * buffer = (char*) malloc(100 * sizeof(char));&lt;br /&gt;
    free(buffer);&lt;br /&gt;
    buffer = NULL;&lt;br /&gt;
    printf(&amp;quot;Done!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;font-weight: bold&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;rhobincu@IronMan&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/work/pc/test $&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt; valgrind --leak-check=full ./test&lt;br /&gt;
 ==6244== Memcheck, a memory error detector&lt;br /&gt;
 ==6244== Copyright (C) 2002-2013, and GNU GPL&amp;#039;d, by Julian Seward et al.&lt;br /&gt;
 ==6244== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info&lt;br /&gt;
 ==6244== Command: ./test&lt;br /&gt;
 ==6244== &lt;br /&gt;
 Done!&lt;br /&gt;
 ==6244== &lt;br /&gt;
 ==6244== HEAP SUMMARY:&lt;br /&gt;
 ==6244==     in use at exit: 0 bytes in 0 blocks&lt;br /&gt;
 ==6244==   total heap usage: 1 allocs, 1 frees, 100 bytes allocated&lt;br /&gt;
 ==6244== &lt;br /&gt;
 ==6244== All heap blocks were freed -- no leaks are possible&lt;br /&gt;
 ==6244== &lt;br /&gt;
 ==6244== For counts of detected and suppressed errors, rerun with: -v&lt;br /&gt;
 ==6244== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Realizați o funcție &amp;lt;code&amp;gt;char * allocateString(unsigned size)&amp;lt;/code&amp;gt; care să aloce în HEAP o zonă de memorie care să poată stoca un sir de caractere de dimensiunea &amp;lt;code&amp;gt;size&amp;lt;/code&amp;gt; și să întoarcă adresa de unde începe zona respectivă. HINT: nu uitați de caracterul pentru final de șir.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Citiți de la tastatură o lungime de șir &amp;lt;code&amp;gt;length&amp;lt;/code&amp;gt; apoi folosind funcția de mai sus, alocați memorie pentru stocarea unui șir de acea dimensiune. Citiți apoi de la tastatură și memorați un șir de caractere pe care să-l afișați ulterior în consolă folosind funcția &amp;lt;code&amp;gt;puts&amp;lt;/code&amp;gt;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Pentru programul de mai sus, realizați o funcție &amp;lt;code&amp;gt;void printString(char * string)&amp;lt;/code&amp;gt; care să afișeze pe ecran șirul de caractere, folosind exclusiv funcția &amp;lt;code&amp;gt;putchar&amp;lt;/code&amp;gt; și fără a folosi operatorul de indexare a vectorilor ([]). Verificați că această funcție afișează același lucru ca funcția &amp;lt;code&amp;gt;puts&amp;lt;/code&amp;gt;. HINT: Utilizați operatorul de dereferențiere și aritmetica pointerilor.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Realizați o funcție &amp;lt;code&amp;gt;compute&amp;lt;/code&amp;gt; de tip &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; care să calculeze suma și produsul a două valori de tip &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; astfel încât funcția apelantă să le poată utiliza.  Testați funcția într-un program.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Găsiți și eliminați pierderile de memorie din codul de mai jos:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFER_SIZE 100&lt;br /&gt;
&lt;br /&gt;
struct Buffer {&lt;br /&gt;
    unsigned size;&lt;br /&gt;
    char * string;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Buffer * createBuffer(unsigned size) {&lt;br /&gt;
    struct Buffer * newBuffer = (struct Buffer*) malloc (sizeof(struct Buffer));&lt;br /&gt;
    newBuffer-&amp;gt;size = size;&lt;br /&gt;
    newBuffer-&amp;gt;string = (char*) malloc(size * sizeof(char));&lt;br /&gt;
    return newBuffer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct Buffer * reverseWord(struct Buffer * buffer) {&lt;br /&gt;
    struct Buffer * newBuffer = createBuffer(buffer-&amp;gt;size);&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; strlen(buffer-&amp;gt;string); i++) {&lt;br /&gt;
        *(newBuffer-&amp;gt;string + i) = buffer-&amp;gt;string[strlen(buffer-&amp;gt;string) - 1 - i];&lt;br /&gt;
    }&lt;br /&gt;
    newBuffer-&amp;gt;string[strlen(buffer-&amp;gt;string)] = &amp;#039;\0&amp;#039;;&lt;br /&gt;
    return newBuffer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    unsigned wordCount;&lt;br /&gt;
    printf(&amp;quot;How many words? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%u&amp;quot;, &amp;amp;wordCount);&lt;br /&gt;
&lt;br /&gt;
    unsigned i;&lt;br /&gt;
    for(i = 0; i &amp;lt; wordCount; i++) {&lt;br /&gt;
        struct Buffer * buffer = createBuffer(BUFFER_SIZE);&lt;br /&gt;
        scanf(&amp;quot;%s&amp;quot;, buffer-&amp;gt;string);&lt;br /&gt;
        buffer = reverseWord(buffer);&lt;br /&gt;
        printf(&amp;quot;Reversed is: %s\n&amp;quot;, buffer-&amp;gt;string);&lt;br /&gt;
        free(buffer);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8283</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8283"/>
		<updated>2026-03-06T13:02:15Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Pointerii și structurile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare/dereferentiere. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    (*structPointer).intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; (incrementând-o de n ori) : &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8273</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8273"/>
		<updated>2026-02-27T12:03:33Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Valoarea de la o adresă */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare/dereferentiere. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; (incrementând-o de n ori) : &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8264</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8264"/>
		<updated>2026-02-20T09:17:03Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; (incrementând-o de n ori) : &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8263</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8263"/>
		<updated>2026-02-20T09:16:41Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini &amp;#039;&amp;#039;&amp;#039;n&amp;#039;&amp;#039;&amp;#039; și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; (incrementând-o de ---n--- ori) : &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8262</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8262"/>
		<updated>2026-02-20T09:14:52Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;:&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8261</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8261"/>
		<updated>2026-02-20T09:14:23Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;:&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;- pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;- pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8260</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8260"/>
		<updated>2026-02-20T09:13:41Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;:&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;- pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;- pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8259</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8259"/>
		<updated>2026-02-20T09:13:01Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
- pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &lt;br /&gt;
&lt;br /&gt;
- pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8258</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8258"/>
		<updated>2026-02-20T09:12:07Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
- pentru jumătate dintre câini, dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &lt;br /&gt;
- pentru jumătate dintre câini, fără să dereferențiați acel pointer și afișați informațiile câinilor - câte un câine pe rând (nume, varstă, culoare, rasă) &lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8257</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8257"/>
		<updated>2026-02-20T09:06:43Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char, int, long, float, struct Dog. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Folosind operatorul &amp;#039;&amp;#039;&amp;#039;sizeof&amp;#039;&amp;#039;&amp;#039; afisați numarul de bytes (și in paranteză rotundă, numărul de biți) pentru fiecare dintre tipurile de date: char*, int*, long*, float*, struct Dog*, void*. Ce observați? &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8256</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8256"/>
		<updated>2026-02-20T08:57:59Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Structura în C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt; -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8255</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8255"/>
		<updated>2026-02-20T08:57:30Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Structura în C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char ...&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char ...&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt;  -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8254</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8254"/>
		<updated>2026-02-20T08:56:13Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Structura în C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |                                       char char&lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt;  -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8253</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8253"/>
		<updated>2026-02-20T08:54:45Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
     struct person&lt;br /&gt;
-------------------------                                          char char ...                      &lt;br /&gt;
| struct mystring*    ● |------&amp;gt;       struct mystring             --------------------------------------&lt;br /&gt;
-------------------------          -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---       | char*               ● | ----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| unsigned           29 |  |       | unsigned           10 |&lt;br /&gt;
-------------------------  |       -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |    &lt;br /&gt;
| float            68.9 |  ----&amp;gt;      struct mystring              ------------------------------&lt;br /&gt;
-------------------------          -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                   | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
                                   | unsigned           10 |&lt;br /&gt;
                                   -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------         -------------------------       char char...             char&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;  | struct mystring       |       ------------------------------------------------&lt;br /&gt;
-------------------------    /    -------------------------       | V | a | s | i | l | e | \0 |    |  ...   |   |&lt;br /&gt;
| struct mystring*    ● |---/     | char*               ● |-----&amp;gt;  -----------------------------------------------&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| unsigned           29 |         | unsigned           30 |&lt;br /&gt;
-------------------------         -------------------------&lt;br /&gt;
| float             1.7 |  &lt;br /&gt;
-------------------------  &lt;br /&gt;
| float            68.9 |    &lt;br /&gt;
-------------------------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8252</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8252"/>
		<updated>2026-02-20T08:42:34Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Structura în C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------&lt;br /&gt;
| struct person         |&lt;br /&gt;
-------------------------       -------------------------&lt;br /&gt;
| struct mystring*    ● |------&amp;gt;| struct mystring       |       --------------------------------------&lt;br /&gt;
-------------------------       -------------------------       | G | h | e | o | r | g | h | e | \0 |&lt;br /&gt;
| struct mystring*    ● |---    | char*               ● |-----&amp;gt; --------------------------------------&lt;br /&gt;
-------------------------  |    -------------------------&lt;br /&gt;
| unsigned           29 |  |    | unsigned           10 |&lt;br /&gt;
-------------------------  |    -------------------------&lt;br /&gt;
| float             1.7 |  |&lt;br /&gt;
-------------------------  |    -------------------------&lt;br /&gt;
| float            68.9 |  ----&amp;gt;| struct mystring       |       ------------------------------&lt;br /&gt;
-------------------------       -------------------------       | V | a | s | i | l | e | \0 |&lt;br /&gt;
                                | char*               ● |----&amp;gt;  ------------------------------&lt;br /&gt;
                                -------------------------&lt;br /&gt;
                                | unsigned           10 |&lt;br /&gt;
                                -------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_11&amp;diff=8251</id>
		<title>PC Laborator 11</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_11&amp;diff=8251"/>
		<updated>2026-02-20T08:29:51Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date noi, de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;;&lt;br /&gt;
* să declare și să utilizele variabile de aceste tipuri în programe&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de tip &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; sunt identice ca sintaxă cu cele de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, dar se comportă diferit. Spre deosebire de tipurile &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, unde câmpurile unei varibile ocupă zone diferite de memorie, câmpurile dintr-un &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; sunt suprapuse și ocupă aceeași zonă de memorie. Astfel, dacă se scrie într-un câmp, citirea celorlalte câmpuri va dovedi că valoarea acestora s-a modificat:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
union CharAndInt {&lt;br /&gt;
    int value;&lt;br /&gt;
    char string[4];&lt;br /&gt;
    short shorts[2];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    union CharAndInt var;&lt;br /&gt;
    /*&lt;br /&gt;
     * Codurile ascii pentru c, a, si l, in baza 16 sunt:&lt;br /&gt;
     * c = 0x63 a = 0x61 l = 0x6c iar terminatorul de string este 0x00.&lt;br /&gt;
     * Ne asteptam ca value sa fie deci 0x006c6163 iar &lt;br /&gt;
     * shorts[0] = 0x6163 (primii doi bytes in ordine inversa) &lt;br /&gt;
     * shorts[1] = 0x006c (ultimii doi bytes in ordine inversa).&lt;br /&gt;
     */&lt;br /&gt;
    strcpy(var.string, &amp;quot;cal&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;var.value = 0x%08x\n&amp;quot;, var.value);&lt;br /&gt;
    printf(&amp;quot;var.shorts[0] = 0x%04x\n&amp;quot;, var.shorts[0]);&lt;br /&gt;
    printf(&amp;quot;var.shorts[1] = 0x%04x\n&amp;quot;, var.shorts[1]);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* https://en.wikipedia.org/wiki/Endianness#Little-endian&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; sunt utilizate pentru a defini constante (de cele mai multe ori cu valori consecutive, dar nu obligatoriu) care sunt implicit de tipul definit de &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;. Se definesc apoi variabile de tipul &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; respectiv, iar aceste variabile nu pot lua ca valori decât constantele definite în cadrul &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;-ului:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    enum Culoare color;&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.numarInmatriculare, 8, stdin);&lt;br /&gt;
&lt;br /&gt;
    masina.color = ROSU;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina.anFabricatie);&lt;br /&gt;
    return masina;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %d si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.color, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
 &lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tipurile de dată &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; sunt la bază numere întregi. Când se definesc constantele dintr-un enum, dacă nu se specifică explicit valori, atunci prima constantă este implicit 0. Fiecare constantă căreia nu i se atribuie explicit o valoare, va avea implicit valoarea anterioară incrementată cu unu. Astfel, codul de mai sus rulat va afișa pentru culoare, valoarea 5. Este posibil ca două constante dintr-un &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; să aibă aceeași valoare:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB = 0,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În exemplul de mai sus, NEGRU este 0 (implicit), BEJ este 1, ALB este 0, VERDE este 1, ALBASTRU este 2 și ROSU este 3.&lt;br /&gt;
&lt;br /&gt;
O constantă definită într-un &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;, ca și o variabilă de tip &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; se pot converti implicit la un tip de date întreg (char, int, long, etc). Conversia inversă (de la întreg la &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;) este permisă în C dar nu și în C++, unde este obligatoriu un operator de conversie (cast):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
int main() {&lt;br /&gt;
    int valoare = NEGRU;&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, valoare);&lt;br /&gt;
&lt;br /&gt;
    enum Culoare color = 5;&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, color);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți un &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; numit &amp;#039;&amp;#039;&amp;#039;CatBreed&amp;#039;&amp;#039;&amp;#039; în care să definiți minim 5 constante de rase de pisici (dacă nu știți pe de rost, căutați pe Internet). Scrieți apoi o funcție care să ia ca argument o variabilă de tip &amp;lt;code&amp;gt;enum CatBreed&amp;lt;/code&amp;gt; și să întoarcă un șir de caractere care să reprezinte numele rasei. Testați această funcție apelând-o în &amp;lt;code&amp;gt;int main&amp;lt;/code&amp;gt; cu toate constantele definite din &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; și afisând rezultatul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Cat&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă (folosiți enum-ul de mai sus) &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Cat&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Cat&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca un număr (utilizatorul trebuie informat ce reprezintă fiecare număr). Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Cat&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyCatLady&amp;#039;&amp;#039;&amp;#039;, de 10 pisici. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de pisici și apoi citiți informații legate de respectivele pisici, folosind funcția de mai sus, și apoi stocând informațiile in vector. Dacă toate pisicile au culoarea &amp;quot;black&amp;quot;, atunci se va afișa &amp;quot;The crazy cat lady is a witch!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Pornind de la &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt;-ul din exemplu, definiți o variabilă de tip &amp;lt;code&amp;gt;union CharAndInt&amp;lt;/code&amp;gt; și scrieți valoarea corespunzătoare în câmpul &amp;#039;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;#039; astfel încât afișând câmpul &amp;#039;&amp;#039;&amp;#039;string&amp;#039;&amp;#039;&amp;#039; ca șir de caractere să obțineți &amp;quot;cat&amp;quot;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8250</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8250"/>
		<updated>2026-02-20T08:28:36Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_11&amp;diff=8249</id>
		<title>PC Laborator 11</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_11&amp;diff=8249"/>
		<updated>2026-02-20T08:26:35Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date noi, de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;;&lt;br /&gt;
* să declare și să utilizele variabile de aceste tipuri în programe&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de tip &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; sunt identice ca sintaxă cu cele de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, dar se comportă diferit. Spre deosebire de tipurile &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, unde câmpurile unei varibile ocupă zone diferite de memorie, câmpurile dintr-un &amp;lt;code&amp;gt;union&amp;lt;/code&amp;gt; sunt suprapuse și ocupă aceeași zonă de memorie. Astfel, dacă se scrie într-un câmp, citirea celorlalte câmpuri va dovedi că valoarea acestora s-a modificat:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
union CharAndInt {&lt;br /&gt;
    int value;&lt;br /&gt;
    char string[4];&lt;br /&gt;
    short shorts[2];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    union CharAndInt var;&lt;br /&gt;
    /*&lt;br /&gt;
     * Codurile ascii pentru c, a, si l, in baza 16 sunt:&lt;br /&gt;
     * c = 0x63 a = 0x61 l = 0x6c iar terminatorul de string este 0x00.&lt;br /&gt;
     * Ne asteptam ca value sa fie deci 0x006c6163 iar &lt;br /&gt;
     * shorts[0] = 0x6163 (primii doi bytes in ordine inversa) &lt;br /&gt;
     * shorts[1] = 0x006c (ultimii doi bytes in ordine inversa).&lt;br /&gt;
     */&lt;br /&gt;
    strcpy(var.string, &amp;quot;cal&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;var.value = 0x%08x\n&amp;quot;, var.value);&lt;br /&gt;
    printf(&amp;quot;var.shorts[0] = 0x%04x\n&amp;quot;, var.shorts[0]);&lt;br /&gt;
    printf(&amp;quot;var.shorts[1] = 0x%04x\n&amp;quot;, var.shorts[1]);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* https://en.wikipedia.org/wiki/Endianness#Little-endian&lt;br /&gt;
&lt;br /&gt;
= Tipurile de date &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; sunt utilizate pentru a defini constante (de cele mai multe ori cu valori consecutive, dar nu obligatoriu) care sunt implicit de tipul definit de &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;. Se definesc apoi variabile de tipul &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; respectiv, iar aceste variabile nu pot lua ca valori decât constantele definite în cadrul &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;-ului:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    enum Culoare color;&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina.numarInmatriculare, 8, stdin);&lt;br /&gt;
&lt;br /&gt;
    masina.color = ROSU;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina.anFabricatie);&lt;br /&gt;
    return masina;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %d si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.color, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
 &lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tipurile de dată &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; sunt la bază numere întregi. Când se definesc constantele dintr-un enum, dacă nu se specifică explicit valori, atunci prima constantă este implicit 0. Fiecare constantă căreia nu i se atribuie explicit o valoare, va avea implicit valoarea anterioară incrementată cu unu. Astfel, codul de mai sus rulat va afișa pentru culoare, valoarea 5. Este posibil ca două constante dintr-un &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; să aibă aceeași valoare:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB = 0,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În exemplul de mai sus, NEGRU este 0 (implicit), BEJ este 1, ALB este 0, VERDE este 1, ALBASTRU este 2 și ROSU este 3.&lt;br /&gt;
&lt;br /&gt;
O constantă definită într-un &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;, ca și o variabilă de tip &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt; se pot converti implicit la un tip de date întreg (char, int, long, etc). Conversia inversă (de la întreg la &amp;lt;code&amp;gt;enum&amp;lt;/code&amp;gt;) este permisă în C dar nu și în C++, unde este obligatoriu un operator de conversie (cast):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
enum Culoare {&lt;br /&gt;
    NEGRU,&lt;br /&gt;
    BEJ,&lt;br /&gt;
    ALB,&lt;br /&gt;
    VERDE,&lt;br /&gt;
    ALBASTRU,&lt;br /&gt;
    ROSU&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
int main() {&lt;br /&gt;
    int valoare = NEGRU;&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, valoare);&lt;br /&gt;
&lt;br /&gt;
    enum Culoare color = 5;&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, color);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o structură numită &amp;#039;&amp;#039;&amp;#039;Dog&amp;#039;&amp;#039;&amp;#039; ce trebuie să conțină următoarele informații:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; nume &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; vârstă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; culoare &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; rasă &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Realizați apoi o funcție care să citească date de la tastatură și să întoarcă o variabilă de tip &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și o altă funcție care să ia ca argument un &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; și să afișeze informațiile pe ecran. Rasa se va citi ca o structură mystring. Nu uitați că după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039;, în stream-ul standard de intrare va rămâne întotdeauna un caracter newline (&amp;#039;\n&amp;#039;). Dacă după un apel de &amp;#039;&amp;#039;&amp;#039;scanf&amp;#039;&amp;#039;&amp;#039; doriți să citiți un șir de caractere cu &amp;#039;&amp;#039;&amp;#039;fgets&amp;#039;&amp;#039;&amp;#039;, va trebui ca înainte de acest apel să apelați o dată &amp;#039;&amp;#039;&amp;#039;getchar()&amp;#039;&amp;#039;&amp;#039; care va citi și elimina din stream caracterul (&amp;#039;\n&amp;#039;).&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Definiți o variabilă globală, de tip vector de &amp;lt;code&amp;gt;struct Dog&amp;lt;/code&amp;gt; numită &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, de 100 câini. În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, citiți apoi un număr de câini și apoi citiți informații legate de respectivii câini, folosind funcția de mai sus, și apoi stocând informațiile în vector. Dacă jumătate dintre câini au culoarea &amp;quot;black&amp;quot; si jumătate &amp;quot;white&amp;quot;, atunci se va afișa &amp;quot;The crazy dog lady is a Cruella wannabe!&amp;quot;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; În funcția &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; apoi, creați un pointer de tip corespunzator spre începutul vectorului &amp;#039;&amp;#039;&amp;#039;gCrazyDogLady&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039;. Iterați prin acest vector, folosind aritmetica pointerilor pe variabila &amp;#039;&amp;#039;&amp;#039;pTowardsADog&amp;#039;&amp;#039;&amp;#039; și afișați informațiile câinilor - câte un câine pe rand (nume, varstă, culoare, rasă) &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8248</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8248"/>
		<updated>2026-02-20T08:03:35Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri, ori o combinație din cele două.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8247</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8247"/>
		<updated>2026-02-20T08:00:43Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Obiective */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective : recapitulare structuri si pointeri =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8246</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8246"/>
		<updated>2026-02-20T07:59:03Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct mystring{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct mystring *first_name;&lt;br /&gt;
    struct mystring *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;mystring&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile mystring și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default mystring with no content and length = 30&lt;br /&gt;
    struct mystring * some_string = (struct mystring*)malloc(sizeof(struct mystring));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty mystring&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip mystring sunt referință la aceeași adresă, respectiv la același mystring. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile mystring și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8245</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8245"/>
		<updated>2026-02-20T07:56:30Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Obiective */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de tip struct în programe;&lt;br /&gt;
&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8244</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8244"/>
		<updated>2026-02-20T07:55:39Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Obiective */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestei recapitulări studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de aceste tipuri în programe;&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie;&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8243</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8243"/>
		<updated>2026-02-20T07:54:33Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de aceste tipuri în programe;&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Structura în C =&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8242</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8242"/>
		<updated>2026-02-20T07:46:06Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească tipuri de date de tip struct;&lt;br /&gt;
* să declare și să utilizele variabile de aceste tipuri în programe;&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic (in C si C++);&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Structura în C ====&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8241</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8241"/>
		<updated>2026-02-20T07:43:11Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==== Structura în C ====&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Obiective =&lt;br /&gt;
&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să definească și să utilizeze tipuri de date pointer;&lt;br /&gt;
* să folosească pointeri pentru a putea modifica variabilele trimise ca argumente unor funcții;&lt;br /&gt;
* să aloce, să folosească și să elibereze memorie HEAP, în mod dinamic;&lt;br /&gt;
* să utilizeze aritmetica pointerilor pentru a itera peste elemente de la adrese consecutive de memorie; &lt;br /&gt;
* să utilizeze &amp;lt;code&amp;gt;valgrind&amp;lt;/code&amp;gt; pentru a diagnostica pierderile de memorie.&lt;br /&gt;
&lt;br /&gt;
= Tipuri de date pointer =&lt;br /&gt;
&lt;br /&gt;
 Un &amp;#039;&amp;#039;&amp;#039;pointer&amp;#039;&amp;#039;&amp;#039; reprezintă o variabilă care stochează o adresă în memoria dedicată aplicației. Tipul variabilei de tip pointer specifică tipul datei care poate fi citit de la adresa respectivă.&lt;br /&gt;
&lt;br /&gt;
O variabilă de tip pointer se definește în felul următor:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tip_data&amp;gt; * &amp;lt;nume_variabila&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Spre exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int * pa;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Variabila de tip pointer &amp;lt;code&amp;gt;pa&amp;lt;/code&amp;gt; nu memorează un întreg, ci o adresă în memorie, iar de la adresa respectivă se poate citi un întreg. Acest lucru se numește indirectare simplă. În plus, deoarece tipul pointer este în sine un tip de dată, și în definiția unui pointer &amp;lt;tip_data&amp;gt; poate fi un pointer, aceasta permite următoarele construcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;int * pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi un întreg (indirectare simplă);&lt;br /&gt;
* &amp;lt;code&amp;gt;int ** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi un întreg (dublă indirectare);&lt;br /&gt;
* &amp;lt;code&amp;gt;int *** pa;&amp;lt;/code&amp;gt; - variabilă ce stochează o adresă de unde se poate citi o adresă de unde se poate citi o adresă de unde se poate citi un întreg (triplă indirectare);&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Regulă:&amp;lt;/span&amp;gt; Orice variabilă este stocată în memorie și deci are o adresă în memorie.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C există un tip de dată pointer care poate memora o adresă fără a ști ce date se află la adresa respectivă. Acest tip de pointer este &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Dimensiunea tipului de date pointer ==&lt;br /&gt;
&lt;br /&gt;
Conform regulii de mai sus, și variabilele de tip pointer ocupă loc în memorie, deci au dimensiune, în octeți. Un pointer nu oferă informații legate de dimensiunea ocupată de datele de la adresa respectivă, ci doar adresa de unde începe zona ocupată. Din moment ce un pointer memorează doar o adresă, dimensiunea variabilelor de tip pointer nu depinde decât de dimensiunea spațiului de memorie. Astfel, pentru procesoare și sisteme de operare pe 32 de biți, o variabilă de tip pointer va avea 32 de biți, iar pe procesoare și sisteme de operare pe 64 de biți, o variabilă de tip pointer va avea 64 de biți.&lt;br /&gt;
&lt;br /&gt;
== Adresa unei variabile ==&lt;br /&gt;
&lt;br /&gt;
Operatorul care permite aflarea adresei unde este stocată o variabilă este ampersand (&amp;amp;). Acesta este un operator unar ce se plasează înaintea unei variabile iar rezultatul evaluării sale este adresa unde este stocată variabila respectivă. Această adresă poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;, adresa acesteia se poate stoca într-o variabilă de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adresa NULL ==&lt;br /&gt;
&lt;br /&gt;
Pentru orice aplicație, adresa 0 din spațiul ei de memorie este rezervată. Aceasta nu poate fi nici scrisă și nici citită. Această adresa poartă numele de &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;. Orice variabilă de tip pointer poate lua valoarea &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;, lucru care de obicei specifică faptul că de fapt variabila pointer nu stochează o adresă validă.&lt;br /&gt;
&lt;br /&gt;
 Constanta &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; este definită în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt; (Standard Library).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    char * charPointer = NULL;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Valoarea de la o adresă ==&lt;br /&gt;
&lt;br /&gt;
Având o variabilă de tip pointer, valoarea stocată în memorie la adresa respectivă se poate afla folosind caracterul steluță (*), numit și operator de indirectare. Acesta este un operator unar ce se plasează înaintea unei variabile de tip pointer iar rezultatul evaluării sale este valoarea din memorie de la adresa stocată în variabila respectivă. Această valoare poate fi stocată într-o altă variabilă de tipul corespunzător. Altfel spus, pentru o variabilă pointer de tip &amp;#039;&amp;#039;tip_data *&amp;#039;&amp;#039;, valoarea de la adresa stocată de pointerul respectiv se poate memora într-o altă variabilă de tip &amp;#039;&amp;#039;tip_data&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
float floatValue;&lt;br /&gt;
float * floatAddress = &amp;amp;floatValue;&lt;br /&gt;
float anotherFloatValue = *floatAddress;&lt;br /&gt;
&lt;br /&gt;
int intValue;&lt;br /&gt;
int * intAddress = &amp;amp;intValue;&lt;br /&gt;
int ** intPointerAddress = &amp;amp;intAddress;&lt;br /&gt;
int * anotherintAddress = *intPointerAddress;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Accesarea valorii de la o adresă se numește dereferențiere. Dereferențierea unei adrese care nu face parte din spațiul de memorie al aplicației sau dereferențierea lui &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039; va avea ca efect oprirea imediată a programului printr-un &amp;#039;&amp;#039;Segmentation fault.&amp;#039;&amp;#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu confundați steluța utilizată la definirea unui pointer cu operatorul de indirectare/ dereferențiere. Aceștia sunt la fel de diferiți cum este și operatorul de inmulțire față de cel de indirectare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Utilitatea variabilelor de tip pointer =&lt;br /&gt;
&lt;br /&gt;
Pointerii în C au două roluri foarte importante:&lt;br /&gt;
# Alocarea dinamică de memorie în HEAP&lt;br /&gt;
# Modificarea variabilelor parametri ale unor funcții astfel încât modificarea să se păstreze în afara funcției&lt;br /&gt;
&lt;br /&gt;
== Alocarea dinamică de memorie ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată unei aplicații de către sistemul de operare este împărțită în mai multe secțiuni, dintre care importante pentru stocarea de date sunt:&lt;br /&gt;
&lt;br /&gt;
* Segmentele BSS și Data - reprezintă memoria alocată pentru variabilele statice (globale), care există de la începutul până la încheierea programului, fără posibilitate de eliberare;&lt;br /&gt;
* Stiva (Stack) - zona de memorie în care se alocă contextele funcțiilor apelate în timpul execuției programului și în care se alocă argumentele și variabilele locale are funcțiilor; această zonă este alocată la intrarea în funcție și este eliberată la ieșirea din funcție;&lt;br /&gt;
* HEAP - zonă de memorie în care se pot aloca dinamic, de către programator, blocuri de memorie ce pot fi folosite în program până la eliberarea acestora de către programator.&lt;br /&gt;
&lt;br /&gt;
Alocarea și dezalocarea memoriei în heap se fac folosind următoarele funcții:&lt;br /&gt;
* &amp;lt;code&amp;gt;void * malloc(unsigned size)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;size&amp;#039;&amp;#039; octeți într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea nu șterge conținutul memoriei respective;&lt;br /&gt;
* &amp;lt;code&amp;gt;void * calloc(unsigned elements, unsigned elementSize)&amp;lt;/code&amp;gt; - alocă &amp;#039;&amp;#039;elements&amp;#039;&amp;#039; elemente de &amp;#039;&amp;#039;elementSize&amp;#039;&amp;#039; octeți fiecare într-o zonă continuă din HEAP și întoarce adresa de memorie unde începe zona respectivă; dacă alocarea eșuează (nu exită suficientă memorie într-o zonă continuă în HEAP), funcția va întoarce &amp;#039;&amp;#039;&amp;#039;NULL&amp;#039;&amp;#039;&amp;#039;; alocarea șterge tot conținutul memoriei respective, scriind 0 la fiecare locație;&lt;br /&gt;
* &amp;lt;code&amp;gt;void free (void *)&amp;lt;/code&amp;gt; - dezalocă o zonă de memorie alocată în prealabil cu &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; sau &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;; apelul succesiv de două sau mai multe ori a funcției &amp;lt;code&amp;gt;free&amp;lt;/code&amp;gt; pentru aceeași zonă de memorie sau apelul ei pentru o adresă care nu a fost alocată în prealabil va avea ca efect oprirea imediată a programului cu eroare (&amp;#039;&amp;#039;double free or corruption&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Toate aceste funcții sunt definite în fișierul header &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;stdlib.h&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * intPointer;&lt;br /&gt;
    short * shortPointer;&lt;br /&gt;
&lt;br /&gt;
    intPointer = (int*) malloc(sizeof(int));&lt;br /&gt;
    shortPointer = (short*) calloc(1, sizeof(short));&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru int este: %d\n&amp;quot;, *intPointer);&lt;br /&gt;
    printf(&amp;quot;Valoarea din zona alocata pentru short este: %hd\n&amp;quot;, *shortPointer);&lt;br /&gt;
&lt;br /&gt;
    free(intPointer);&lt;br /&gt;
    free(shortPointer);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Deoarece funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; au doar rolul de a aloca memorie, fără să știe care este scopul utilizării acestei memorii, ele întorc un pointer de tip &amp;lt;code&amp;gt;void *&amp;lt;/code&amp;gt;. Astfel, pentru a putea stoca adresa într-un alt tip de pointer (de exemplu &amp;lt;code&amp;gt;int *&amp;lt;/code&amp;gt;), ea trebuie convertită la tipul de date corect. Aceasta este explicația prezenței operatorului de cast din fața apelului funcțiilor &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt; din codul de mai sus.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Aritmetica pointerilor ==&lt;br /&gt;
&lt;br /&gt;
Când se alocă memorie in HEAP, rareori se alocă pentru un singur element, de cele mai multe ori se alocă pentru un număr mare de elemente de același fel. Ca exemplu, dacă vrem să stocăm o imagine High Definition, ne trebuie o zonă de memorie care să poată memora informație de culoare pentru 1920 * 1080 de pixeli, fiecare pixel având informație de culoare pentru roșu, verde și albastru (RGB). Fiecare din aceste componente de culoare se stochează pe un octet ca valoare întreagă fără semn (unsigned char). Prin urmare, pentru un frame se vor aloca 1920 * 1080 * 3 octeți = 6220800, aproape 6 MB. Această memorie se alocă întotdeauna într-o zonă continuă de către funcțiile &amp;lt;code&amp;gt;malloc&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;calloc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    unsigned char * frame;&lt;br /&gt;
    frame = (unsigned char*) malloc(1920 * 1080 * 3 * sizeof(unsigned char));&lt;br /&gt;
    //... use frame&lt;br /&gt;
&lt;br /&gt;
    free (frame);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deoarece pointer-ul nu memorează decât adresa de început a zonei de memorie, există posibilitatea de a modifica adresa pentru a accesa elementele ulterioare. În acest scop, variabilele de tip pointer suportă doar operații aritmetice de adunare sau scădere, nu și de înmulțire sau împărțire.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Incrementarea unui pointer nu crește adresa cu 1, ci cu dimensiunea tipului de dată al pointer-ului. Deci pentru un &amp;lt;code&amp;gt;int * p;&amp;lt;/code&amp;gt;, linia &amp;lt;code&amp;gt;p++;&amp;lt;/code&amp;gt; va incrementa adresa cu 4 (sizeof(int)):&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int * pointer;&lt;br /&gt;
    pointer = (int*) malloc(10 * sizeof(int));&lt;br /&gt;
    printf(&amp;quot;The pointer address is: %p\n&amp;quot;, pointer);&lt;br /&gt;
    printf(&amp;quot;The pointer address + 1 is: %p\n&amp;quot;, pointer + 1);&lt;br /&gt;
    free (pointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție &amp;lt;/span&amp;gt; ca prin operații pe pointeri să nu depășiți zona de memorie alocată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și vectorii ==&lt;br /&gt;
&lt;br /&gt;
Memoria alocată pentru mai multe elemente de același fel reprezintă de fapt un vector de elemente de acel tip. Astfel aflăm că de fapt vectorii și pointerii, în multe situații se pot folosi interschimbabil.&lt;br /&gt;
&lt;br /&gt;
 Când se definește un vector, numele vectorului reprezintă un pointer la adresa de unde începe zona lui de memorie, adică adresa unde este memorat elementul de la indexul 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int array[10];&lt;br /&gt;
    array[0] = 13;&lt;br /&gt;
    printf(&amp;quot;The array pointer address is: %p\n&amp;quot;, array);&lt;br /&gt;
    printf(&amp;quot;The value at address %p is %d\n&amp;quot;, array, *array);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 Dereferențierea unui pointer indexat cu o valoare este echivalentă cu folosirea operatorului de acces la vector: &amp;lt;code&amp;gt;*(v + k)&amp;lt;/code&amp;gt; == &amp;lt;code&amp;gt;v[k]&amp;lt;/code&amp;gt;, unde &amp;#039;&amp;#039;&amp;#039;v&amp;#039;&amp;#039;&amp;#039; este un pointer (sau vector) iar &amp;#039;&amp;#039;&amp;#039;k&amp;#039;&amp;#039;&amp;#039; este un întreg.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;14,18&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int arraySize;&lt;br /&gt;
    printf(&amp;quot;size = &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;, &amp;amp;arraySize);&lt;br /&gt;
&lt;br /&gt;
    int * heapArray;&lt;br /&gt;
    heapArray = (int*) malloc(arraySize * sizeof(int));&lt;br /&gt;
&lt;br /&gt;
    int i;&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = &amp;quot;, i);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;heapArray[i]);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(i = 0; i &amp;lt; arraySize; i++) {&lt;br /&gt;
        printf(&amp;quot;heapArray[%d] = %d\n&amp;quot;, i, *(heapArray + i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    free (heapArray);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pointerii și structurile ==&lt;br /&gt;
&lt;br /&gt;
Ca orice tip de dată, și variabilele de tip structură ocupă loc în memorie și deci pot exista pointeri de tip structură:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Având un pointer la o structură, accesul la câmpuri se poate face în două moduri:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Dereferențierea pointerului pentru a obține &amp;quot;valoarea&amp;quot; structurii și apoi utilizarea operatorului &amp;quot;.&amp;quot; pentru accesul la membri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;12&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Accesul la membrii unei structuri accesate printr-un pointer este atât de popular și des întâlnit în C încât există un operator special care permite accesul la câmpuri fără dereferențiere. Acest operator este săgeata &amp;quot;-&amp;gt;&amp;quot;: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;13,14&amp;quot;&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test testStructVar;&lt;br /&gt;
    struct Test * structPointer = &amp;amp;testStructVar;&lt;br /&gt;
&lt;br /&gt;
    *structPointer.intField = 10;&lt;br /&gt;
    structPointer-&amp;gt;floatField = 4.3;&lt;br /&gt;
    structPointer-&amp;gt;charField = &amp;#039;B&amp;#039;;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alocarea memoriei în HEAP pentru structuri se face identic cu alocarea pentru tipurile primitive de date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; highlight=&amp;quot;10, 14&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
struct Test {&lt;br /&gt;
    int intField;&lt;br /&gt;
    float floatField;&lt;br /&gt;
    char charField;&lt;br /&gt;
    char charArrayField[100];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Test * structPointer = (struct Test*) malloc(sizeof(struct Test));&lt;br /&gt;
&lt;br /&gt;
    // use structPointer&lt;br /&gt;
&lt;br /&gt;
    free(structPointer);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adrese ca argumente de funcție ==&lt;br /&gt;
&lt;br /&gt;
Știm deja că în C argumentele funcțiilor sunt pass-by-value, asta înseamnă că funcției i se transmite valoarea dintr-o variabilă, nu variabila în sine. Astfel, dacă o variabilă este folosită ca argument la apelul unei funcții, modificarea argumentului în funcție nu se propagă și spre variabila sursă:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, arg);&lt;br /&gt;
    arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Există o soluție pentru a permite propagarea modificării spre variabila sursă, și anume în loc de a trimite ca argument funcției variabila, se transmite adresa variabilei. Asta permite funcției să scrie direct în memoria alocată pentru variabilă și deci să-i modifice valoarea:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void divideByTwo(int *arg) {&lt;br /&gt;
    printf(&amp;quot;Argument before division = %d\n&amp;quot;, *arg);&lt;br /&gt;
    *arg /= 2;&lt;br /&gt;
    printf(&amp;quot;Argument after division = %d\n&amp;quot;, *arg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int var = 10;&lt;br /&gt;
    divideByTwo(&amp;amp;var);&lt;br /&gt;
    printf(&amp;quot;Variabile after function call = %d\n&amp;quot;, var);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8240</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8240"/>
		<updated>2026-02-20T07:40:16Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Structura în C */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==== Structura în C ====&lt;br /&gt;
&lt;br /&gt;
Tipurile de date &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale structurii. Un exemplu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Câmpurile structurii &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; sunt: &amp;#039;&amp;#039;&amp;#039;marca&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;model&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;anFabricatie&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;numarInmatriculare&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;culoare&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție&amp;lt;/span&amp;gt;: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; nu implică existența unei varibile de tip &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Declararea unei variabile de tipul &amp;#039;&amp;#039;Masina&amp;#039;&amp;#039; se face exact ca declararea oricărei alte variabile, sub forma: &amp;lt;tip_data&amp;gt; &amp;lt;nume_variabila&amp;gt;, cu observația că tipul de dată va conține și cuvântul cheie &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, deci acesta va fi &amp;lt;code&amp;gt;struct Masina&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Odată definită o variabilă de tip &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, operatorul folosit pentru a accesa câmpurile structurii este &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color: blue; font-weight: bold&amp;quot;&amp;gt;Observație&amp;lt;/span&amp;gt;: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.&lt;br /&gt;
&lt;br /&gt;
Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Masina {&lt;br /&gt;
    char marca[100];&lt;br /&gt;
    char model[50];&lt;br /&gt;
    unsigned short anFabricatie;&lt;br /&gt;
    char numarInmatriculare[8];&lt;br /&gt;
    char culoare[10];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct Masina citesteMasina() {&lt;br /&gt;
    struct Masina masina_mea;&lt;br /&gt;
    printf(&amp;quot;Care este marca masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.marca, 100, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este modelul masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.model, 50, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este numarul de inmatriculare al masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.numarInmatriculare, 8, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este culoarea masinii? &amp;quot;);&lt;br /&gt;
    fgets(masina_mea.culoare, 10, stdin);&lt;br /&gt;
    printf(&amp;quot;Care este anul de fabricatie a masinii? &amp;quot;);&lt;br /&gt;
    scanf(&amp;quot;%hu&amp;quot;, &amp;amp;masina_mea.anFabricatie);&lt;br /&gt;
    return masina_mea;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void afiseazaMasina(struct Masina masina){&lt;br /&gt;
    printf(&amp;quot;Masina marca %s si modelul %s are numarul de inmatriculare &amp;quot;&lt;br /&gt;
            &amp;quot;%s, culoarea %s si a fost fabricata in anul %hu!\n&amp;quot;,&lt;br /&gt;
            masina.marca, masina.model, masina.numarInmatriculare,&lt;br /&gt;
            masina.culoare, masina.anFabricatie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    struct Masina parcAuto[10];&lt;br /&gt;
    parcAuto[0] = citesteMasina();&lt;br /&gt;
&lt;br /&gt;
    afiseazaMasina(parcAuto[0]);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8239</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8239"/>
		<updated>2026-02-20T07:38:09Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==== Structura în C ====&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. În laboratorul următor vom vedea aceasta limitare rezolvată prin noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8238</id>
		<title>C++ POO Lab Lucrarea 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_1&amp;diff=8238"/>
		<updated>2026-02-20T07:36:46Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==== Structura în C ====&lt;br /&gt;
&lt;br /&gt;
Plecând de la limbajul C, ne amintim că acesta pune la dispoziție o serie de tipuri de date primitive, incluse în standardul limbajului. Ca exemple, avem: &amp;#039;&amp;#039;int&amp;#039;&amp;#039;, &amp;#039;&amp;#039;long&amp;#039;&amp;#039;, &amp;#039;&amp;#039;char&amp;#039;&amp;#039;, &amp;#039;&amp;#039;double&amp;#039;&amp;#039;, etc. În plus, există posibilitatea de a crea structuri compuse folosind cuvântul cheie &amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Struct_(C_programming_language) struct]&amp;#039;&amp;#039;. O structură în C este compusă din una sau mai multe variabile care pot fi ori de tip primitiv, ori alte structuri.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare avem un exemplu de definiție a unor structuri în C.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
struct string{&lt;br /&gt;
    char* str;&lt;br /&gt;
    unsigned length;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct person{&lt;br /&gt;
    struct string *first_name;&lt;br /&gt;
    struct string *last_name;&lt;br /&gt;
    unsigned age;&lt;br /&gt;
    float height;&lt;br /&gt;
    float weight;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Se vede că structura &amp;#039;&amp;#039;person&amp;#039;&amp;#039; conține pointeri la două structuri de tip &amp;#039;&amp;#039;string&amp;#039;&amp;#039;. Relația este descrisă de schema bloc următoare (cu exemple de valori pentru variabilele primitive):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations1.png|Schema bloc pentru relația dintre structurile string și person]]&lt;br /&gt;
&lt;br /&gt;
În continuare, vom da un exemplu de utilizare a acestor structuri:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    //make a default string with no content and length = 30&lt;br /&gt;
    struct string * some_string = (struct string*)malloc(sizeof(struct string));&lt;br /&gt;
    unsigned default_length = 30;&lt;br /&gt;
    some_string-&amp;gt;length = default_length;&lt;br /&gt;
    some_string-&amp;gt;str = (char*)malloc(default_length * sizeof(char));&lt;br /&gt;
    strcpy(some_string-&amp;gt;str, &amp;quot;Vasile&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    //make a person structure in which all strings refer to the default empty string&lt;br /&gt;
    struct person* new_person = (struct person*)malloc(sizeof(struct person));&lt;br /&gt;
    new_person-&amp;gt;first_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;last_name = some_string;&lt;br /&gt;
    new_person-&amp;gt;age = 29;&lt;br /&gt;
    new_person-&amp;gt;height = (float)1.7;&lt;br /&gt;
    new_person-&amp;gt;weight = 68.9F;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Persoana se numeste %s %s, are varsta de %d ani, inaltimea %f si greutatea %f\n&amp;quot;, new_person-&amp;gt;first_name-&amp;gt;str, &lt;br /&gt;
        new_person-&amp;gt;last_name-&amp;gt;str,&lt;br /&gt;
        new_person-&amp;gt;age,&lt;br /&gt;
        new_person-&amp;gt;height,&lt;br /&gt;
        new_person-&amp;gt;weight);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În acest exemplu, schema bloc este diferită dintr-un punct de vedere esențial: ambii pointeri de tip string sunt referință la aceeași adresă, respectiv la același string. Astfel, dacă se modifică &amp;#039;&amp;#039;new_person-&amp;gt;first_name&amp;#039;&amp;#039;, atunci implicit se modifică și &amp;#039;&amp;#039;new_person-&amp;gt;last_name&amp;#039;&amp;#039; (de fapt este aceeași structură):&lt;br /&gt;
&lt;br /&gt;
[[Fișier:struct_relations2.png|Schema bloc pentru relația dintre structurile string și person cu același pointer pentru nume]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pentru a face un rezumat, structura, in C, este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; compusă din tipuri primitive, sau alte structuri. Analog cu orice alt tip de dată, se pot defini variabile de tipul structurii, așa cum se pot defini variabile de tip primitiv. Limitarea fundamentală a structurilor este că acestea nu pot conține decât &amp;#039;&amp;#039;&amp;#039;date&amp;#039;&amp;#039;&amp;#039;, nu și &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039;. Astfel se introduce noțiunea de &amp;#039;&amp;#039;&amp;#039;clasă&amp;#039;&amp;#039;&amp;#039;.&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_2&amp;diff=8237</id>
		<title>C++ POO Lab Lucrarea 2</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Lucrarea_2&amp;diff=8237"/>
		<updated>2026-02-20T07:36:23Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Clase și obiecte */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;După parcurgerea acestei platforme, veți deveni familiari cu diferite concepte de programare orientată pe obiecte: clasa, obiectul, câmpul, metoda, constructorul, încapsularea.&lt;br /&gt;
&lt;br /&gt;
= Noțiuni despre paradigme de programare =&lt;br /&gt;
&lt;br /&gt;
De la inventarea mașinilor de calcul, lupta pentru performață și avans tehnologic s-a dat pe două fronturi. Pe de o parte prin îmbunătățirea performațelor hardware-ului, prin creșterea frecveței, a numărului de core-uri, a memoriei disponibile și a complexității setului de instrucțiuni, iar pe de altă parte, prin găsirea de noi metode de programare eficientă a algoritmilor. Aceste metode noi nu însemnă exclusiv limbaje noi, cu toate că dacă urmărim evoluția acestora în ultimii ani, vom observa o creștere semnificativă, atât ca număr, cât și ca varietate. De ce apar în continuare limbaje noi, dacă există deja un număr atât de mare? Există mai multe motive, dar cel principal constă în apariția unor funcționalități noi, care trebuie exprimate în moduri care încă nu există (spre exemplu acceleratoarele SIMD - Single Instruction Multiple Data sunt greoi de programat folosind C, deoarece limbajul nu are suport pentru tipuri de date vectoriale). Dar apariția limbajelor noi mai este influențată de un lucru, și anume apariția unor noi paradigme.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;[http://en.wikipedia.org/wiki/Programming_paradigm Paradigma de programare]&amp;#039;&amp;#039;&amp;#039; se referă la modul în care este descris un algoritm. Sigur, prin descriere nu ne referim la modul în care se fac adunările sau înmulțirile sau la limbajul în sine, ci la un nivel mai înalt, și anume la cum sunt structurate datele, și la legătura dintre structurile de date și secvențele de program care acționează asupra lor. Există un număr relativ mic de paradigme de programare, și vom numi imediat niște exemple, dar e important de reținut că nu se poate spune că una este sau nu mai bună decât cealaltă, ci, ca și în cazul limbajelor de programare, fiecare este optimă pentru anumite clase de aplicații.&lt;br /&gt;
&lt;br /&gt;
== Programarea imperativă procedurală ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Imperative_programming Programarea imperativă] descrie un algoritm la nivel de instrucțiune care modifică starea programului. Programarea procedurală structurează aceste instrucțiuni pe secvențe distincte, numite &amp;#039;&amp;#039;&amp;#039;proceduri&amp;#039;&amp;#039;&amp;#039; sau &amp;#039;&amp;#039;&amp;#039;funcții&amp;#039;&amp;#039;&amp;#039; (a nu se confunda totuși cu programarea funcțională), care acționează asupra unor structuri de date globale, vizibile tuturor procedurilor, sau locale, vizibile fiecărei proceduri în parte. Ca exemplu de limbaj de programare procedural este C-ul original (nu C++). Programele scrise în C sunt construite din funcții (care pot lua argumente, calcula și întoarce valori) și date globale. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Programarea procedurală se folosește pe scară largă în programare la nivel foarte jos (kernel, sistem de operare, embedded), deoarece C-ul oferă control absolut asupra resurselor hardware, și se potrivește foarte bine cu modul în care procesorul execută programul. Pe de altă parte, în cazul aplicațiilor la nivel înalt, cum ar fi editoare de text, aplicații client - server, simulatoare, programe de sinteză, etc., acolo unde se scrie o cantitate enormă de algoritmi, faptul că programarea procedurală nu oferă o structurare a datelor și o legătură între date și procedurile care le folosesc, o face foarte greu de folosit. În aceste cazuri apar probleme de securitate, probleme de memorie, probleme de mentenanță și dezvoltare ulterioară, etc.&lt;br /&gt;
&lt;br /&gt;
== Programarea declarativă funcțională ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Functional_programming Programarea funcțională] se referă la stilul și limbajele de programare în care computația se tratează evaluând expresii matematice. Spre deosebire de programarea imperative, unde apar stări și variabile, programarea funcțională pe bazează pe un sistem formal numit [http://en.wikipedia.org/wiki/Lambda_calculus lambda-calcul], care descrie un program sub forma compunerii unor funcții matematice.&lt;br /&gt;
&lt;br /&gt;
Unul din primele limbaje funcționale este [http://en.wikipedia.org/wiki/Lisp_(programming_language) Lisp] dar există și limbaje funcționale moderne ([https://en.wikipedia.org/wiki/Scala_(programming_language) Scala], [https://en.wikipedia.org/wiki/Haskell_(programming_language) Haskel], etc.). Ce e și mai interesant este faptul că limbajele imperative sau OOP consacrate (C++, Java) au început în ultimul timp să suporte și ele expresii lambda, fapt care duce treptat la apariția unor limbaje de programare hibride.&lt;br /&gt;
&lt;br /&gt;
== Programarea orientată obiect ==&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Object-oriented_programming Programarea orientată obiect] are ca punct de plecare programarea procedurală, în sensul că se bazează tot pe noțiunile de stare și variabile, dar introduce o serie de concepte care ajută la structurarea programelor:&lt;br /&gt;
* clase și obiecte;&lt;br /&gt;
* încapsulare;&lt;br /&gt;
* polimorfism;&lt;br /&gt;
* moștenire.&lt;br /&gt;
&lt;br /&gt;
=== Clase și obiecte ===&lt;br /&gt;
&lt;br /&gt;
==== Clasa în C++ ====&lt;br /&gt;
&lt;br /&gt;
O clasă în C++ se declară similar cu un &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt;, folosind cuvântul cheie &amp;lt;code&amp;gt;class&amp;lt;/code&amp;gt;. De fapt, o structură și o clasă sunt echivalente în C++, cu excepția unui singur detaliu care va fi discutat în secțiunea [[#Modificatori de acces și încapsulare]]. Prin urmare, &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;clasa&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; este un &amp;#039;&amp;#039;&amp;#039;tip de dată&amp;#039;&amp;#039;&amp;#039; și reprezintă un șablon după care se crează (instanțiază) &amp;#039;&amp;#039;&amp;#039;obiecte&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Noțiunea de &amp;#039;&amp;#039;&amp;#039;obiect&amp;#039;&amp;#039;&amp;#039; este inspirat din sistemele reale, în care diverse obiecte de diferite tipuri interacționează pentru a produce un efect dorit, de exemplu piesele unei mașini care conlucrează pentru a face mașina să meargă. Diverse obiecte din mașină sunt similare, fap parte din aceeași clasă de obiecte, spre exemplu o mașina are patru roți și deși aceste obiecte au aceleași proprietăți (de exemplu dimensiune, presiune sau grad de uzură), fiecare din aceste obiecte au valori diferite pentru aceste proprietăți. În plus, toate roțile, indiferent de valorile proprietăților, au același rol, deci aceeași funcționalitate: se învârt pentru a face mașina să se deplaseze, se pot umfla sau desumfla, etc. În programare, proprietățile unei clase de obiecte se definesc prin variabile iar funcționalitatea prin funcții.&lt;br /&gt;
&lt;br /&gt;
Putem spune astfel că o clasă definește proprietățile și funcționalitatea obiectelor, iar fiecare obiect în parte poate avea valori diferite pentru aceste proprietăți. Ca definiții:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039;Clasa&amp;#039;&amp;#039;&amp;#039; este o &amp;#039;&amp;#039;&amp;#039;structură&amp;#039;&amp;#039;&amp;#039; care poate conține variabile, numite &amp;#039;&amp;#039;&amp;#039;câmpuri&amp;#039;&amp;#039;&amp;#039; ale clasei, și funcții, numite &amp;#039;&amp;#039;&amp;#039;metode&amp;#039;&amp;#039;&amp;#039; are clasei. Câmpurile și metodele sunt &amp;#039;&amp;#039;&amp;#039;membrii&amp;#039;&amp;#039;&amp;#039; clasei.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Clasa este un tip de dată. Datele de tipul clasei se numesc &amp;#039;&amp;#039;&amp;#039;obiecte&amp;#039;&amp;#039;&amp;#039;. Obiectele sunt instanțe ale clasei. Astfel, când se creează un obiect nou, se mai spune că se &amp;#039;&amp;#039;&amp;#039;instanțiază&amp;#039;&amp;#039;&amp;#039; un obiect de tipul clasei respective.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
    std::string mName;&lt;br /&gt;
    std::string mColor;&lt;br /&gt;
    unsigned mAge;&lt;br /&gt;
    bool mHasFeathers;&lt;br /&gt;
    &lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, mName.c_str());&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Supraîncărcarea ====&lt;br /&gt;
&lt;br /&gt;
Dacă în limbajul C nu este permisă declararea mai multor funcții cu același nume, în C++ este posibil acest lucru, folosind conceptul de &amp;#039;&amp;#039;&amp;#039;supraîncărcare&amp;#039;&amp;#039;&amp;#039;. Prin urmare, se pot declara funcții sau metode cu același nume, dar doar dacă există totuși diferențe care permit compilatorului să decidă care din aceste funcții este apelată. Diferențele se fac prin &amp;#039;&amp;#039;&amp;#039;semnătura&amp;#039;&amp;#039;&amp;#039; funcției. &lt;br /&gt;
&lt;br /&gt;
Semnătura este formată din următoarele elemente:&lt;br /&gt;
# Numele funcției&lt;br /&gt;
# Tipul argumentelor funcției&lt;br /&gt;
# Ordinea argumentelor funcției&lt;br /&gt;
# Numărul argumentelor funcției&lt;br /&gt;
# Alți specificatori (de exemplu &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Semnătura NU conține și tipul întors de funcție. Prin urmare, funcțiile de mai jos au aceeași semnătură:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
int divide (int n, int m); &lt;br /&gt;
double divide (int n, int m);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constructorul ===&lt;br /&gt;
&lt;br /&gt;
Când se instanțiază obiecte, câmpurile acestora sunt neinițializate. Pentru a atribui valori acestor câmpuri, putem folosi operatorul ”.” pentru a accesa aceste câmpuri, similar cu sintaxa limbajului C:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
int main() {&lt;br /&gt;
    Animal firstAnimal;&lt;br /&gt;
    firstAnimal.mName = &amp;quot;Dog&amp;quot;;&lt;br /&gt;
    firstAnimal.mColor = &amp;quot;black&amp;quot;;&lt;br /&gt;
    firstAnimal.mAge = 2;&lt;br /&gt;
    firstAnimal.mHasFeathers = false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Problema este că în cazul în care se dorește instanțierea unui număr mare de obiecte, acest mod de atribuire de valori câmpurilor devine anevoios. În acest sens, limbajele orientate pe obiecte oferă posibilitatea definirii unor metode speciale care se apelează automat în momentul în care se creează obiecte noi, și care se numesc constructori:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039;Constructorul&amp;#039;&amp;#039;&amp;#039; este o metodă specială, definită în interiorul unei clase, care se apelează automat la instanțierea obiectelor, și care are rolul de a inițializa câmpurile din obiect.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În C++, constructorul poate fi recunoscut după cele două particularități:&lt;br /&gt;
# Are același nume cu numele clasei;&lt;br /&gt;
# Nu are tip returnat (nici măcar &amp;#039;&amp;#039;void&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Astfel, putem crea un constructor nou pentru clasa &amp;#039;&amp;#039;&amp;#039;Animal&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
    std::string mName;&lt;br /&gt;
    std::string mColor;&lt;br /&gt;
    uint8_t mAge;&lt;br /&gt;
    bool mHasFeathers;&lt;br /&gt;
    &lt;br /&gt;
    Animal(std::string name, std::string color, uint8_t age, bool hasFeather) {&lt;br /&gt;
        mName = name;&lt;br /&gt;
        mColor = color;&lt;br /&gt;
        mAge = age;&lt;br /&gt;
        mHasFeathers = hasFeathers;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, mName.c_str());&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Constructorii, fiind metode în clasă, beneficiază de supraîncărcare, deci pot exista mai mulți constructori într-o clasă, dar cu semnături diferite. Astfel, trebuie să aveți în vedere următoarele reguli:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Dacă nu declarați explicit un constructor în clasă, compilatorul va introduce automat un constructor implicit, fără argumente, care nu are niciun efect de inițializare a câmpurilor.&amp;lt;/div&amp;gt;&lt;br /&gt;
# &amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Dacă declarați explicit cel puțin un constructor în clasă, compilatorul nu va mai introduce constructorul implicit. Dacă doriți să puteți crea obiecte folosind constructorul fără argumente, trebuie să-l declarați explicit. Pentru a ușura sintaxa, puteți folosi cuvântul cheie &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; care reprezintă implementarea implicită a constructorului fără argumente&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot; line highlight=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
    std::string mName;&lt;br /&gt;
    std::string mColor;&lt;br /&gt;
    uint8_t mAge;&lt;br /&gt;
    bool mHasFeathers;&lt;br /&gt;
    &lt;br /&gt;
    Animal() = default;&lt;br /&gt;
&lt;br /&gt;
    Animal(std::string name, std::string color, uint8_t age, bool hasFeather) {&lt;br /&gt;
        mName = name;&lt;br /&gt;
        mColor = color;&lt;br /&gt;
        mAge = age;&lt;br /&gt;
        mHasFeathers = hasFeathers;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, mName.c_str());&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Inițializarea și atribuirea câmpurilor de către constructor ====&lt;br /&gt;
&lt;br /&gt;
În momentul în care se apelează un constructor, acesta trebuie să modifice valorile câmpurilor obiectului. Acest lucru se poate face în două moduri:&lt;br /&gt;
# Prin atribuire&lt;br /&gt;
# Prin inițializare&lt;br /&gt;
&lt;br /&gt;
===== Atribuirea câmpurilor =====&lt;br /&gt;
&lt;br /&gt;
Varianta cea mai simplă, dar nu și cea mai eficientă, este accea de a atribui valori câmpurilor. Acest lucru este evidențiat în exemplul de mai sus. Totuși, există și posibilitatea ca numele argumentelor constructorului să coincidă cu numele câmpurilor. În această situație, atribuirea devine ambiguă. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Când utilizați o variabilă, compilatorul o caută incremental, din blocul de instrucțiuni (scope-ul) cel mai apropiat în exterior. Deci dacă există o variabilă locală și un câmp cu același nume, compilatorul va considera variabila locală ca fiind cea la care vă referiți.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a rezolva acest conflict de nume, se poate utiliza cuvântul cheie &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; care reprezintă un pointer la obiectul curent (cel care se construiește de către constructor):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
    std::string name;&lt;br /&gt;
    std::string color;&lt;br /&gt;
    uint8_t age;&lt;br /&gt;
    bool hasFeathers;&lt;br /&gt;
    &lt;br /&gt;
    Animal(std::string name, std::string color, uint8_t age, bool hasFeather) {&lt;br /&gt;
        this-&amp;gt;name = name;&lt;br /&gt;
        this-&amp;gt;color = color;&lt;br /&gt;
        this-&amp;gt;age = age;&lt;br /&gt;
        this-&amp;gt;hasFeathers = hasFeathers;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, name.c_str());&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Cuvântul cheie &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; poate fi folosit în orice metodă (ne-statică) dintr-o clasă (inclusiv în constructor), și reprezintă pointer la obiectul curent (pentru care s-a apelat metoda respecitvă). Deci poate fi folosit mai departe împreună cu operatorul &amp;lt;code&amp;gt;-&amp;gt;&amp;lt;/code&amp;gt; pentru a accesa membrii (câmpurile sau metodele) obiectului.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;sfat&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;darkgreen&amp;quot;&amp;gt;Sfat:&amp;lt;/font&amp;gt; Pentru a evita problemele de conflict de nume între câmpuri și variabile locale, folosiți întotdeauna convenția de a numi câmpurile cu prefixul &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt;: &amp;#039;&amp;#039;mName&amp;#039;&amp;#039;, &amp;#039;&amp;#039;mHasFeathers&amp;#039;&amp;#039; sau &amp;#039;&amp;#039;mMember&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Inițializarea câmpurilor =====&lt;br /&gt;
&lt;br /&gt;
Limbajul C++ pune la dispoziție o sintaxă specială care permite inițializarea câmpurilor în constructor. Acest lucru este esențial atunci când se declară câmpuri constante sau câmpuri de tip referință. Diferența dintre atribuire inițializare este că cea din urmă se face doar la declararea variabilei iar prima se poate face oricând după aceea, atât timp cât variabila nu este declarată constantă. &lt;br /&gt;
&lt;br /&gt;
Sintaxa este evidențiată mai jos:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot; line highlight=&amp;quot;7&amp;quot;&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
    std::string mMame;&lt;br /&gt;
    std::string mColor;&lt;br /&gt;
    uint8_t mAge;&lt;br /&gt;
    bool mHasFeathers;&lt;br /&gt;
    &lt;br /&gt;
    Animal(std::string name, std::string color, uint8_t age, bool hasFeather) : mName(name), mColor(color), mAge(age), mHasFeathers(hasFeathers) {&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, mName.c_str());&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Numele de dinainte de paranteză este cel al câmpului, iar în paranteză este expresia cu care se inițializează acesta.&lt;br /&gt;
&lt;br /&gt;
=== Modificatori de acces și încapsulare ===&lt;br /&gt;
&lt;br /&gt;
Membrii unei clase se pot împărți în două mari categorii:&lt;br /&gt;
# Membri care se expun pentru a fi utilizați de alte obiecte;&lt;br /&gt;
# Membri care există doar pentru a ajuta la implementarea internă a funcționalității obiectului. &lt;br /&gt;
&lt;br /&gt;
Pentru a permite ascunderea anumitor membri ai unei clase, limbajele orientate pe obiecte oferă conceptul de modificatori de acces. În C++ există trei modificatori de acces, din care doi sunt prezentați mai jos:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;public&amp;#039;&amp;#039;&amp;#039; - membrii declarați publici sunt vizibili și accesibili din orice alt obiect de orice tip;&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;private&amp;#039;&amp;#039;&amp;#039; - membrii declarați privați nu sunt accesibili decât din obiecte de același tip cu obiectul respectiv.&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;protected&amp;#039;&amp;#039;&amp;#039; - membrii declarați protejați nu sunt accesibili decât din obiecte de același tip cu obiectul respectiv sau obiecte de tip clase derivate din clasa respectivă (pentru &amp;#039;&amp;#039;&amp;#039;derivat&amp;#039;&amp;#039;&amp;#039;, vedeți paragraful moștenire).&lt;br /&gt;
&lt;br /&gt;
Se recomandă ca în general toate câmpurile să fie declarate private. În acest fel, este se &amp;#039;&amp;#039;încapsulează&amp;#039;&amp;#039; în obiect, iar accesul la ele se face prin metode publice care permit validarea modificărilor sau a citirilor de date din obiect:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
class Animal {&lt;br /&gt;
private:&lt;br /&gt;
    std::string mName;&lt;br /&gt;
    std::string mColor;&lt;br /&gt;
    int mAge;&lt;br /&gt;
    bool mHasFeathers;&lt;br /&gt;
&lt;br /&gt;
public:&lt;br /&gt;
    void makeSound() {&lt;br /&gt;
        printf(&amp;quot;Animal %s makes a sound!\n&amp;quot;, mName.c_str());&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // this is a getter method&lt;br /&gt;
    std::string getName() {&lt;br /&gt;
        return mName;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // this is a setter method&lt;br /&gt;
    void setAge(int age) {&lt;br /&gt;
        if(age &amp;gt; 0) {&lt;br /&gt;
            mAge = age;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție: &amp;lt;/font&amp;gt;Una din cele două diferențe între &amp;lt;code&amp;gt;class&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;struct&amp;lt;/code&amp;gt; este că pentru prima, modificatorul de acces implicit este &amp;#039;&amp;#039;&amp;#039;private&amp;#039;&amp;#039;&amp;#039; iar pentru a doua este &amp;#039;&amp;#039;&amp;#039;public&amp;#039;&amp;#039;&amp;#039;. Prin urmare, modificatorul &amp;#039;&amp;#039;&amp;#039;private&amp;#039;&amp;#039;&amp;#039; de la începutul clasei din exemplul de mai sus poate lipsi.&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Utile&amp;diff=8236</id>
		<title>C++ POO Lab Utile</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=C%2B%2B_POO_Lab_Utile&amp;diff=8236"/>
		<updated>2026-02-20T07:34:16Z</updated>

		<summary type="html">&lt;p&gt;Cbira: Pagină nouă: În acest laborator ne vom reaminti sintaxa limbajului C, vom exersa utilizarea mediului de dezvoltare CLion și a &amp;#039;&amp;#039;debugger&amp;#039;&amp;#039;-ului.  == Tool-ul de depanare GDB == Depanatorul GNU...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;În acest laborator ne vom reaminti sintaxa limbajului C, vom exersa utilizarea mediului de dezvoltare CLion și a &amp;#039;&amp;#039;debugger&amp;#039;&amp;#039;-ului.&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută (pentru a determina motivul rezultatelor necorespunzătoare) sau ce s-a întâmplat cu programul în momentul în care a fost întreruptă execuţia în mod neaşteptat.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GDB este capabil de a îndeplini 4 categorii de operații (și alte operaţii intermediare lor):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să determine o pauză in execuţia programului în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să modifice anumite valori în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n) {&lt;br /&gt;
    if (n == 0) {&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact = 0;&lt;br /&gt;
    for (i = 1; i &amp;lt;= n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do {&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    } while (n &amp;lt; 0 || n &amp;gt; 8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for (i = 0; i &amp;lt;= n; i++) {&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20          scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21      }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22      unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23      for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24          suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4     if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5         return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13  }&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23      for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24          suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4     if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8     unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9     for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10          fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9     for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12      return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;    Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
După acest laborator veți putea folosi IDE-ul CLion pentru a scrie și depana programe în C. Totodată veți relua și recapitula noțiunile legate de pointeri în C.&lt;br /&gt;
&lt;br /&gt;
= Utilizarea IDE-ului CLion =&lt;br /&gt;
&lt;br /&gt;
[https://www.jetbrains.com/clion CLion] este un mediu integrat de dezvoltare (IDE) care permite dezvoltarea de programe în limbajele C și C++. CLion nu instalează și compilator pentru C/C++, acesta trebuie instalat manual, în prealabil. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Imaginea de Linux folosită la Programarea Calculatoarelor are deja instalat compilatorul de C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instalarea GCC ==&lt;br /&gt;
&lt;br /&gt;
=== Instalarea GCC în Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru instalarea compilatorului de C (GCC) în distribuțiile de Linux provenite din Ubuntu (Ubuntu, Kubuntu, Xubuntu, Mint, LMDE, etc.) se poate folosi comanda:&lt;br /&gt;
&lt;br /&gt;
 apt-get install -y build-essential&lt;br /&gt;
&lt;br /&gt;
=== Instalarea GCC în Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru compilarea de programe cu GCC în Windows, aveți nevoie de instalarea acestui compilator care poate fi făcută prin instalarea unuia din următoarele două suite de programe:&lt;br /&gt;
* [https://cygwin.com Cygwin] - Tutorial de instalare [https://cygwin.com/install.html aici].&lt;br /&gt;
* [http://www.mingw.org/ MinGW] - Tutorial de instalare [http://www.mingw.org/wiki/InstallationHOWTOforMinGW aici].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Nu uitați ca la instalare să bifați în lista de pachete și compilatorul de C (&amp;lt;code&amp;gt;gcc&amp;lt;/code&amp;gt;), &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; și &amp;lt;code&amp;gt;git&amp;lt;/code&amp;gt;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instalarea CLion ==&lt;br /&gt;
&lt;br /&gt;
De la adresa https://www.jetbrains.com/clion/download/#section=linux puteți descărca kitul de instalare pentru sistemul vostru de operare.&lt;br /&gt;
După instalare, urmaţi următorii paşi de configurare, în funcţie de suita de programe aleasă:&lt;br /&gt;
* [https://www.jetbrains.com/help/clion/quick-tutorial-on-configuring-clion-on-windows.html#Cygwin Configurare CLion cu Cygwin]&lt;br /&gt;
* [https://www.jetbrains.com/help/clion/quick-tutorial-on-configuring-clion-on-windows.html#MinGW  Configurare CLion cu MinGW]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Realizarea unui proiect ==&lt;br /&gt;
&lt;br /&gt;
Odată pornit, CLion oferă posibilitatea de a deschide un proiect existent, sau de a crea unul nou. Vrem să realizăm un proiect nou, aşadar se va alege &amp;#039;&amp;#039;&amp;#039;New Project&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Se poate realiza un nou proiect atunci când altul este deja deschis folosind meniul &amp;lt;code&amp;gt;File - New Project &amp;lt;/code&amp;gt; .&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier:Welcome_to_clion.png | 600px | Imaginea 1]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Mai departe se va selecta categoria &amp;#039;&amp;#039;&amp;#039;C++ Executable&amp;#039;&amp;#039;&amp;#039; şi se va introduce locaţia proiectului.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; În imagine se observă că locaţia introdusă este &amp;#039;&amp;#039;&amp;#039;/home/student/projects/NewProject&amp;#039;&amp;#039;&amp;#039;. Se recomandă ca directorul în care se realizează proiectul să aibă numele proiectului, sau un nume sugestiv (în imagine &amp;#039;&amp;#039;&amp;#039;NewProject&amp;#039;&amp;#039;&amp;#039;)&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Fișier:New_project_location_clion.png | 600px | Imaginea 2]]&lt;br /&gt;
&lt;br /&gt;
== Componentele IDE-ului CLion == &lt;br /&gt;
&lt;br /&gt;
[[Fișier:CLion_env.png | 1000px | Imaginea 3]]&lt;br /&gt;
&lt;br /&gt;
La crearea unui nou proiect, IDE-ul CLion generează automat fişierul &amp;#039;&amp;#039;&amp;#039;main.cpp&amp;#039;&amp;#039;&amp;#039;. Acesta conţine un exemplu program ce va fi rescris de către utilizator. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secţiunile marcate în imagine reprezintă:&lt;br /&gt;
# Zona &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;verde&amp;lt;/span&amp;gt; - &amp;#039;&amp;#039;&amp;#039;Project view&amp;#039;&amp;#039;&amp;#039; indică toate fişierele şi directoarele ce alcătuiesc proiectul.&lt;br /&gt;
# Zona &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;albastră&amp;lt;/span&amp;gt; - &amp;#039;&amp;#039;&amp;#039;Editor&amp;#039;&amp;#039;&amp;#039; este fereastra de vizualizare şi editare a textului &lt;br /&gt;
# Zona &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;roşie&amp;lt;/span&amp;gt; - &amp;#039;&amp;#039;&amp;#039;Toolbar&amp;#039;&amp;#039;&amp;#039; oferă acces rapid pentru operaţiile uzuale. Dintre acestea, cel mai des vom folosi:&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Build&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_build_button.png | 16px]]&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Run&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_run_button.png | 16px]]&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Debug&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_debug_button.png | 16px]]&lt;br /&gt;
# Zona &amp;lt;span style=&amp;quot;color: gold&amp;quot;&amp;gt;galbenă&amp;lt;/span&amp;gt; - &amp;#039;&amp;#039;&amp;#039;Run&amp;#039;&amp;#039;&amp;#039; este zona în care se introduc datele de intrare şi se în care vor fi afişate datele de ieşire.&lt;br /&gt;
&lt;br /&gt;
== Exemplu de program în modul &amp;#039;&amp;#039;debug&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
Copiați codul de mai jos înlocuind programul deja existent în fișierul &amp;#039;&amp;#039;main.c&amp;#039;&amp;#039;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    printf(&amp;quot;Debugging program...\n&amp;quot;);&lt;br /&gt;
    int value = 0;&lt;br /&gt;
    value = value + 1;&lt;br /&gt;
    value++;&lt;br /&gt;
    value = value * 2;&lt;br /&gt;
    value -= 1;&lt;br /&gt;
    printf(&amp;quot;Value is now %d!\n&amp;quot;, value);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a executa programul în modul debug trebuie sa introducem cel puţin un &amp;#039;&amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039;&amp;#039;. Astfel indicăm programului unde se va opri pentru a ne acorda control asupra execuţiei, având posibilitatea de a continua execuţia pas cu pas. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Introducem un nou breakpoint dând click în dreptul liniei de la care vrem să obţinem controlul. În cazul nostru, vom alege să indroducem un breakpoint chiar la definirea variabilei &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CLion_breakpoint.png | 1000px | Imaginea 4]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Atenție:&amp;lt;/span&amp;gt; Când alegem locaţia unui breakpoint trebuie să ţinem cont de următorul aspect: în modul &amp;#039;&amp;#039;&amp;#039;debug&amp;#039;&amp;#039;&amp;#039; programul se va opri &amp;#039;&amp;#039;&amp;#039;înainte&amp;#039;&amp;#039;&amp;#039; de a executa linia în dreptul căreia a fost introdus breakpoint-ul!&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
În continuare, trebuie se pornim execuţia programului in modul debug [[Fișier:CLion_debug_button.png | 16px]]. Observăm apariţia ferestrei Debug (chenarul albastru, Imaginea 5) ce conţine următoarele:&lt;br /&gt;
#Zona &amp;lt;span style=&amp;quot;color: gold&amp;quot;&amp;gt;galbenă&amp;lt;/span&amp;gt; - fereastra cu toate variabilele declarate, împreună cu valorile lor. Momentan nu există nicio variabilă declarată (deoarece linia asupra la care ne-am oprit nu a fost încă executată!)&lt;br /&gt;
#Zona &amp;lt;span style=&amp;quot;color: red&amp;quot;&amp;gt;roşie&amp;lt;/span&amp;gt; - Permite trecerea între fereastra pentru procesul de depanare (&amp;#039;&amp;#039;&amp;#039;Debugger&amp;#039;&amp;#039;&amp;#039;) şi fereastra în care se afişează/introduc datele (&amp;#039;&amp;#039;&amp;#039;Console&amp;#039;&amp;#039;&amp;#039;)&lt;br /&gt;
#Zona &amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;verde&amp;lt;/span&amp;gt; - Conţine comenzile pentru controlul execuţiei în modul debug (comenzi numite &amp;#039;&amp;#039;&amp;#039;stepping actions&amp;#039;&amp;#039;&amp;#039;):&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Step over&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_step_over.png | 16px]] - Execută comenzile de pe linia curentă şi trece la următoarea linie&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Step into&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_step_into.png | 16px]] - Programul va executa linia curentă iar dacă pe linia curentă există un apel de funcție, se va opri pe prima linie din funcția respectivă. Această comandă este utilă atunci cand pe linia curentă se află un apel de funcţie şi vrem sa studiem comportamentul codului din interiorul funcţiei.&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Step out&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_step_out.png | 16px]] - Termină de executat funcţia în care se află linia curentă&lt;br /&gt;
#*&amp;#039;&amp;#039;&amp;#039;Run to cursor&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_run_to_cursor.png | 16px]] - Execută toate instructiunile până se intâlneste cursorul.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; În modul debug, linia curentă este marcată de către mediul de dezvoltare prin colorarea acesteia cu albastru.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alte comenzi utile:&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Resume program&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_resume_project.png | 16px]] - Continuă execuţia pâmă la următorul breakpoint (dacă nu există, se va executa până la final)&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Stop&amp;#039;&amp;#039;&amp;#039; [[Fișier:CLion_stop.png | 16px]] - Se opreşte definitv execuţia programului, împreună cu modul debug&lt;br /&gt;
&lt;br /&gt;
[[Fișier:CLion_debug_process.png | 1000px | Imaginea 5]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a exersa utilizarea sistemului de debug, realizați următoarele operații:&lt;br /&gt;
# Parcurgeti tot programul folosind &amp;#039;&amp;#039;&amp;#039;Step Over&amp;#039;&amp;#039;&amp;#039; și vizualizând valoarea variabilei &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt; la fiecare pas, până la ultima linie din program, unde utilizați &amp;#039;&amp;#039;&amp;#039;Resume program&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# Reporniți aplicația în modul de debug și puneți un al doilea &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; pe linia cu apelul funcției &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt;. &lt;br /&gt;
# Folosiți &amp;#039;&amp;#039;&amp;#039;Resume program&amp;#039;&amp;#039;&amp;#039; pentru a ajunge la al doilea &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039;.&lt;br /&gt;
# Odată ajunși acolo, folosiți &amp;#039;&amp;#039;&amp;#039;Step In&amp;#039;&amp;#039;&amp;#039; pentru a intra în funcția &amp;lt;code&amp;gt;printf&amp;lt;/code&amp;gt; (neavând codul sursă, veți vedea codul de asamblare obținut din dezasamblarea fișierului obiect de către GDB).&lt;br /&gt;
# Folosiți &amp;#039;&amp;#039;&amp;#039;Step Out&amp;#039;&amp;#039;&amp;#039; pentru a reveni în funcția &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; și apoi &amp;#039;&amp;#039;&amp;#039;Resume program&amp;#039;&amp;#039;&amp;#039; pentru a termina execuția.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Formatare automată a codului ===&lt;br /&gt;
&lt;br /&gt;
CLion oferă opțiunea de a formata automat codul prin selectarea &amp;#039;&amp;#039;&amp;#039;Code -&amp;gt; Reformat Code&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
Ce probleme rezolvă această formatare automată:&lt;br /&gt;
* alinierea liniilor în funcție de blocurile de instrucțiuni și tipurile de &amp;#039;&amp;#039;statements&amp;#039;&amp;#039; de pe fiecare linie;&lt;br /&gt;
* plasarea sau eliminarea de spații acolo unde este necasar.&lt;br /&gt;
Ce probleme NU rezolvă această formatare automată;&lt;br /&gt;
* lipsa acoladelor de la blocurile &amp;#039;&amp;#039;&amp;#039;if&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;for&amp;#039;&amp;#039;&amp;#039;;&lt;br /&gt;
* numele insuficient de sugestive pentru numele de funcții, structuri sau variabile.&lt;br /&gt;
&lt;br /&gt;
Stilul conform căruia este modificat codul poate fi configurat folosind meniul &amp;lt;code&amp;gt;File|Settings|Editor|CodeStyle&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generare automată a codului ===&lt;br /&gt;
&lt;br /&gt;
CLion oferă posibilitatea de a genera fragmente de cod des înâlnite, precum constructori şi operatori în interiorul claselor. Această acţiune poate fi realizată folosind meniul &amp;lt;code&amp;gt; Code|Generate&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Altele ===&lt;br /&gt;
* [https://www.jetbrains.com/help/clion/using-todo.html TODO Comments]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Nu uitați de regulile următoare: [[Convenții de cod - C]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8235</id>
		<title>Programare Orientată pe Obiecte (C++)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8235"/>
		<updated>2026-02-20T07:33:13Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Tutorial Utilizare CLion IDE si debugger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
Scopul laboratorului de Programare Orientată Obiect este de a introduce studentului conceptele paradigmei de programare orientată pe obiecte, aprofundarea limbajului C++, precum și familiarizarea cu tehnicile de programare specifice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate lucrările acestui laborator pleacă de la premiza că sunteți deja familiarizați cu sintaxa limbajului C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate fișierele/ programele scrise la fiecare laborator se pot salva, pe e-mail, pe un stick USB, pe un repository personal de Git sau pe Moodle.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platforme de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[C++ POO Lab Lucrarea 1]] - recapitulare: pointeri și structuri&lt;br /&gt;
# [[C++ POO Lab Lucrarea 2]] - paradigme de programare; clasa, obiectul, câmpul și metoda; supraîncărcarea; constructorul; încapsularea și modificatorii de acces&lt;br /&gt;
# [[C++ POO Lab Lucrarea 3]] - destructorul; referința; metode &amp;#039;&amp;#039;const-qualified&amp;#039;&amp;#039;; supraîncărcarea operatorilor; constructorul de copiere și operatorul de copiere prin atribuire&lt;br /&gt;
# [[C++ POO Lab Lucrarea 4]] - moștenirea; polimorfismul - metode virtuale și pur virtuale; clase abstracte&lt;br /&gt;
# [[C++ POO Lab Lucrarea 5]] - tratarea excepțiilor&lt;br /&gt;
&amp;lt;!-- # [[C++ POO Lab Lucrarea 6]] - aplicații grafice - QT. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare g++ (Compilatorul C++ de la GNU) ==&lt;br /&gt;
&lt;br /&gt;
=== Instalare Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru Windows, compilatorul g++ poate fi instalat prin [http://www.mingw.org MinGW]. Urmăriți instrucțiunile de instalare și nu uitați să bifați compilatorul de C++ și utilitarul &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Instalare Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru Ubuntu, deschideți un terminal și tastați următoarea comandă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare CLion IDE ==&lt;br /&gt;
&lt;br /&gt;
Pentru toate sistemele de operare, urmăriți instrucțiunile prezentate pe [https://www.jetbrains.com/help/clion/installation-guide.html site-ul oficial].&lt;br /&gt;
&lt;br /&gt;
== Tutorial Utilizare CLion IDE si Debugger ==&lt;br /&gt;
&lt;br /&gt;
[[C++ POO Lab Utile]] - utilizarea IDE-ului CLion și a debugger-ului&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8234</id>
		<title>Programare Orientată pe Obiecte (C++)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8234"/>
		<updated>2026-02-20T07:32:58Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
Scopul laboratorului de Programare Orientată Obiect este de a introduce studentului conceptele paradigmei de programare orientată pe obiecte, aprofundarea limbajului C++, precum și familiarizarea cu tehnicile de programare specifice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate lucrările acestui laborator pleacă de la premiza că sunteți deja familiarizați cu sintaxa limbajului C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate fișierele/ programele scrise la fiecare laborator se pot salva, pe e-mail, pe un stick USB, pe un repository personal de Git sau pe Moodle.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platforme de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[C++ POO Lab Lucrarea 1]] - recapitulare: pointeri și structuri&lt;br /&gt;
# [[C++ POO Lab Lucrarea 2]] - paradigme de programare; clasa, obiectul, câmpul și metoda; supraîncărcarea; constructorul; încapsularea și modificatorii de acces&lt;br /&gt;
# [[C++ POO Lab Lucrarea 3]] - destructorul; referința; metode &amp;#039;&amp;#039;const-qualified&amp;#039;&amp;#039;; supraîncărcarea operatorilor; constructorul de copiere și operatorul de copiere prin atribuire&lt;br /&gt;
# [[C++ POO Lab Lucrarea 4]] - moștenirea; polimorfismul - metode virtuale și pur virtuale; clase abstracte&lt;br /&gt;
# [[C++ POO Lab Lucrarea 5]] - tratarea excepțiilor&lt;br /&gt;
&amp;lt;!-- # [[C++ POO Lab Lucrarea 6]] - aplicații grafice - QT. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare g++ (Compilatorul C++ de la GNU) ==&lt;br /&gt;
&lt;br /&gt;
=== Instalare Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru Windows, compilatorul g++ poate fi instalat prin [http://www.mingw.org MinGW]. Urmăriți instrucțiunile de instalare și nu uitați să bifați compilatorul de C++ și utilitarul &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Instalare Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru Ubuntu, deschideți un terminal și tastați următoarea comandă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare CLion IDE ==&lt;br /&gt;
&lt;br /&gt;
Pentru toate sistemele de operare, urmăriți instrucțiunile prezentate pe [https://www.jetbrains.com/help/clion/installation-guide.html site-ul oficial].&lt;br /&gt;
&lt;br /&gt;
== Tutorial Utilizare CLion IDE si debugger ==&lt;br /&gt;
&lt;br /&gt;
[[C++ POO Lab Utile]] - utilizarea IDE-ului CLion și a debugger-ului&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8233</id>
		<title>Programare Orientată pe Obiecte (C++)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8233"/>
		<updated>2026-02-20T07:31:50Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Platforme de laborator */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
Scopul laboratorului de Programare Orientată Obiect este de a introduce studentului conceptele paradigmei de programare orientată pe obiecte, aprofundarea limbajului C++, precum și familiarizarea cu tehnicile de programare specifice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate lucrările acestui laborator pleacă de la premiza că sunteți deja familiarizați cu sintaxa limbajului C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate fișierele/ programele scrise la fiecare laborator se pot salva, pe e-mail, pe un stick USB, pe un repository personal de Git sau pe Moodle.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platforme de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[C++ POO Lab Lucrarea 1]] - recapitulare: pointeri și structuri&lt;br /&gt;
# [[C++ POO Lab Lucrarea 2]] - paradigme de programare; clasa, obiectul, câmpul și metoda; supraîncărcarea; constructorul; încapsularea și modificatorii de acces&lt;br /&gt;
# [[C++ POO Lab Lucrarea 3]] - destructorul; referința; metode &amp;#039;&amp;#039;const-qualified&amp;#039;&amp;#039;; supraîncărcarea operatorilor; constructorul de copiere și operatorul de copiere prin atribuire&lt;br /&gt;
# [[C++ POO Lab Lucrarea 4]] - moștenirea; polimorfismul - metode virtuale și pur virtuale; clase abstracte&lt;br /&gt;
# [[C++ POO Lab Lucrarea 5]] - tratarea excepțiilor&lt;br /&gt;
&amp;lt;!-- # [[C++ POO Lab Lucrarea 6]] - aplicații grafice - QT. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare g++ (Compilatorul C++ de la GNU) ==&lt;br /&gt;
&lt;br /&gt;
=== Instalare Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru Windows, compilatorul g++ poate fi instalat prin [http://www.mingw.org MinGW]. Urmăriți instrucțiunile de instalare și nu uitați să bifați compilatorul de C++ și utilitarul &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Instalare Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru Ubuntu, deschideți un terminal și tastați următoarea comandă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare CLion IDE ==&lt;br /&gt;
&lt;br /&gt;
Pentru toate sistemele de operare, urmăriți instrucțiunile prezentate pe [https://www.jetbrains.com/help/clion/installation-guide.html site-ul oficial].&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8232</id>
		<title>Programare Orientată pe Obiecte (C++)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8232"/>
		<updated>2026-02-20T07:31:20Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Platforme de laborator */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
Scopul laboratorului de Programare Orientată Obiect este de a introduce studentului conceptele paradigmei de programare orientată pe obiecte, aprofundarea limbajului C++, precum și familiarizarea cu tehnicile de programare specifice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate lucrările acestui laborator pleacă de la premiza că sunteți deja familiarizați cu sintaxa limbajului C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate fișierele/ programele scrise la fiecare laborator se pot salva, pe e-mail, pe un stick USB, pe un repository personal de Git sau pe Moodle.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platforme de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[C++ POO Lab Utile]] - utilizarea IDE-ului CLion și a debugger-ului&lt;br /&gt;
# [[C++ POO Lab Lucrarea 1]] - recapitulare: pointeri și structuri&lt;br /&gt;
# [[C++ POO Lab Lucrarea 2]] - paradigme de programare; clasa, obiectul, câmpul și metoda; supraîncărcarea; constructorul; încapsularea și modificatorii de acces&lt;br /&gt;
# [[C++ POO Lab Lucrarea 3]] - destructorul; referința; metode &amp;#039;&amp;#039;const-qualified&amp;#039;&amp;#039;; supraîncărcarea operatorilor; constructorul de copiere și operatorul de copiere prin atribuire&lt;br /&gt;
# [[C++ POO Lab Lucrarea 4]] - moștenirea; polimorfismul - metode virtuale și pur virtuale; clase abstracte&lt;br /&gt;
# [[C++ POO Lab Lucrarea 5]] - tratarea excepțiilor&lt;br /&gt;
&amp;lt;!-- # [[C++ POO Lab Lucrarea 6]] - aplicații grafice - QT. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare g++ (Compilatorul C++ de la GNU) ==&lt;br /&gt;
&lt;br /&gt;
=== Instalare Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru Windows, compilatorul g++ poate fi instalat prin [http://www.mingw.org MinGW]. Urmăriți instrucțiunile de instalare și nu uitați să bifați compilatorul de C++ și utilitarul &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Instalare Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru Ubuntu, deschideți un terminal și tastați următoarea comandă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare CLion IDE ==&lt;br /&gt;
&lt;br /&gt;
Pentru toate sistemele de operare, urmăriți instrucțiunile prezentate pe [https://www.jetbrains.com/help/clion/installation-guide.html site-ul oficial].&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8231</id>
		<title>Programare Orientată pe Obiecte (C++)</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Programare_Orientat%C4%83_pe_Obiecte_(C%2B%2B)&amp;diff=8231"/>
		<updated>2026-02-20T07:30:35Z</updated>

		<summary type="html">&lt;p&gt;Cbira: /* Platforme de laborator */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Scopul laboratorului ==&lt;br /&gt;
&lt;br /&gt;
Scopul laboratorului de Programare Orientată Obiect este de a introduce studentului conceptele paradigmei de programare orientată pe obiecte, aprofundarea limbajului C++, precum și familiarizarea cu tehnicile de programare specifice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate lucrările acestui laborator pleacă de la premiza că sunteți deja familiarizați cu sintaxa limbajului C.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;lt;font color=&amp;quot;#ff0000&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt; Toate fișierele/ programele scrise la fiecare laborator se pot salva, pe e-mail, pe un stick USB, pe un repository personal de Git sau pe Moodle.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Platforme de laborator ==&lt;br /&gt;
&lt;br /&gt;
# [[C++ POO Lab Lucrarea 0]] - utilizarea IDE-ului CLion și a debugger-ului&lt;br /&gt;
# [[C++ POO Lab Lucrarea 1]] - recapitulare: pointeri și structuri&lt;br /&gt;
# [[C++ POO Lab Lucrarea 2]] - paradigme de programare; clasa, obiectul, câmpul și metoda; supraîncărcarea; constructorul; încapsularea și modificatorii de acces&lt;br /&gt;
# [[C++ POO Lab Lucrarea 3]] - destructorul; referința; metode &amp;#039;&amp;#039;const-qualified&amp;#039;&amp;#039;; supraîncărcarea operatorilor; constructorul de copiere și operatorul de copiere prin atribuire&lt;br /&gt;
# [[C++ POO Lab Lucrarea 4]] - moștenirea; polimorfismul - metode virtuale și pur virtuale; clase abstracte&lt;br /&gt;
# [[C++ POO Lab Lucrarea 5]] - tratarea excepțiilor&lt;br /&gt;
&amp;lt;!-- # [[C++ POO Lab Lucrarea 6]] - aplicații grafice - QT. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare g++ (Compilatorul C++ de la GNU) ==&lt;br /&gt;
&lt;br /&gt;
=== Instalare Windows ===&lt;br /&gt;
&lt;br /&gt;
Pentru Windows, compilatorul g++ poate fi instalat prin [http://www.mingw.org MinGW]. Urmăriți instrucțiunile de instalare și nu uitați să bifați compilatorul de C++ și utilitarul &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Instalare Linux ===&lt;br /&gt;
&lt;br /&gt;
Pentru Ubuntu, deschideți un terminal și tastați următoarea comandă:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorial Instalare CLion IDE ==&lt;br /&gt;
&lt;br /&gt;
Pentru toate sistemele de operare, urmăriți instrucțiunile prezentate pe [https://www.jetbrains.com/help/clion/installation-guide.html site-ul oficial].&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8230</id>
		<title>Legarea bibliotecii math in cmake</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8230"/>
		<updated>2026-02-01T09:58:33Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dupa compilarea fiecarui modul c, urmeaza etapa de link-editare. Daca in timpul acelei etape linkerul nu gaseste o functie pe care o chemati, va afisa la consola o eroare de acest tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Scanning dependencies of target ClionExample&lt;br /&gt;
[ 50%] Building C object CMakeFiles/ClionExample.dir/main.c.o&lt;br /&gt;
[100%] Linking C executable ClionExample&lt;br /&gt;
CMakeFiles/ClionExample.dir/main.c.o: In function `main&amp;#039;:&lt;br /&gt;
/home/student/CLionProjects/ClionExample/main.c:10: undefined reference to `sqrt&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acesta eroare se intampla asa cum se observa, nu la compilare (la consola se afiseaza Linking C executable ... si apoi eroarea &amp;quot;undefined referece to&amp;quot; respectiva functie =&amp;gt; la linkeditare apare eroarea. Motivul este: nu s-a inclus biblioteca math in procesul de linkeditare a executabilului. Pentru a o rezolva, trebuie indicat in reteta de build (fisierul CMakeLists.txt) adaugarea bibliotecii math. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
target_link_libraries(PROIECTUL_MEU m)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un exemplu de fisier CMakeLists.txt modificat se poate vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:LinkMathLibCmake.png|faracadru|upright=2]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8229</id>
		<title>Legarea bibliotecii math in cmake</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8229"/>
		<updated>2026-02-01T09:57:27Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dupa compilarea fiecarui modul c, urmeaza etapa de link-editare. Daca in timpul acelei etape linkerul nu gaseste o functie pe care o chemati, va afisa la consola o eroare de acest tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Scanning dependencies of target untitled2&lt;br /&gt;
[ 50%] Building C object CMakeFiles/untitled2.dir/main.c.o&lt;br /&gt;
[100%] Linking C executable untitled2&lt;br /&gt;
CMakeFiles/untitled2.dir/main.c.o: In function `main&amp;#039;:&lt;br /&gt;
/home/student/CLionProjects/untitled2/main.c:10: undefined reference to `sqrt&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acesta eroare se intampla asa cum se observa, nu la compilare (la consola se afiseaza Linking C executable ... si apoi eroarea &amp;quot;undefined referece to&amp;quot; respectiva functie =&amp;gt; la linkeditare apare eroarea. Motivul este: nu s-a inclus biblioteca math in procesul de linkeditare a executabilului. Pentru a o rezolva, trebuie indicat in reteta de build (fisierul CMakeLists.txt) adaugarea bibliotecii math. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
target_link_libraries(PROIECTUL_MEU m)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un exemplu de fisier CMakeLists.txt modificat se poate vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:LinkMathLibCmake.png|faracadru|upright=2]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8228</id>
		<title>Legarea bibliotecii math in cmake</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8228"/>
		<updated>2026-02-01T09:49:41Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dupa compilarea fiecarui modul c, urmeaza etapa de link-editare. Daca in timpul acelei etape linkerul nu gaseste o functie pe care o chemati, va afisa la consola o eroare de acest tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Scanning dependencies of target untitled2&lt;br /&gt;
[ 50%] Building C object CMakeFiles/untitled2.dir/main.c.o&lt;br /&gt;
[100%] Linking C executable untitled2&lt;br /&gt;
CMakeFiles/untitled2.dir/main.c.o: In function `main&amp;#039;:&lt;br /&gt;
/home/student/CLionProjects/untitled2/main.c:10: undefined reference to `sqrt&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acesta eroare se intampla asa cum se observa, nu la compilare (la consola se afiseaza Linking C executable ... si apoi eroarea &amp;quot;undefined referece to&amp;quot; respectiva functie =&amp;gt; la linkeditare apare eroarea. Motivul este: nu s-a inclus biblioteca math in procesul de linkeditare a executabilului. Pentru a o rezolva, trebuie indicat in reteta de build (fisierul CMakeLists.txt) adaugarea bibliotecii math. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
target_link_library(PROIECTUL_MEU m)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un exemplu de fisier CMakeLists.txt modificat se poate vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:LinkMathLibCmake.png|faracadru|upright=2]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8227</id>
		<title>Legarea bibliotecii math in cmake</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Legarea_bibliotecii_math_in_cmake&amp;diff=8227"/>
		<updated>2026-02-01T09:47:25Z</updated>

		<summary type="html">&lt;p&gt;Cbira: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dupa compilarea fiecarui modul c, urmeaza etapa de link-editare. Daca in timpul acelei etape linkerul nu gaseste o functie pe care o chemati, va afisa la consola o eroare de acest tip:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Scanning dependencies of target untitled2&lt;br /&gt;
[ 50%] Building C object CMakeFiles/untitled2.dir/main.c.o&lt;br /&gt;
[100%] Linking C executable untitled2&lt;br /&gt;
CMakeFiles/untitled2.dir/main.c.o: In function `main&amp;#039;:&lt;br /&gt;
/home/student/CLionProjects/untitled2/main.c:10: undefined reference to `sqrt&amp;#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acesta eroare se intampla asa cum se observa, nu la compilare (la consola se afiseaza Linking C executable ... si apoi eroarea &amp;quot;undefined referece to&amp;quot; respectiva functie =&amp;gt; la linkeditare da eroare. Eroarea de mai sus este datorata faptului ca nu s-a inclus biblioteca math in procesul de linkeditare a executabilului. Pentru a o rezolva, trebuie indicat in reteta de build (fisierul CMakeLists.txt) adaugarea bibliotecii math. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
target_link_library(PROIECTUL_MEU m)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un exemplu de fisier CMakeLists.txt modificat se poate vedea mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:LinkMathLibCmake.png|faracadru|upright=2]]&lt;/div&gt;</summary>
		<author><name>Cbira</name></author>
	</entry>
</feed>