Differences

This shows you the differences between two versions of the page.

Link to this comparison view

programare:laboratoare:suport_teoretic:tipuri-de-date-si-operatori [2025/10/10 14:37]
darius.neatu
programare:laboratoare:suport_teoretic:tipuri-de-date-si-operatori [2025/10/10 16:42] (current)
darius.neatu
Line 1: Line 1:
-===== Matrice. Operaţii cu matriceadunare, înmulţire. Reprezentarea în memorie. =====+===== PCLP Suport Teoretic pentru LaboratorTipuri de dateOperatori ​=====
  
-==== Obiective ===== 
  
-În urma parcurgerii acestui laborator studentul va fi capabil: 
-  * să declare matrice si orice fel de tablou multidimensional; ​ 
-  * sa initializeze aceste structuri, atat din declaratie, cat si prin instructiuni iterative; ​ 
-  * sa cunoasca regulile de reprezentare ale tablourilor in memorie si sa inteleaga modul in care compilatorul interpreteaza operatorii de indexare; ​ 
-  * sa cunoasca scheme comune de utilizare a acestor structuri; ​ 
-  * sa foloseasca practici recunoscute si recomandate pentru scrierea de cod sursa care implica lucrul cu matrice; 
-  * sa recunoasca si sa evite erorile comune de programare legate de aceste structuri 
  
 +==== Tipuri fundamentale de date ====
  
 +Tipurile de date reprezintă tipul de informație care poate fi stocat într-o variabilă. Un tip de data definește atât gama de valori pe care o poate lua o variabilă de un anume tip cât și operațiile care se pot efectua asupra ei. În continuare sunt prezentate tipurile fundamentale ale limbajului C, împreună cu o scurtă descriere a acestora:
 +  * ''​char''​ - reprezentat printr-un număr pe 8 biți (un byte). Poate fi echivalent fie cu ''​signed char'',​ fie cu ''​unsigned char''​. Vezi observația de mai jos cu privire la acest lucru. Este folosit în general pentru reprezentarea caracterelor ASCII.
 +  * ''​int''​ - stochează numere întregi. Lungimea sa (și implicit plaja de valori) este dependentă de compilator si sistemul de operare considerat. **În general**, pe Linux, ''​int''​ se reprezintă pe 32 de biți (deci 4 bytes). În acest caz, poate memora numere din intervalul [–2.147.483.648;​ 2.147.483.647].
 +  * ''​float''​ - reprezintă un număr real stocat în virgulă mobilă, în gama de valori 3.4E+/-38. În **general** respectă formatul [[https://​en.wikipedia.org/​wiki/​IEEE_floating_point|IEEE 754 single-precision]],​ ceea ce înseamnă că dimensiunea sa va fi 4 (octeți) și numărul va avea cel puțin 7 zecimale exacte.
 +  * ''​double''​ - reprezinta un număr real stocat în virgulă mobilă, în gama de valori 1.7E+/-308. În **general** respectă formatul [[https://​en.wikipedia.org/​wiki/​IEEE_floating_point|IEEE 754 double-precision]],​ ceea ce înseamnă că dimensiunea sa va fi 8 (octeți) și numărul va avea cel puțin 15 zecimale exacte.
  
-==== Noţiuni teoretice ==== 
  
-=== Matrice ===+Acestor tipuri fundamentale li se mai pot adăuga un număr de specificatori,​ după cum urmează: 
 +  * ''​short''​ - aplicabil doar pentru ''​int''​. Tipul rezultat are **cel puțin** 16 biți. 
 +  * ''​long''​ - aplicabil pentru ''​int''​ și ''​double''​. ''​long int''​ se garantează că are **cel puțin** 32 biți. Legat de ''​long double''​ se garantează doar că este mai mare sau egal ca dimensiune decât ''​double'',​ care la rândul lui este mai mare sau egal decât ''​float''​.
  
-Matricea ​este o colecţie omogenă şi bidimensională de elementeAcestea pot fi accesate prin intermediul a doi indicinumerotaţi,​ ca şi în cazul vectorilor, începand de la 0Declaraţia unei matrice ​este de forma:+și 
 +  * ''​signed''​ - aplicabil pentru ''​int''​ și ''​char''​. O variabilă declarată ''​int'' ​este implicit ''​signed''​. Cuvântul cheie există în acest caz doar pentru cazuri în care vrem să spunem acest lucru explicitAplicat pe ''​char''​ (=> ''​signed char''​)ne garantează faptul că acea variabilă va putea avea orice valoare din intervalul [-128; 127]. 
 +  * ''​unsigned''​ - precizează faptul că valoarea variabilei ​este pozitivă. Aplicabil doar tipurilor întregi.
  
-<code bash> +Cei 4 specificatori au fost împărțiți în 2 grupuri de specificatori complementari. Asta înseamnă că expresia ''​long signed int a;''​ este corectă. La fel este și ''​unsigned short int b;''​. Definiția ''​short long int c;''​ nu este însă corectă. De asemenea, **nu** oricare specificator din prima categorie cu unul din a doua se pot combina. De exemplu, ''​long signed char d;''​ și ''​long unsigned double e;''​ nu sunt corecte.
-<​tip_elemente>​ <​nume_matrice>​[<​dim_1>​][<​dim_2>​]; +
-</​code>​+
  
-De exemplu, avem: +<spoiler Tipul char
-<code c+**Observație!** 
-int mat[5][10];​ +În C există 3 "​tipuri de ''​char''":​ ''​char'',​ ''​signed char'',​ ''​unsigned char''​. Acest lucru este diferit față de ''​int'',​ spre exemplu, unde se garantează că ''​signed int''​ este **mereu** același tip ca ''​int''​. Pentru ''​char''​ acest lucru nu este adevărat: o variabilă declarată ''​char'',​ poate fi, în funcție de compilator/sistem de operare fie ''​signed char'',​ fie ''​unsigned char''​. Diferența este subtilă însă importantă atunci când vrem să scriem cod C **portabil**. Ca **best practice**, folosim: 
-</code> +  * ''​char''​ - atunci când vrem să stocăm un caracter ASCII. 
-<code c> +  * ''​signed char''​ - atunci când vrem să stocăm un întreg din intervalul ​[-128; 127]
-#define MAX_ELEM 100 +  * ''​unsigned char''​ - atunci când vrem să stocăm orice întreg din intervalul ​[0; 255].
-float a[MAX_ELEM][MAX_ELEM]+
-</​code>​+
  
-Numărul de elemente ale unei matrice va fi ''​dim_1*dim_2'',​ şi semnificaţia fiecărei dimensiuni este o chestiune ce ţine de logica programului. ​În matematicăprima dimensiune poate să însemne linia şi doua coloana pentru fiecare element, însa acest lucru nu este obligatoriu. Este necesar ​totuşi, pentru funcţionarea corectă a programului, să se respecte semnificaţiile alese pe întreg parcursul codului sursă.+**Observație!** 
 +În paragraful anterioracolo unde s-folosit sintagma //în general...//​ înseamnă că acel lucru nu este necesar ​adevărat atunci când compilăm codul cu compilatorul **X** (gcc, clang, MSVC, Intel, XL C, etc), pe sistemul de operare **Y** (Linux, Windows, SunOS, AIX, etc)  șpe arhitectura hardware **Z** (x86ARM, PowerPC, Sparc, etc). În unele cazuri vrem să scriem cod **portabil**deci nu vrem să facem prezumții cu privire la aceste lucruri. Pe parcurs o să devină clar de ce în **C** unele lucruri nu sunt exact specificate. 
 +</​spoiler>​
  
-=== Tablouri multidimensionale === 
  
-Vectorii şi matricele se pot extrapola la noţiunea generală de tablou ​cu mai multe dimensiuni, care se declară ​în modul următor:+Uneori ne dorim să folosim tipuri a căror dimensiune este exact specificată (ca în cazul lucrului ​cu struct-uri, care va fi discutat într-un laborator viitor). Pentru asta, putem folosi tipurile definite ​în headerul ''<​stdint.h>''​. ​
  
-<code bash> +Câteva exemple sunt următoarele:​ ''​int8_t'',​ ''​int16_t'',​ ''​int64_t'',​ ''​uint32_t''​. Pentru o listă completă consultați ​[[http://en.cppreference.com/w/​c/​types/​integer|documentația]] **oficială** (online) a limbajului.
-<​tip_elemente>​ <​nume_tablou>​[<​dim_1>​][<​dim_2>​]...[<​dim_n>​];​ +
-</code>+
  
-De exemplu: +<note warning
-<code c+**Atenție!** 
-int cube[3][3][3];​ +Nu abuzați de aceste tipuri. Ele au fost introduse în limbaj în special pentru a permite efectuarea operațiile pe biți într-un mod **portabil**. Dacă aveți nevoie de un contor pentru o instrucțiune ''​for'',​ cel mai probabil tipul pe care îl vreți este ''​int''​. 
-</code>+</note>
  
-Deşi, în cazul mai mult de 3 dimensiunitablourile pot să nu mai aibă sens concret ​sau fizicacestea pot fi deosebit ​de utile în multe situaţii. În acest laborator ne vom rezuma totuşi la tablouri bidimensionale.+Determinarea corectă a tipurilor de date care vor fi folosite este esențială pentru securitatea șbuna funcționare ​aplicațiilor pe care le scrieți. În cazul în care valoarea conținută de o variabilă depașește limitele impuse de tipul de date folositse produce așa-numit-ul over-flow care poate cauza erori aparent inexplicabile. (//Ca o anecdotă, în fiecare an (până acum trei sau patru ani)Bill Gates primea ​de la FISC o scrisoare prin care era somat să iși platească taxele, deoarece apărea in evidențele lor ca având datorii însemnate. Asta deoarece valoarea averii lui (mult peste 4.000.000.000$) producea un overflow ​în softul folosit de către FISC. În final situația a fost soluționată,​ introducând un câmp special pentru el în softul folosit. (A modifica softul peste tot ar fi introdus un plus de stocare nejustificat pentru fiecare din cei aproximativ 300.000.000 de cetațeni ai SUA.)// )
  
-=== Adunarea si înmulţirea matricelor ​===+==== Operatori ====
  
-== Suma matricelor ==+Operatorii limbajului C pot fi unari, binari sau ternari, fiecare având o precedenţă şi o asociativitate bine definite. Tabelul următor sintetizează operatorii limbajului C. Operatorii sunt prezentaţi în ordine descrescătoare a priorităţii.
  
-Fie $A \in {\mathbb R}^{m \times n}$, $B \in {\mathbb R}^{m \times n}$, atunci $(A+B\in {\mathbb R}^{m \times n}$, unde$(A+B)_{i,j} =  ​A_{i,j} B_{i,j}$+ ​Precedenţă  ​ ​Operator ​ ^  Descriere ​ ^  Asociativitate ​ ^ 
 +|  **1**  |  **[]** ​ | Indexare |  stanga-dreapta ​ | 
 +| ::: |  **. şi %%->​%%** ​ | Selecţie membru ​(prin structură, respectiv pointer) |  stânga-dreapta ​ | 
 +| ::: |  **++ şi %%--%%** ​ | Postincrementare/​postdecrementare |  stânga-dreapta ​ | 
 +|  **2**  |  **!**  | Negare logică |  dreapta-stânga ​ | 
 +| ::: |  **~**  | Complement faţă de 1 pe biţi |  dreapta-stânga ​ | 
 +| ::: |  **++ şi %%--%%** ​ | Preincrementare/​predecrementare |  dreapta-stânga ​ | 
 +| ::: |  **+ şi -**  | + şi - unari |  dreapta-stânga ​ | 
 +| ::: |  *****  | Dereferenţiere |  dreapta-stânga ​ | 
 +| ::: |  **&​** ​ | Operator //adresă// |  dreapta-stânga ​ | 
 +| ::: |  **(tip)**  | Conversie de **tip** |  dreapta-stânga ​ | 
 +::: |  **sizeof()**  | Mărimea în octeţ|  dreapta-stânga ​ | 
 +|  **3**  |  *****  | Înmulţire |  stânga-dreapta ​ | 
 +| ::: |  **\/​** ​ | Împărţire |  stânga-dreapta ​ | 
 +| ::: |  **%**  | Restul împărţirii |  stânga-dreapta ​ | 
 +|  **4**  |  **+ şi -**  | Adunare/​scădere |  stânga-dreapta ​ | 
 +|  **5**  |  **%%<<​%% si %%>>​%%** ​ | Deplasare stânga/​dreapta a biţilor |  stânga-dreapta ​ | 
 +|  **6**  |  **<​** ​ | Mai mic |  stânga-dreapta ​ | 
 +| ::: |  **%%<=%%**  | Mai mic sau egal |  stânga-dreapta ​ | 
 +| ::: |  **>​** ​ | Mai mare |  stânga-dreapta ​ | 
 +| ::: |  **>​=** ​ | Mai mare sau egal |  stânga-dreapta ​ | 
 +|  **7**  |  **==** ​ | Egal |  stânga-dreapta ​ | 
 +| ::: |  **!=** ​ | Diferit |  stânga-dreapta ​ | 
 +|  **8**  |  **&​** ​ | ŞI pe biţ|  stânga-dreapta ​ | 
 +|  **9**  |  **^**  | SAU-EXCLUSIV pe biţi |  stânga-dreapta ​ | 
 +|  **10** ​ |  **|**  | SAU pe biţi |  stânga-dreapta ​ | 
 +|  **11** ​ |  **&&​** ​ | ŞI logic |  stânga-dreapta ​ | 
 +|  **12** ​ |  **||** ​ | SAU logic |  stânga-dreapta ​ | 
 +|  **13** ​ |  **?:​** ​ | Operator condiţional |  dreapta-stânga ​ | 
 +|  **14** ​ |  **=**  | Atribuire |  dreapta-stânga ​ | 
 +| ::: |  **+= ş-=**  | Atribuire cu adunare/​scădere |  dreapta-stânga ​ | 
 +| ::: |  ***= şi /=**  | Atribuire cu multiplicare/​împărţire |  dreapta-stânga ​ | 
 +| ::: |  **%=** ​ | Atribuire cu modulo |  dreapta-stânga ​ | 
 +| ::: |  **&= si |=**  | Atribuire cu ŞI/SAU |  dreapta-stânga ​ | 
 +| ::: |  **^=** ​ | Atribuire cu SAU-EXCLUSIV |  dreapta-stânga ​ | 
 +| ::: |  **%%<<​= şi >>​=%%** ​ | Atribuire cu deplasare de biţi |  dreapta-stânga ​ | 
 +|  **15** ​ |  **,**  | Operator secvenţa |  stânga-dreapta ​ |
  
-{{:programare:​laboratoare:​sum.png|}}+Trebuie avută în vedere precedenţa operatorilor pentru obţinerea rezultatelor scontate. Dacă unele tipuri de precedenţă (cum ar fi cea a operatorilor artimetici) sunt evidente şi nu prezintă (aparent) probleme (şi datorită folosirii lor dese), altele pot duce la erori greu de găsit. De exemplu, următorul fragment de cod nu produce rezultatul dorit, deoarece:
  
-Exemplu:+<code c> 
 +if (flags & MASK == 0) { 
 +  ... 
 +
 +</​code>​
  
-$$ +se evaluează mai întai egalitatea care produce ca rezultat (pentru False, și pentru True) după care se aplică Și pe biți între flags și 1.
-  \Large +
-  \begin{bmatrix} +
-     1 & 3 \\  +
-     & 4 \\ +
-     5 & 8 +
-  \end{bmatrix} +
-+
-  \begin{bmatrix}  +
-    2 & 5 \\  +
-    1 & 2 \\  +
-    6 & 1 +
-  \end{bmatrix} +
-+
-  \begin{bmatrix} +
-    3 & 8 \\  +
-    ​& 6 \\  +
-    11 & 9 +
-  \end{bmatrix} +
-$$+
  
-== Înmulţirea matricelor ==+Pentru a obţine rezultatul dorit se vor folosi parantezele:​
  
-Fie $A \in {\mathbb R}^{m \times n}$, $B \in {\mathbb R}^{n \times p}$, atunci $(AB) \in {\mathbb R}^{m \times p}$, unde elementele $A.B$ sunt date de formula: +<code c> 
-$(AB)_{i,​j} ​\sum_{r=1}^n A_{i,r}B_{r,j}$+if ((flags & MASK) == 0) { 
 +  ... 
 +} 
 +</​code>​
  
 +acum mai întâi se va face ȘI pe biți între flags și MASK, după care se verifică egalitatea.
  
-{{:​programare:​laboratoare:​mul.png|}} Exemplul din stânga prezintă cum se calculează valorile (1,2) si (3,3) ale '''​AB'''​ daca '''​A''' ​este o matrice 3×2, si '''​B'''​ o matrice 2×3. Pentru calculul unui element din matrice se consideră o linie respectiv o coloană din fiecare matrice conform săgeţilor. Elementele ​din acestea sunt înmulţite câte 2 conform înmulţirii pe vectoriapoi suma produselor constituie elementul din matricea finală+O expresie ​este o secventă de operanzi și operatori (validă din punct de vedere al sintaxei limbajului C) care realizează una din funcțiile: calculul unei valoridesemnarea unui obiect (variabilă) sau funcţii sau generarea unui efect lateral.
  
-$$ +O altă greşeală frecventă este utilizarea greşită a operatorilor **=** şi **==**. Primul reprezintă atribuireal doilea comparaţie de egalitate. Apar deseori erori ca:
-  (\mathbf{AB})_{1,​2} ​\sum_{r=1}^2 a_{1,​r}b_{r,​2} ​a_{1,​1}b_{1,​2}+a_{1,​2}b_{2,​2} \\  +
-  (\mathbf{AB})_{3,​3} = \sum_{r=1}^2 a_{3,​r}b_{r,​3} = a_{3,​1}b_{1,​3}+a_{3,​2}b_{2,3} +
-$$+
  
-Exemplu:+<code c> 
 +if (a = 2) { 
 +  ... 
 +
 +</​code>​
  
-$$ +Compilatorul consideră condiţia corectă, deoarece este o expresie validă în limbajul C care face atribuire, care se evaluează mereu la o valoare nenulă.
-  \Large +
-   +
-  \begin{bmatrix} +
-     1 & 0 & 2 \\  +
-     -1 & 3 & 1 +
-  \end{bmatrix} +
-\cdot +
-  \begin{bmatrix}  +
-    3 & 1 \\  +
-    2 & 1 \\  +
-    1 & 0 +
-  \end{bmatrix} +
-+
-\begin{bmatrix} +
-   1 \times 3 + 0 \times 2 + 2 \times 1 & 1 \times 1 + 0 \times 1 + 2 \times 0 \\ +
-  -1 \times 3 + 3 \times 2 + 1 \times 1 & -1 \times 1 + 3 \times 1 + 1 \times 0  +
-\end{bmatrix} +
-+
-\begin{bmatrix} +
-    5 & 1 \\ +
-    4 & 2 +
-\end{bmatrix} +
-$$+
  
-=== Reprezentarea în memorie ​===+==== Funcții matematice ====
  
-Cunoaşterea reprezentării în memorie a tablourilor vă ajută să înţelegeţi mai bine cum se lucrează cu aceste tipuri de date şi să evitaţi atât erorile comune, cât şi pe cele mai subtile. Aşa cum se ştie, fiecare variabilă are asociata o anumită adresă în memorie şi ocupă o anumită lungime, măsurată în octeţi. Standardul C impune ca un tablou să fie memorat într-o zonă continuă de memorie, astfel ca pentru un tabloul de forma: ​''​T tab[dim1][dim2]...[dimn];''​ +Fișierul antet ''​math.h'' ​conține un set de funcții matematice des utilizate ​în programeCâteva dintre acestea sunt:
-dimensiunea ocupată în memorie va fi ''​sizeof(T)*dim1*dim2*...*dimn''​. Vom considera în continuare cazul particular al unui vector vect de lungime n, şi al unui element oarecare al acestuia, de pe pozitia i. +
-Atunci când întalneşte numele vect, compilatorul va intelege ''"​adresa ​în memorie de la care începe vectorul vect"''​Operatorul de indexare [] aplicat numelui vect instruieşte compilatorul să ''"​evalueze acel element de tipul T, care se află pe pozitia i în vectorul care începe de la adresa vect"''​. Acest lucru se poate exprima direct''"​evaluarea variabilei de tip T de la adresa vect + i * sizeof(T)"''​.+
  
-În ultima formulare observaţi ca nu mai intervine sub nici o formă dimensiunea vectorului dată la declarare. Aceea a fost necesară doar compilatoruluica sa ştie câtă memorie să aloce pentru reprezentarea acestuia. De asemeneaobservaţi că sunt permise indexari în afara spaţiului de memorie alocat, şi astfel programul va putea, din greşeala, accesa alte zone de memorie, lucru care poate avea repercursiuni grave. În cel mai bun caz programul nostru se va comporta foarte ciudat ​(erori în locuri total imprevizibile), şi în cel mai rău caz întreg ​sistemul va fi blocat ​(în cazul sistemelor care nu au implementate spaţii virtuale ​de memorie proprii fiecărei aplicaţii - platformele Windows NT si Linux).+^  Antet  ^  Descriere ​ ^ 
 +| //''​double asin(double arg);\\ double acos(double arg);''//​ | Calculează arcsinusul/​arccosinusul valorii **arg**; rezultatul este măsurat în radiani | 
 +| //''​double atan(double arg);\\ double atan2(double ydouble x);''//​ | Calculează arctangenta valorii **arg**respectiv a fracției y/x | 
 +| //''​double floor(double num);''//​ | Întoarce ​cel mai mare întreg mai mic sau egal cu **num** ​(partea întreagă inferioară
 +| //''​double ceil(double num);''//​ | Întoarce ​cel mai mic întreg ​mai mare sau egal cu num (partea întreagă superioară) | 
 +| //''​double sin(double arg);​\\ ​ double cos(double arg);​\\ ​ double tan(double arg);''//​ | Calculează sinusul/​cosinusul/​tangenta parametrului **arg**, considerată ​în radiani | 
 +| //''​double sinh(double arg);\\ double cosh(double arg);\\ double tanh(double arg);''//​ |Calculează sinusul/​cosinusul/​tangenta hiperbolică a parametrului **arg** | 
 +| //''​double exp(double arg);''//​ | Întoarce valoarea ''​e''<​sup>''​arg''</​sup>​ | 
 +| //''​double pow(double base, double exp);''//​ | Întoarce valoarea ''​base''<​sup>''​exp''</​sup>​ | 
 +| //''​double log(double num);''//​ | Calculează logaritmul natural (de bază **e**al valorii **num** | 
 +| //''​double log10(double num);''//​ | Calculează logaritmul în baza 10 al parametrului | 
 +| //''​double sqrt(double num);''//​ | Calculează radăcina pătrată a parametrului | 
 +| //''​double fmod(double x, double y);''//​ | Întoarce restul împarțirii lui **x** la **y** | 
 +| //''​double fabs(double arg);''//​ | Întoarce valoarea absolută a lui **arg** |
  
-Faptul că graniţa dintre vectori şi adrese ​de memorie ​este atât de fină în limbajul Csintaxa acestuia permite expresii ciudate, de forma:+=== Studiu de caz === 
 +<spoiler Măsurarea timpului ​de execuție a programelor>​ 
 + 
 +Uneori ​este utilă măsurarea timpului ​de execuție a unei anumite parți a unui program sau chiar a întregului program. În acest scop putem folosi funcția ''​clock()''​ din fișierul antet ''​time.h''​. Această funcție întoarce o aproximare a numărului de cicluri de ceas trecute de la pornirea programului. Pentru a obţine o valoare ​în secundeîmpărțim această valoare la constanta **CLOCKS_PER_SEC**. Funcţia are antetul:
  
 <code c> <code c>
-char a[100]; +clock_t clock(void);
-a[0] = 1; +
-3[a] = 5;+
 </​code>​ </​code>​
  
-Instrucţiunea din urmă înseamna pur şi simplu "​asignează 5 variabilei ​de tip char de la adresa 3 + a * sizeof(char) = 3 + a". Observaţi că aceasta este echivalentă cu a[3] = 5;+Următorul fragment este un exemplu ​de utilizare ​acestei funcții:
  
-De asemenea, un alt avantaj apare la definirea unui parametru al unei funcţii, de tip vector, caz în care nu este necesară precizarea dimensiunii acestuia: +<code c> 
-void sort(int[] vect, n);+#include <​stdio.h>​ 
 +#include <​time.h>​ 
 +  
 +  
 +clock_t t_startt_stop; 
 +float seconds; 
 +  
 +// Marcam momentul ​de inceput 
 +t_start = clock(); 
 +  
 +// Executam operatia pentru care masuram timpul de executie 
 +// [....] 
 +  
 +// Marcam momentul de sfarsit 
 +t_stop = clock(); 
 +  
 +seconds = ((float)(t_stop - t_start)) / CLOCKS_PER_SEC;​ 
 +  
 +printf("​Timp de executie: %.3f sec.\n", seconds); 
 +</​code>​
  
-<​note>​ +Următorul fragment este un exemplu ​de funcție care are ca scop oprirea programului ​pentru ​un anumit timp:
-Este de remarcat faptul că pentru **tablouri ​de dimensiuni m > 1**, este necesară precizarea **lungimilor ultimelor m - 1 dimensiuni**, ​pentru ​ca compilatorul să poată calcula adresa fiecărui element atunci când acesta este referit în program. +
-Mai multe detalii legate de reprezentarea tablourilor şi, în general, a datelor în memorie, vor fi date în laboratorul 8. +
-</​note>​+
  
-=== Exemple de programe === 
- 
-  * Declararea unei matrici unitate: 
 <code c> <code c>
-#define M 20 /* nr maxim de linii si de coloane */ +void wait(int seconds){ 
- +  ​clock_t endwait
-int main() { +  ​endwait = clock () + seconds * CLOCKS_PER_SEC ​
-  ​float unit[M][M]+  ​while (clock() < endwait) {}
-  ​int i,j,n; +
-     +
-  printf("​nr.linii/​coloane:​ "); +
-  ​scanf("​%d",​ &n); +
-  if (n > M+
-    return; +
-  } +
-     +
-  for (i = 0; i n; i++) { +
-    for (j = 0; j < n; j++) { +
-      if (i != j) { +
-        unit[i][j]=0;​ +
-      ​else { +
-        unit[i][j]=1;​ +
-      } +
-    } +
-  } +
-    +
-  return 0;+
 } }
 </​code>​ </​code>​
 +</​spoiler>​
  
-  * Citire/​scriere de matrice de reali:+<spoiler Generarea numerelor aleatoare>​ 
 + 
 +Valorile aleatoare (a căror valoare nu poate fi prezisă dinaintea rulării programului şi care diferă între 2 rulări) pot fi generate în C cu funcţia:
  
 <code c> <code c>
-int main() +int rand(void);
-  int nl, nc, i, j; +
-  float a[20][20];​ +
-   +
-  /* Citire de matrice */ +
-  printf("​nr.linii:​ "); +
-  scanf("​%d",​ &nl); +
-  printf("​nr.coloane:​ "); +
-  scanf("​%d",​ &nc); +
-     +
-  if (nl > 20 || nc > 20) { +
-    printf("​Eroare:​ dimensiuni > 20 \n"​);​ +
-    return ; +
-  } +
-     +
-  for (i = 0; i < nl; i++) { +
-    for (j = 0; j < nc; j++) { +
-      scanf("​%f",​ &​a[i][j]);​ +
-    } +
-  } +
-     +
-  /* Afisare matrice */ +
-  for (i = 0; i < nl; i++) { +
-    for (j = 0; j < nc; j++) { +
-      printf("​%f ",​a[i][j]);​ +
-    } +
-    printf ("​\n"​);​ +
-  } +
-   +
-  return 0; +
-}+
 </​code>​ </​code>​
  
-==== Erori comune ====+care face parte din antetul ''​stdlib.h''​. Această întoarce o valoare cuprinsă între 0 și **RAND_MAX** (valoare care este dependenta de librariile folosite, dar care se garantează a fi minim 32767). 
 + 
 +Numerele generate nu sunt cu adevărat aleatoare, ci pseudo-aleatoare;​ aceste numere sunt uniform distribuite pe orice interval, dar șirul de numere aleatoare generate este dependent de prima valoare, care trebuie aleasă de utilizator sau programator. Această valoare, numită **seed**, se selectează cu funcţia: 
 + 
 +<code c> 
 +void srand(unsigned int seed); 
 +</​code>​ 
 + 
 +Cea mai întalnită utilizare a funcției de inițializare presupune setarea unui **seed** egal cu valoarea ceasului sistemului de la pornirea programului,​ prin instrucțiunea:​ 
 + 
 +<code c> 
 +srand((unsigned)time(NULL));​  
 +rand(); //​generează valori random. 
 +</​code>​
  
-  * Inversarea indicilor pentru elementele unei matrice sau tablouE usor sa-l inversezi pe i cu j in expresia A[i][j] astfel ca trebuie sa fiti atenti cand scrieti astfel ​de codLuati in considerare si folosirea ​de nume mai sugestive pentru ​variabile. ​+Funcția ''​time()''​ din fişierul antet ''​time.h''​ întoarce numărul ​de secunde trecute de la ora 00:00, din data de 1 ianuarie 1970Funcția primește şi un parametru ​de tip pointer, care reprezintă adresa unei variabile ​în care se salvează valoarea returnată. Pentru laboratorul curent, parametrul va avea valoarea **NULL**.
  
-===== Referinţe ===== +</spoiler>
-   +
-  * [[http://​en.wikipedia.org/​wiki/​Matrix_multiplication | Wikipedia - Matrix Multiplication]]+
  
-  * [[http://​ocw.cs.pub.ro/​courses/​so/​laboratoare/​resurse/​gdb | GDB - Tutorial]]+==== Referinţe ====
  
-  * [[https://github.com/cs-pub-ro/ComputerProgramming/blob/master/Laboratories/Lab6/Lab6.pdf Cheatsheet matrici]]+  * [[https://en.wikipedia.org/wiki/​C_data_types|Wikipedia ​C data types]] 
 +  * [[http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B|Wikipedia - Operators in C and C++]] 
 +  * [[http://en.wikipedia.org/​wiki/​C_mathematical_functions|Wikipedia - C mathematical functions]]
  
programare/laboratoare/suport_teoretic/tipuri-de-date-si-operatori.txt · Last modified: 2025/10/10 16:42 by darius.neatu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0