of 93 /93
Programarea Calculatoarelor Versiune 0.32 Cristian Vicas , nov. 16, 2020

Programarea Calculatoarelor - utcluj.rousers.utcluj.ro/~visoft/teach/programareacalculatoarelor.pdfProgramarea Calculatoarelor, Versiune 0.32 1.2Desfas˘, urare 1.2.1Abstractizare

  • Author
    others

  • View
    54

  • Download
    0

Embed Size (px)

Text of Programarea Calculatoarelor -...

  • Programarea CalculatoarelorVersiune 0.32

    Cristian Vicas,

    nov. 16, 2020

  • Contents

    1 Introducere 11.1 Despre ce e vorba aici? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

    1.1.1 Ce este software-ul? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.2 Cum e alcătuit un calculator? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    1.2 Desfăs, urare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2.1 Abstractizare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2.2 Lean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2.3 CE vs CUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.4 Cheia succesului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    2 Iterat, ia 1 72.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Un program simplu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    2.2.1 Anatomia unui program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.3 Instruct,iuni de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    2.3.1 Instruct,iunea for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.3.2 Instruct,iunea if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    2.4 Instruct,iuni, expresii s, i funct,ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.4.1 Instruct,iunile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.4.2 Funct,iile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.4.3 Expresiile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    2.5 Memoria si variabilele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.5.1 Vizibilitatea unei variabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.5.2 Alte observat,ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.5.3 Init,ializarea variabilelor s, i constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

    2.6 Intrări s, i ies, iri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.6.1 Ies, irea în consola text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.6.2 Citirea de la tastatură . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

    2.7 Lean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.7.1 Abordarea standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.7.2 Abordarea când învăt,at,i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.7.3 Abordarea când stăpânit,i instrumentele . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

    3 Iterat, ia 2 213.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.2 Tipuri de memorie accesibile programului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

    3.2.1 Variabile globale fis, ierului curent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    i

  • 3.2.2 Variabile locale funct,iei/blocului curent . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.2.3 Accesarea memoriei Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.2.4 Declararea variabilelor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    3.3 Variabile (date) compuse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.3.1 Tablouri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.3.2 Structuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.3.3 S, iruri de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

    3.4 Pointeri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.4.1 Declararea pointerilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303.4.2 Operat,ii cu pointeri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303.4.3 Legătura între pointeri s, i tabele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313.4.4 Alocarea de memorie în zona heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

    3.5 Expresii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343.5.1 Operat,ii aritmetice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343.5.2 Operatorul de asignare sau atribuire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363.5.3 Operatori de comparat,ie s, i logici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373.5.4 Alt,i operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393.5.5 Priorităt,ile s, i asocierea operatorilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393.5.6 Supraîncărcarea operatorilor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    3.6 Funct,ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413.6.1 Apel prin referint, ă . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.6.2 Stiva . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453.6.3 Apel recursiv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

    3.7 Intrări/ies, iri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.7.1 Deschiderea unui fis, ier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.7.2 Accesul la nivel de caracter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473.7.3 Accesul la nivel de s, ir de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473.7.4 Accesul la nivel binar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.7.5 Redirectarea I/O standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

    4 Probleme propuse 494.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.2 Citire de text din fis, ier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.3 Parsare text dintr-un s, ir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.4 Liste de vectori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.5 Operat,ii cu liste de s, iruri de cuvinte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504.6 Tabele dinamince . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

    5 Iterat, ia 3 515.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2 Toolchain-ul de compilare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    5.2.1 Preprocesarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525.3 Programarea modulară . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

    5.3.1 Compilarea s, i Link-editarea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565.3.2 Modulele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

    5.4 Variabile statice s, i constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585.4.1 Modificatorul const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585.4.2 Modificatorul static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585.4.3 Modificatorul extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

    5.5 Lucrul cu date structurate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595.5.1 Array-uri de pointeri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595.5.2 Matrice în structură . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605.5.3 Matrici continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625.5.4 S, iruri de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

    ii

  • 5.5.5 Structuri recursive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645.5.6 Reuniuni de date s, i structuri pe bit,i . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

    5.6 Functii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.6.1 Recursivitatea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.6.2 Pointerii la funct,ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

    5.7 Strategii de programare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735.7.1 Optimizări s, i "mai optim" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735.7.2 Cod curat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    6 Limbajul s, i mediul Python 776.1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776.2 Elemente de sintaxă . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786.3 Structuri de date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

    6.3.1 S, ir de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796.3.2 Liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796.3.3 Tuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806.3.4 Dict,ionare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806.3.5 Funct,ii, clase, obiecte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

    6.4 Biblioteca matematică . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806.5 Setarea unui toolchain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

    7 Limbajul s, i mediul MATLAB 83

    8 Planificare curs 85

    9 Bibliografie 87

    iii

  • iv

  • CHAPTER 1

    Introducere

    1.1 Despre ce e vorba aici?

    Bine at,i venit la materia Programarea calculatoarelor!

    Toate dispozitivele electronice smart din jurul nostru sunt controlate de software. De la smartphone s, i smartwatchesla dispozitive integrate ce controlează motorul de la mas, ină.

    A, s, i să nu uităm, fac rachetele să aterizeze pe platforme mobile în mijlocul oceanului.1

    Pe scurt, software-ul pune în mis, care s, i dă viat, ă tuturor dispozitivelor lumii moderne. Foarte put,ine dispozitive suntconstruite strict din hardware.

    La această materie acumulăm nis, te cunos, tint,e elementare de cum să facem calculatorul să facă ceea ce vrem noi. Vomînvăt,a cum să folosim un limbaj de programare s, i cum să abordăm rezolvarea unei probleme de software.

    Cursul acesta presupune că NU avet,i cunos, tint,e prealabile de C. Nu vă speriat,i, dacă nu at,i făcut la liceu programare.Pentru cei care "s, tit,i" deja C++: Not,iunile predate merg dincolo de nivelul predat la liceu. Nu ignorat,i materia doardin cauză că at,i fost olimpici! S-ar putea să avet,i surprize neplăcute.

    1.1.1 Ce este software-ul?

    Procesorul (nucleul, "creierul" calculatorului) execută nis, te instruct,iuni aflate în memoria de lucru (RAM). Acesteinstruct,iuni sunt stricte, precise s, i deterministe. Ele sunt codate ca s, i un pattern (s, ablon, model) de bit,i, adică numerebinare: 00101001, 11100011 etc etc. Acest pattern de bit,i este recunoscut s, i executat de procesor. Pattern-ul de bit,ise numes, te cod mas, ină s, i alcătuies, te un program. Tot în memorie se păstrează, tot ca pattern-uri de bit,i, s, i valorinumerice utile (datele programului).

    În trecut, inginerii perforau acest pattern pe nis, te hârtii speciale s, i le încărcau în memorie. Între timp au mai evoluatun pic lucrurile. Folosim un compilator care să traducă un text (nu chiar ca s, i cel de aici) în cod mas, ină. Acel text,înt,eles de compilator se numes, te limbaj de programare.

    Aici vom învăt,a să programăm calculatorul în principal în limbajul C. Dacă avem timp, ne uităm s, i la alte două limbajefoarte utile în cariera de Inginer, Python s, i MATLAB.

    1 Canalul YouTube a celor de la SpaceX: https://www.youtube.com/watch?v=4jEz03Z8azc

    1

    https://www.youtube.com/watch?v=4jEz03Z8azc

  • Programarea Calculatoarelor, Versiune 0.32

    1.1.2 Cum e alcătuit un calculator?

    Elementele principale sunt:

    • Procesorul

    • Memoria de lucru (RAM)

    • Interfet,e cu perifericele (I/O)

    • Magistralele de comunicare (Bus-urle) de pe placa de baza

    Putem avea toate aceste componente puse pe o placă de bază, (ex ca la un desktop sau laptop) sau să le avem pe toateîntr-un singur circuit. As, a numitul System On a Chip (SoC). Raspberry Pi sau Arduino, sunt două platforme foartepopulare.

    Memoria cont,ine date s, i instruct,iuni s, i este accesată în principal de procesor prin intermediul magistralelor. Circuiteleperiferice pot s, i ele interact,iona cu procesorul citind valori din mediul extern (intrare) sau producând efecte (ies, ire,output). Cele mai cunoscute dispozitive de intrare (input): Tastatura si mouse-ul. Simplist, procesorul cites, te dacăavem apăsat vreun buton la tastatură s, i dacă da, îl memorează. Ca ies, ire, avem bineînt,eles ecranul. Simplificat, fiecareLED de pe ecran, este aprins s, i stins de procesor în funct,ie de anumite reguli.2

    În procesor găsim următoarele tipuri de instruct,iuni (din nou, foarte simplificat):

    • Citire din memorie (sau de la periferice)

    • Calcule aritmetice/matematice

    • Scriere în memorie (sau la periferice)

    • Control al fluxului de execut,ie (Care este următoarea instruct,iune care se va executa?)

    Cu aceste patru tipuri de instruct,iuni, putem să facem aproape orice. De la a aprinde un LED până la mas, ini autonome.

    Un exemplu de (pseudo)cod ce adună două numere s, i salvează rezultatul:

    Listing 1.1: Operat,ie de adunare scrisă într-un pseudo limbaj deasamblare.

    mov r0, [10340]mov r1, [10344]add r2, r0, r1mov [10348], r2

    Adică, ia cont,inutul de la adresa de memorie 10340 si 10344 s, i le stochează în regis, trii r0 s, i r1. Adună s, i păstreazărezultatul în r2. Apoi, scrie rezultatul la adresa 10348. Simplu? Dar laborios. Pănă la urmă nu face altceva decâtechivalentul matematic al lui c = a + b unde a s, i b sunt cunoscute.

    Pentru a abstractiza s, i us, ura lucrul cu procesorul, s-au inventat limbajele de programare.

    Limbajul C este suficient de flexibil si portabil să funct,ioneze (aproape) identic pe multe platforme s, i sisteme deoperare.

    2 În realitate procesorul nu interoghează fiecare periferic s, i nici nu controlează constant fiecare LED din ecran. La Arhitectura Calculatoarelorvet,i învăt,a mult mai în detaliu despre întreruperi, DMA, buffer-e, controller-e s, i alte concepte. DAR pentru simplificare, deocamdată, acceptat,iprezentarea de mai înainte.

    2 Chapter 1. Introducere

  • Programarea Calculatoarelor, Versiune 0.32

    1.2 Desfăs, urare

    1.2.1 Abstractizare

    Vrem să mergem într-o excursie, cu scopul de a vizita un oras, nou. Dintr-o altă t,ară. Presupunem că nu este 2020 s, ică anii următori sunt mai veseli.

    Am fixat destinat,ia, am fixat s, i scopul vizitei, acum mai trebuie să organizăm. Cu ce începem? Putem lucra latransportul până la destinat,ie, cazare în oras, ul dorit, actele s, i permisele necesare, lista de necesităt,i, bagaje, etc.

    SAU

    Putem planifica în detaliu ce vom îmbrăca în fiecare zi (încă nu s, tim cât stăm), ce vom servi la micul dejun (undestăm?) s, i la un moment dat să ajungem s, i la transport sau cazare.

    Evident, abordarea init,ială are mai multe s, anse de succes. Oare este posibil să ne deplasăm acolo? Ce acte trebuie?Putem începe apoi cu o căutare după un mijloc de transprt. Am găsit ceva decent, putem căuta cazare în intervaluldorit. Poate că, cazarea va impune nis, te restrict,ii mai puternice (ex. trebuie stat o săptămână întreagă). Putem avansas, i rezerva cazarea, după care să avansăm s, i să rezervăm transportul.

    Acum că linile "mari" ale călătoriei sunt fixate putem adăuga detalii. Cum mergem până la aeroport/gară? Cummergem de la aeroportul destinat,ie la cazare? Oare cum voi fi îmbrăcat?

    Mai sus am prezentat o descompunere a problemei de sus în jos. La fiecare etapă am concretizat anumite elemente (egtransportul) pe când altele au rămas abstracte (voi fi îmbrăcat cumva s, i voi avea bagaje)

    Capacitatea de a rat,iona abstract cu diverse concepte este foarte importantă pentru un Inginer.

    1.2.2 Lean

    În trecut, o sarcină mare, se diviza în o serie de etape succesive:

    • Specificarea cerint,elor problemei

    • Analiza în detaliu a cerint,elor

    • Proiectarea solut,iei

    • Executarea, implementarea proiectului

    • Testarea

    • Operat,ionalizarea s, i livrarea la client.

    Această metodologie s-a dovedit utilă în anumite cazuri de nis, ă, dar, în IT, este fatală. De obicei este foarte beneifcăpentru manageri, consultant,i, subcontractant,i dar în nici un caz benefică pentru clientul final sau echipa de inginericare realizează sistemul.

    Apocrific până s, i Winston Royce, presupusul autor al metodologiei3 a insistat mult timp asupra gres, elii făcute demanagement. Prea târziu, banii curgeau, proiectele se întârzâiau, toată lumea care avea putere de decizie, era fericită!Mai put,in clientul.

    În acest curs vom folosi abordarea lean. Sau iterativ. Vom urmări un obiectiv s, i vom ajunge la obiectiv facând câtevaiterat,ii. Fiecare iterat,ie va avea o finalitate, avansând (sau rezolvând) un element cheie al problemei s, i în acelas, i timprafinând solut,ia anterioară. Această abordare (numită Lean) s-a dovedit deosebit de eficientă în realizarea sistemelortehnice s, i comperciale complexe.

    3 Articolul Managing the development of large software systems poate fi găsit deocamdată aici: http://www-scf.usc.edu/~csci201/lectures/Lecture11/royce1970.pdf

    1.2. Desfăs, urare 3

    http://www-scf.usc.edu/~csci201/lectures/Lecture11/royce1970.pdfhttp://www-scf.usc.edu/~csci201/lectures/Lecture11/royce1970.pdf

  • Programarea Calculatoarelor, Versiune 0.32

    Metodologia lean se regăses, te în machine learning ("Artificial Intelligence"), în business s, i în tot ceea ce înseamnăindustria software de azi (La software lucrează împreuna cu metodologia agile).

    Vom învăt,a C-ul iterativ, prima iterat,ie vă va da rapid cunos, tint,e elementare despre majoritatea elementelor.Următoarele, vor aprofunda not,iunile s, i vă vor învăt,a noi s, i noi instrumente din ce în ce mai complexe.

    Problemele le vom rezolva tot iterativ. Scriem un cod simplu, care poate rezolvă un subpunct mai simplu, compilăm,executăm, observăm rezultatul. Apoi, daca totul este ok, trecem la următorul subpunct. Scriem cod care credemcă rezolvă subpunctul, compilăm, rulăm s, i repetăm dacă nu obt,inem rezultatul dorit. În următoarele iterat,ii putemde exemplu rafina cele două subpuncte s, i rezolva alte cerint,e (exemplu, elegant,a codului). De obicei regula este caiterat,iile să fie cât mai scurte.

    Avantajele acestei abordări este că la finalul fiecărei iterat,ii avet,i o solut,ie part,ială a problemei. Acest lucru este foarteutil in business (se poate livra ceva clientului) dar s, i la examen! Dacă se termină timpul înainte de a rezolva toatăproblema, avet,i nis, te subpuncte rezolvate!

    De obicei, în cadrul iterat,iei avem cele câteva faze de identificare a cerint,elor, proiectare, implementare s, i testare. Darele se axează strict pe subproblema pe care o avem ca t,intă în iterat,ia curentă.

    Atent,ie, abordarea top-down s, i lean sunt COMPATIBILE! Abstractizarea ne permite să alegem o subproblemă (ex. neconcentrăm pe cazarea la destinat,ie) în timp ce alte probleme sunt abstractizate (s, tim că putem duce bagaje s, i că existăposibilităt,i de transport)

    Abordarea iterativă ne permite să avansăm cu rezolvarea problemei în timp ce există mai multe constrângeri ceinteract,ionează. (ex cazarea depinde de transport iar datele transportului depind de cazare).

    Memoria umană are capacitate limitată. Este greu să analizezi 500 de pagini de cerint,e. Specificat,iile unui proiect potfi incomplete s, i vagi. Mai mult, de obicei se s, i schimbă pe parcursul proiectului. Toate aceste limitări sunt adresatefrumos s, i elegant de abordarea lean

    1.2.3 CE vs CUM

    Când abordăm o problemă nouă există câteva întrebări.

    CE:

    • Ce trebuie să rezolvăm?

    • Ce trebuie să livrăm clientului?

    • Ce constrângeri avem?

    • Ce e foarte important? La ce nu trebuie să dăm atent,ie?

    CUM:

    • Cum să implementez solut,ia?

    • Cum să aprind LED-u?

    • Cum să citesc de la tastatura?

    Întrebările de tip CE sunt întrebări de nivel înalt care ne ajută să descompunem problema în bucăt,i mai mici.Odată descompusă, putem trece la CUM. Aceste întrebări ne ajută să implementăm cod care rezolvă fiecare bucatădescompusă.

    Partea de limbaj C a cursului se axează pe întrebări de tip CUM. Mare atent,ie, din când în când abordăm si CE-u. Unprogramator mediocru are partea de implementare foarte bine pusă la punct (s, tie rapid să răspundă cu solut,ia potrivităla întrebările de tip CUM). Un Inginer bun, stăpânes, te si CE-u. Din păcate, arta de a pune întrebări bune se câs, tigăodată cu experient,a.

    4 Chapter 1. Introducere

  • Programarea Calculatoarelor, Versiune 0.32

    Evident există o ierarhie aici, ca s, i la abstractizare. De exemplu: Trebuie să semnalizez un pericol. CUM fac asta?Aprinzănd s, i stingând periodic un bec. CE instrumente sunt cele mai potrivite? Ce constrângeri am? (Ex. autonomie,mediu agresiv, praf, umezeală, etc) CUM aprind un LED? CUM sting LED-ul? etc etc.

    Presupunem că at,i rezolvat problema de mai sus. Acum trebuie să realizat,i o mas, inărie care efectuează o operat,iepericuloasă s, i trebuie să semnalizat,i acest lucru (CE-ul).

    Cum o facet,i? Cu metoda de mai sus. Odată ce at,i ajuns la acest CE (trebuie să semnalizez) vă putet,i opri cudescompunerea pentru că avet,i solut,ia. Acest concept se numes, te abstractizare. Abstractizăm operat,ia de "avertizare"pentru că este bine cunoscută.

    La fel s, i la programare, pe măsură ce învăt,at,i concepte, le grupăm în entităt,i abstracte pe care le vom folosi mereu.

    1.2.4 Cheia succesului

    Un student bun, în urma acestui curs va stăpâni foarte bine instrumentele limbajului de programare s, i va fi capabilsă descompună o problemă complexă în bucăt,i rezolvabile. Prima parte (cunoas, terea instrumentelor) vine odată cupractica. Partea a doua, (abilităt,ile de rezolvare a problemelor) vine cu s, i mai multă practică.

    Nu vă lăsat,i păcălit,i glumele, cu diverse cantităt,i de sare, prezente aici. Materialul didactic este dens. Fiecare paragrfeste o definit,ie, descrie o proprietate sau arată o observat,ie importantă. Multe concepte odată enunt,ate se presupuncunoscute s, i înt, elese.

    Munca alocată pentru această specializare s, i efortul depus de voi, pentru a vă însus, i not,iunile, depăs, es, te timpul fizicalocat în cadrul orarului (în persoană sau online). Vă încurajez să muncit,i s, i să studiat,i în echipe. Să colaborat,i atuncicând învăt,at,i. Folosit,i din plin mijloacele de comunicare avute la dispozit,ie atunci când avet,i dificultăt,i. Dar atent,ie,colaborarea la evaluări este fraudă s, i se pedepses, te sever.

    Vă recomand să facet,i pauză când învăt,at,i. Concentrat,i-vă 20-30 de minute după care 5-10 minute pauză. Reulat,i(mai ales materialul video) până înt,eleget,i s, i experimentat,i cu codul s, i conceptele învăt,ate aici.

    Când dat,i de greu, când "nu vă iese ceva" folosit,i regula de 15 minute:5 Încercat,i să rezolvat,i singuri problema pentru15 minute (folosind documentat,ie, curs, google, etc) s, i dacă nu reus, it,i, escaladat,i. Ceret,i ajutor de la colegi, asistent,i,profesori.

    Orice at,i face, NU ÎNVĂT, AT, I PE DE ROST!

    Romengleza este din păcate din ce în ce mai prezentă în lumea IT-ului as, a că, get used to it!

    Important: Materialul video atas, at cursului este adit,ional materialului scris. În materialul video conceptele suntexplicate mai pe larg. Deocamdată doar câteva arii sunt acoperite. Baza s, i referint,a după care învăt,at,i s, i suntet,ievaluat,i rămâne suportul de curs s, i îndrumătorul de laborator.

    5 https://twitter.com/math_rachel/status/764931533383749632

    1.2. Desfăs, urare 5

    https://twitter.com/math_rachel/status/764931533383749632

  • Programarea Calculatoarelor, Versiune 0.32

    6 Chapter 1. Introducere

  • CHAPTER 2

    Iterat, ia 1

    2.1 Introducere

    În iterat,ia curentă vet,i învăt,a să compunet,i un program simplu. Vom merge orizontal, adică vom atinge not,iuni multe,fără a intra în detalii. Multe concepte le vom abstractiza.

    Recaptiulând put,in. S, tim că procesorul ia instruct,iuni din memorie s, i le execută una după cealaltă (secvent,ial). Tot înmemorie se pot stoca s, i diverse valori numerice, utile nouă.

    Instruct,iunile în cod mas, ină nu sunt foarte us, or de citit sau de scris. Folosim un limbaj de programare, limbaj din careun compilator va crea acest cod mas, ină executabil.

    În introducere am văzut un exemplu de "cod mas, ină"1 unde procesorul execută secvent,ial fiecare instruct,iune.Limbajul C este parte din paradigma programării imperative. În aceste limbaje îi spun procesorului pas cu pas cesă execute. (C, C++, Java, Python, Matlab, Pascal ar fi câteva exemple). Din paradigma imperativă, procedurală sedesprinde programarea orientată pe obiect, POO (C++, Java, Python).

    Mai există s, i alte paradigme, programarea funct,ională fiind utilă mai ales în sisteme distribuite (Scala, F#, Elixirfiind câteva limbaje des folosite). Programarea logică este mai put,in folosită în industrie, dar are anumite observat,iiteoretice vitale în procesarea paralelă de performant, ă înaltă (High Performance Computing). Fiecare paradigmă areavantajele ei, as, a că să nu vă mire prezent,a elementelor de programare funct,ională în limbaje "imperative" ca Java,Javascript sau Python. Sub nici o formă nu trebuie să ignorat,i aceste paradigme!

    1 De fapt ce am arătat în introducere este tot un text în limbaj de asamblare, pe care un compilator îl va traduce în cifre. Dar la ora actuală numai există mult,i ingineri care să înt,eleagă sau să scrie direct în cod mas, ină. Probabil Jeff Dean (Căutat,i: "Jeff Dean facts")

    7

  • Programarea Calculatoarelor, Versiune 0.32

    2.2 Un program simplu

    Primul program în cam orice limbaj de programare este celebrul "Hello world!". Ce fac aceste tipuri de programe? Deobicei afis, ează un mesaj pe ecran. Sau fac un LED sa clipească3. Scopul lor este de a demonstra cea mai mica unitatefunct,ională a unui limbaj de programare sau a unei tehnologii.

    Listing 2.1: "Hello world!" în C

    #include int main(){

    printf("Hello World!");return 0;

    }

    Acum s, tim cum să afis, ăm un mesaj pe ecran. La laborator, vet,i învăt,a despre cum să compilat,i acest program scurt.

    Oare cum putem modifica mesajul afis, at? Oare ce putem modifica, din textul de mai sus, fără să modificămfunct,ionalitatea? Dar fără să avem erori de compilare?

    Încercat,i! Modificat,i bucăt,i din cod s, i vedet,i ce se întâmplă!

    2.2.1 Anatomia unui program

    Partea cea mai importantă s, i care produce modificări vizibile este printf("Hello World!");. Mai mult, dacămodific textul dintre ghilimele, se modifică s, i mesajul afis, at pe ecran. Evident!

    Cu except,ia spat,iilor albe, orice modificare la cod va duce la o eroare de compilare. Modificarea mesajului dintreghilimele va duce la modificarea mesajului pe ecran.

    În acest moment avem un instrument! Putem afis, a ceva pe ecran!

    Fiecare linie din program face ceva anume. Pe scurt:

    • #include îi spune compilatorului că avem nevoie să lucrăm cu I/O (input/output)

    • int void main() s, i acoladele { respectiv } fac parte din limbaj

    • printf("mesaj"); afis, ează mesajul pe ecran!

    • return 0 spune sistemului de operare că totul s-a executat cum trebuie s, i nu au fost erori. Încercat,i să returnat,ialtceva.

    • Comanda de afis, are este înconjurată de { respectiv }. Aceste perechi de acolade definesc un bloc de instruct, iuni

    Simplu? Deocamdata, da! Vom vedea mai încolo că ceea ce denumim noi compilator e de fapt un lant, de instrumente.Dar, abstractizăm întreg lant,ul (numit toolchain) sub denumirea simplă de compilator.

    Atent,ie, am introdus conceptul de bloc de instruct, iuni.3 https://www.arduino.cc/en/Tutorial-0007/BlinkingLED

    8 Chapter 2. Iterat, ia 1

    https://www.arduino.cc/en/Tutorial-0007/BlinkingLED

  • Programarea Calculatoarelor, Versiune 0.32

    2.3 Instruct, iuni de control

    2.3.1 Instruct, iunea for

    Problemă: Vreau să afis, ez primele numere pare non negative mai mici ca 10.

    Deja avem câteva instrumente! Un pic de inventar:

    • Compilatorul, ia un fis, ier text s, i îl convertes, te în cod mas, ină executabil

    • Instruct,iuni în limbajul C, (bucăt,i de text) cu care pot face calculatorul să afis, eze un mesaj pe ecran!

    Oare putet,i rezolva problema? Încercat,i! Iterativ! Mai întâi o cifră, apoi compilat,i. Apoi a 2-a cifră pară, compilat,i.Apoi toate! A fost greu? Dar oare se poate mai elegant? Observat,i codul de mai jos:

    Listing 2.2: Instruct,iunea for

    1 #include 2 int main()3 {4 for(int i = 0; i < 10; i = i + 2){5 printf("%d ", i);6 }7 return 0;8 }

    Hmm, parcă solut,ia în care modificam doar linia cu printf arăta mai bine s, i mai simplu! Oare ce avantaje areaceastă solut,ie?

    Începem să vedem câteva elemente care se suprapun cu cerint,ele problemei. Avem instruct,iunea de afis, are pe ecran,avem cifra 10, avem o operat,ie de incrementare din doi în doi, avem o operat,ie de setare la zero.

    Descris în cuvinte, am dat aceste instruct,iuni procesorului:

    • Rezervă o zonă de memorie s, i denumes, te-o i. Pune acolo numărul 0 int i = 0

    • Afis, ează pe ecran ceea ce se află în zona de memorie i: printf("%d ", i)

    • Adaugă la valoarea din zona de memorie i, numărul 2. Scrie rezultatul înapoi la i. i = i + 2

    • Repetă, cât timp la locat,ia i, valoarea este mai mică cu 10. i < 10

    Din nou, t,inet,i cont de abstractizare! Volumul de instruct,iuni în cod mas, ină este mult mai mare decât ce am scris noi.Din fericire NU avem treabă cu codul mas, ină. Deasemenea, construct,ia din linia 4 s-ar putea să vă sperie un pic. Ovom "sparge" în unităt,i mai mici imediat s, i vom vedea care părt,i pot fi modificate ca să ne servească nouă.

    În codul de mai sus am introdus discret s, i lucrul cu memoria. S, tim că principala sarcină a procesorului este să"socotească" cu datele stocate în memorie. Cu ajutorul variabilei i, abstractizăm conceptul de memorie s, i operat,iilecare se fac cu memoria.

    Bun, haidet,i să vedem dacă at,i căpătat intuit,ie despre cum funct,ionează for-ul. Modificat,i codul de mai sus să afis, ezenumerele pare mai mici de 20. Mai mici de 200!

    Ati reus, it? Cât de mare a fost schimbarea? Dar dacă rămâneam la solut,ia anterioară?

    Am scris mai mult cod, cu instruct,iuni noi s, i complicate dar am câs, tigat multă flexibilitate!

    Instruct,iunea for permite controlul execut,iei programului. Instruct,iunea determină executarea repetată a ceea ce seaflă în interiorul acoladelor imediat următoare (blocul de instruct,iuni).

    În interiorul instruct,iunii găsim nis, te operat,ii. Acestea controlează de câte ori se execută blocul.

    Să ne mai uităm odată la instuct,iunea for:

    2.3. Instruct, iuni de control 9

  • Programarea Calculatoarelor, Versiune 0.32

    for( A ; B ; C ) instructiune

    A, B s, i C sunt expresii. (Nu intrăm încă în definit,ia expresiei, gândit,i-vă ca la o expresie matematică)

    Expresia A va fi executată înainte de a intra în buclă. Ea are rolul de a init,ializa ciclul for.

    Expresia B este condit,ia de continuare. Ciclul for se va executa cât timp această expresie este adevărată. În limbajulC, o expresie este adevărată, True, dacă are valoare diferită de zero. Atent,ie, prima evaluare a expresiei se face înaintede a intra in ciclu. Asta înseamnă că sunt cazuri în care ciclul for nu se va executa deloc. Din cauză că schimbareavalorii lui B duce la terminarea ciclului, i se mai zice lui B s, i condit,ia de terminare.

    Dacă expresia B este adevărată (True) se va executa instruct,iunea (sau blocul de instruct, iuni) instructiune.

    Expresia C este apelată de fiecare dată după ce s-a executat un pas al ciclului for. Este numită s, i expresia dereinit,ializare. Atent,ie, la final, se va executa ultima iterat,ie a ciclului for, se va evalua C s, i apoi se va evalua B.După care, programul continuă cu următoarea instruct,iune de după for.

    Întrebare: Ce valoare are memorată variabila i după ce se iese din ciclul for? Nu vă dat,i seama după regulile de maisus? Nu e nimic! Adăugt,i o instruct,iune de afis, are, după ies, ira din ciclul for. În funct,ie de compilator, s-ar putea să vădea erori cum că identificatorul i nu este declarat.

    Modificăm un pic codul:

    #include void main(){

    int i;for(i = 0; i < 10; i = i + 2){printf("%d ", i);

    }printf("Dupa for, i = %d ", i);

    }

    Vedem că variabila i cont,ine valoarea 10. Explicabil, după ce se execută afis, area cu valoarea 8, bucla for va executaexpresia C, care va face ca i să ia valoarea 10. Apoi, înainte de a re-intra în ciclu se verifică B. Aceasta va fi falsăpentru că în acest pas, i NU este strict mai mic decăt 10. Este egal cu 10.

    Vom reveni la eroarea care a apărut când textul int i era prezent în interiorul instruct,iunii for. T, ine de vizibilitateavariabilelor în interiorul codului s, i de diverse variat,ii ale implementării compilatoarelor.

    2.3.2 Instruct, iunea if

    Am rezolvat problema anterioară apelând la cunos, tint,ele noastre de matematică. S, tim că primul număr par este 0, s, timcă ele urmează o progresie aritmetică cu pasul 2. As, a că generarea lor, matematic, a fost banal.

    Ce ne facem însă dacă, nu putem da o solut,ie matematică? Dacă de exemplu, trebuie să afis, ăm rădăcinile unei ecuat,iicu sinus, logaritm, exponent,iale, x ridicat la puteri? Presupunând doar că acceptă undeva, o rădăcină întreagă înintervalul căutat. S, i că vrem să găsim o solut,ie algoritmică la această problemă.

    CE trebuie să facem? Iterăm fiecare valoare întreagă posibilă pe interval, s, i verificăm funct,ia noastră grea. Afis, ămdoar când rezultatul este zero. Simplu? Dacă e să aprofundăm problema, s, tim CUM să facem iterat,ia, s, tim CUMsă afis, ăm valoarea pe ecran, ce instrument nu avem încă este acela în care controlăm fluxul de execut,ie al codului înfunct,ie de o condit,ie. Aici vine instruct,iunea if.

    Repetăm problema cu numerele pare s, i nu implementăm funct,ii matematice grele, deocamdată. Însă, rescriem, ca săfolosim instruct,iunea if.

    CE trebuie să facem? Trebuie să parcurgem toate numerele întregi de la 0 la 10 s, i pentru fiecare număr trebuie sădecidem dacă numărul este par sau nu. Dacă este par, îl afis, ăm.

    10 Chapter 2. Iterat, ia 1

  • Programarea Calculatoarelor, Versiune 0.32

    Matematic, verificarea parităt,ii se face cu modulo. In limbajul C, operatorul modulo este %. Da, l-am mai văzut îninterior la printf. Acolo are cu totul alt rol. Din păcate sunt multe astfel de elemente în limbajul C. Stat,i să ajungemla paranteze () sau la *. Operatorul * pică cei mai mult,i student,i la examen!

    12 modulo 2 este echivalent cu 12 % 2 în C. Rezultatul este 0. Adică, restul împărt,irii lui 12 cu 2 este 0. Adică12 este număr par. Bingo! Am rezolvat o parte din problema! Ne oprim aici? NU!

    Abordăm iterativ problema, as, a că vă recomand să modificat,i codul astfel:

    • Facet,i ca valoarea lui i să meargă de la 0 la 10 din 1 în 1. Compilat,i, rulat,i, corectat,i dacă sunt gres, eli.

    • Afis, at,i valoarea lui i s, i valoarea lui i % 2. Comanda printf("%d %d ", i, i % 2); ar trebui săfunct,ioneze.

    Vedem că pentru numerele pare, i%2 este zero.

    Acum putem itera din nou s, i face codul mai elegant. Introducem formal instruct,iunea if :

    if( condit, ie ){

    cod A

    }else{

    cod F

    }

    Dacă condit, ie se evaluează la o valoare diferită de zero, se va executa cod A. Dacă se evaluează ca fals, se va executacod F. Asta înseamnă că bucata cod A se va executa doar când condit,ia este adevărată. Partea cu else poate sălipsească.

    Convent,ia din limbajul C, este că, dacă o zonă de memorie cont,ine doar 0, variabila respectivă se consideră a aveavaloarea de adevăr, Fals. Dacă există un pattern diferit de zero, valoarea de adevăr se consideră a fi Adevărat.

    Mai introducem o expresie. Dacă vreau să aflu că două variabile sunt identice, folosesc operatorul ==. Expresia a ==b va fi diferită de zero (Adevărată) dacă în zona de memorie a lui a s, i b se află acelas, i pattern de bit,i. (Observat,ievitală pentru a înt,ege mai încolo operat,iile cu pointeri. Mai citit,i odată textul, observând expresia acelas, i pattern debit,i).

    Acum putem trece la a răspunde întrebărilor CUM. Cum verific dacă un număr este par? i % 2 == 0 CUMcontrolez afis, area, astfel încât să se afis, eze doar numerele pare? Cu if.

    Punet,i pauză s, i încercat,i să rezolvat,i problema singuri.

    Mai jos, o solut,ie posibilă.

    Listing 2.3: Numere pare, cu if

    #include void main(){

    int i;for(i = 0; i < 10; i = i + 1){if (i % 2 == 0){

    printf("%d ", i);}

    }}

    O gres, eală frecventă care se face este aceea de a uita un = în expresia de comparat,ie. Adică în loc de a == b săscriem a = b. Dezastru total. Valoarea expresiei a = b este valoarea lui b. As, a că dacă vrem să verificăm dacăi este 5, scriind gres, it if ( i = 5), partea cod A va fi executată tot timpul! Pentru că valoarea 5 este adevărată,conform convent,iei din limbajul C.

    2.3. Instruct, iuni de control 11

  • Programarea Calculatoarelor, Versiune 0.32

    2.4 Instruct, iuni, expresii s, i funct, ii

    Limbajul C este imperativ, fiecare instruct,iune se execută secvent,ial. Cu instruct,iunile de control putem alege care vafi blocul următor care va fi executat. Dar în interiorul unui bloc, instruct,iunile se execută secvent,ial.

    Am văzut pe scurt câteva elemente de limbaj, acum le dăm o definit,ie mai riguroasă.

    În limbajul C, o instruct,iune este de obicei terminată cu caracterul ;. Avem mai multe tipuri de instruct,iuni, în funct,iede ce avem înainte de acest ;.

    2.4.1 Instruct, iunile

    Comentariul. Putem scrie orice text, dacă la începutul liniei punem două slash-uri //. Sau putem înconjura textuldorit de perechea /* */ (poate fi în interiorul unui cod valid sau se poate întinde pe mai multe linii)

    Instruct, iunea vidă unde avem doar un ;.

    Instruct, iunea normală: Poate fi un apel de funct,ie (vom vedea imediat), un exemplu bun ar fi linia cu printf. Totaici intră s, i instruct,iunea formată dintr-o expresie urmată de ;.

    Declarat, iile de variabile le vom aprofunda la variabile. Exemplu, int i;. Observat,i ; de la sfârs, it.

    Avem apoi instruct, iuni de control ale mersului programului, am văzut deja for s, i if - else. Mai sunt, while,do - while, case - switch, continue, break, etc. Majoritatea le vom vedea la laborator, ele fiind doarvariat,ii ale celor două instruct,iuni de bază, if s, i for.

    Blocul de instruct, iuni este o secvent, ă de instruct,iuni prinsă între acolade {}. Atent,ie, din punct de vedere al C-uluiun bloc de instruct,iuni este văzut ca o singură instruct,iune. Asta înseamnă că peste tot unde este legal să apară oinstruct,iune, poate apărea un bloc de instruct,iuni. S, i de regula, s, i reciproc:

    int i;for(i = 0; i < 10; i = i + 1)

    printf("%d ", i);printf("\nLa iesire din ciclu: %d ", i);

    Foarte important, putem avea blocuri îmbricate. Am văzut la Cod 2.3 trei niveluri de îmbricare.

    Instruct,iunile se pot grupa în funct,ii. Funct,iile pot accepta parametri s, i pot returna valori, cam la fel ca o funct,iematematică. Fără să s, tim, am lucrat cu două funct,ii. printf s, i atent,ie, main. Da, încă de la Hello World, at,i grupatinstruct,iunile într-o funct,ie. Această funct,ie main are o semnificat,ie deosebită. Compilatorul caută această funct,ie capunctul principal de intrare în program. Prima linie de cod din funct,ia main (nu chiar, dar abstractizăm deocamdată)este prima care se va executa în momentul în care procesorul ajunge să execute programul nostru.

    2.4.2 Funct, iile

    Funct, iile nu sunt doar un mod, comod pentru noi, cu care grupăm codul. Există instruct,iuni speciale de procesor caregestionează apelul de funct,ie. Deocamdată nu vom simt,i diferent,a între a avea nis, te instruct,iuni grupate astfel încât săpoată fi apelate us, or s, i a avea o funct,ie cu tot ce înseamnă o funct,ie. (stivă, variabile locale, recursivitate, etc).

    Funct,ia printf ascunde în spatele ei un cod foarte complex care poate să transforme un pattern de bit,i din memorieîn text clar, interpretabil de oameni (human readable). Este o funct,ie, de multe ori deja compilată la nivelul toolchain-ului.

    Din acest punct vom face distinct,ie clară între o instruct,iune printf("hello"); s, i un apel de funct,ie:printf("hello"). Care e diferent,a? Caracterul ; de la sfârs, it. Diferent,a este foarte importantă pentru că unapel de funct,ie poate să apară într-o expresie. E perfect legal (dar nu prea are sens) să scriem expresia i = 10 +printf("hello"). S, i să o scriem ca s, i condit,ie la if. NU VA RECOMAND SA FACET, I ASTA!!! Dar este legal

    12 Chapter 2. Iterat, ia 1

  • Programarea Calculatoarelor, Versiune 0.32

    din punct de vedere al C-ului. (valid din cauză că printf returnează ceva. Dacă funct,ia apelată nu returnează nimic,nu este valid ca apelul să apară într-o expresie)

    Atunci când apelăm o funct,ie, compilatorul copiază cont,inutul memoriei variabilelor s, i a constantelor scrise întreparantezele de la linia de unde se fae apelul, în zona de memorie a variabilelor funct,iei (acolo unde sunt instruct,iunilefunct,iei). Acest fapt este esent,ial când vet,i proiecta funct,ii.

    În exemplul Cod 2.3 am văzut cum se declară o funct,ie, funct,ia main(): un cuvânt cheie urmat de nume, apoi ()urmat, atent,ie, de un bloc de instruct,iuni. În cazul nostru, numele este main, cuvântul cheie este void (acesta aratăce returnează funct,ia, în cazul nostru declarăm că nu returnează nimic) După paranteze urmează un bloc de instruct,iunidelimitat de acolade: {}. Nu putem pune doar o instruct,iune, ca s, i la for.

    Am văzut s, i cum se apelează o funct,ie, cu parametri. Se scrie numele funct,iei urmat de parametrii funct,iei, întreparanteze. Prin intermediul acestor parametri, transmitem de exemplu, codului din printf ce s, i cum să afis, eze peecran.

    2.4.3 Expresiile

    Expresia este o combinat,ie de operat,ii matematice, atribuiri, apeluri de funct,ii etc. care la sfârs, it are o valoare.

    Exemple de operat,ii matematice: +, -, * , /, %. Aces, tia se numesc operatori. Ei "operează" pe operanzi. (constante,variabile, apeluri de funct,ii).

    Am mai întâlnit s, i operatorul de egalitate == respectiv diferit !=. Putem avea comparat,ii de inegalitate, mai mic respectiv =. Putem construi expresii logice mai complexe cu operatori logici: s, i &&, sau ||, negare!.

    Ca s, i în matematică, operatorul de înmult,ire are prioritate fat, ă de cel de adunare. Deocamdată ne oprim aici cuoperatorii. Sunt mult mai mult,i, îi vom atinge pe majoritatea iar priorităt,ile lor sunt un subiect care pune probleme laexamen s, i dă multe bug-uri.

    Mare atent,ie la operatorul de atribuire = s, i cel de comparat,ie == . Sursa inepuizabilă de bug-uri!!!

    2.5 Memoria si variabilele

    Memoria calculatorului este văzută de procesor ca un s, ir de octet,i. Un octet este un număr reprezentat binar prin 8 bit,i(One byte have 8 bits). Într-un octet putem memora 256 de valori, exemplu de la 0 la 255.

    Zecimal Binar0 == 00000000255 == 11111111

    Prima locat,ie de memorie are adresa 0 iar ultima adresă depinde de cantitatea de memorie disponibilă (nu chiar, darlăsăm paginat,ia pentru Arhitectura Calculatoarelor).

    Pentru că e greu s, i există un risc mare de securitate să lucrăm cu pozit,ii fixe în memorie, există conceptul de variabile.Acestea pot fi privite ca s, i un pseudonim (alias) pentru o anumită adresă. Variabilele au un tip s, i un nume.

    Când scriet,i instruct,iunea care declară o variabilă, de exemplu int i; facet,i câteva lucruri:

    • Compilatorul s, tie că vă trebuie o zonă de memorie, o rezervă. Câtă memorie? Depinde de tipul variabilei.

    • Peste tot unde va apărea i compilatorul va "înlocui" litera i cu ceea ce se află stocat la adresa rezervată anterior

    • Când va implica variabila i în diverse operat,ii va s, ti că pattern-ul de bit,i de la acea adresă reprezintă un întregcu semn. Cuvântul cheie pus înaintea numelui variabilei este tipul variabilei. El specifică cum interpreteazăcompilatorul pattern-ul de bit,i stocat la adresa variabilei.

    2.5. Memoria si variabilele 13

  • Programarea Calculatoarelor, Versiune 0.32

    Toate cele trei puncte de mai sus sunt vitale s, i trebuie să vă intre foarte bine în reflexe, atunci când vedet,i o variabilă.

    Rezervarea memoriei este importantă pentru că programul vostru nu este singurul care se execută pe mas, ină. Dacăscriet,i aiurea în memorie (se poate) în cel mai bun caz sistemul de operare vă lichidează programul iar într-un scenariupesimist dat,i peste cap întreaga mas, ină.

    Nu e foarte dragut, acest scenariu când mas, ina e alcătuită din aprox. 40 de tone de explozibil aprins. A păt,it-o Ariane5 la primul zbor. Procesorul a fost instruit să scrie o valoare ce ocupa 8 octet,i într-o locat,ie unde erau rezervat,i doar 4.Au fost doar pagube materiale. Căutat,i "Ariane 5 first flight software bug". Asta s-a întâmplat în 1996. S, i dacă asta vise pare preistorie, căutat,i "Boeing 747 Max crash". Problema nu a fost aceeas, i dar a t,inut tot de software. Din păcatecâteva sute de oameni au murit.

    Tipul variabilei specifică două lucruri vitale: (1) Cîtă memorie trebuie alocată s, i (2) Cum interpretăm, în operat,ii,pattern-ul de bit,i stocat acolo.

    Tipul este un contract între noi, cei care folosim variabilele s, i cei care au creat microprocesoarele (respectiv auimplementat pe ele diverse operat,ii). Folosind variabilele noi spunem CE vrem să se întâmple (ex adunarea) iar prinintermediul tipului procesorul s, tie CUM să efectueze operat,ia (adunare în virgulă mobilă).

    Conceptul de tip stă la baza programării orientate pe obiect. Concepte ca încapsularea, polimorfismul, interfet,ele etcse pot explica foarte us, or interpretând conceptul de tip ca o legătură între nis, te bit,i s, i operat,iile care se pot face cuacei bit,i.

    Haidet,i să vedem câteva tipuri de date s, i cum este interpretat pattern-ul de bit,i de către procesor. MARE ATENT, IE!!!Numărul de octet,i/bit,i ocupat de un tip de date este diferit de la o arhitectură la alta! Aici este doar un exemplu.

    Table2.1: Câteva tipuri, dimensiunea memoriei rezervate s, i interval devalori posibile.

    Tip Dimensiune bit, i Interpretare Interval de valorichar 8 Caracter (întreg fără semn) 0 la 255short 16 Întreg cu semn -32,768 la 32,767int 32 Întreg cu semn -2,147,483,648 la 2,147,483,647float 32 Virgulă mobilă 3.4 * 10−38 < |𝑖| < 3.4 * 1038double 64 Virgulă mobilă 1.7 * 10−308 < |𝑖| < 1.7 * 10308void* 8/16/32/64 Adresă de memorie Depinde de arhitectura sistemului

    Deasemenea avem modificatori cum ar fi long sau unsigned. Modificatorul long rezervă mai mult,i bit,i. Mergepe int s, i double. unsigned, după cum îi zice s, i numele, modifică interpretarea pattern-ului de bit,i ca întreg fărăsemn.

    Valorile întregi fără semn se păstrează direct în codul binar 11 = 1 * 23+0 * 22+1 * 21+1 * 20 adică pentru numărul11 avem în memorie pattern-ul 1011. Restul bit,ilor sunt 0.

    Numerele întregi cu semn se păstrează ca si Two's complement iar cele în virgulă mobilă după standardulIEEE-754.

    Mai încolo vet,i învăt,a (s, i uita la fel de rapid) despre endianess. Pe scurt, această not,iune specifică unde se alfă bitulsau octetul cel mai semnificativ într-un s, ir de bit,i sau octet,i. Deocamdată ret,inet,i că în memorie bit,ii se scriu ca s, i pehartie. Numărul zecimal 34 este identic cu numărul 0000034. Nu contează zero-urile din fat, ă. La fel, în binar, 11 esteidentic cu 0000 0000 0000 0011 (am lăsat spat,ii pentru claritate)

    Dimensiunea memoriei ocupată de un tip sau de o variabilă se poate afla cu operatorul sizeof. Des, i se foloses, te cuparanteze, este considerat un operator s, i nu o funct,ie: sizeof(int) va spune cât,i octet,i sunt rezervat,i pentru tipulint pe platforma pe care rulează codul. În practică niciodată să nu presupunet,i că pentru un anumit tip sunt stocat,i unanumit număr de octet,i. Folosit,i sizeof în calcule. Există însă s, i tipuri speciale pentru care compilatorul garanteazăun număr specific de octet,i. Nu intrăm acolo.4

    4 Căutat,i specificat,iile stdint.h dacă vă trebuie dimensiune fixă de bit,i la anumite variabile, independent de arhitectura sistemului pentrucare se face compilarea.

    14 Chapter 2. Iterat, ia 1

  • Programarea Calculatoarelor, Versiune 0.32

    Trebuie să ret,inet,i că atunci când lucrăm cu o variabilă, compilatorul produce instruct,iuni care, în orice operat,ie încare este implicată variabila, înlocuies, te variabila cu cont, inutul memoriei definit de variabilă. Aceste operat,ii sunttransparente pentru limbajul C. De aceea, când scriem de exemplu i + 2 compilatorul va crea instruct,iuni care aduccont,inutul memoriei lui i s, i apoi instruct,iuni care adaugă 2 la acea valoare.

    La fel se întâmplă s, i la atribuiri. i = -5 va fi tradus printr-o instruct,iune care scrie pattern-ul de bit,i corespunzătorlui -5 în locat,ia de memorie denumită i. Înainte de scriere, valoarea -5 va fi convertită într-un pattern de bit,i conformtipului variabilei i. Two's Complement dacă i este declarat int sau IEEE-754 dacă este double.

    2.5.1 Vizibilitatea unei variabile

    Scopul sau vizibilitatea unei variabile în cod. Instruct,iunea de declarare a unei variabile poate să apară în exteriorulcodului (ex în afara funct,iei main) sau în interiorul unui bloc de instruct,iuni. Mai poate apărea în interiorul expresieide init,ializare de la for.

    În funct,ie de locat,ia unde a fost declarată variabila aceasta este vizibilă sau nu în alte zone ale codului. Variabila estevizibilă în blocul curent după ce a fost declarată precum s, i în blocurile îmbricate în blocul curent. Variabila NU maieste vizibilă (compilatorul îi spune sistemului de operare ca NU mai are nevoie de zona de memorie) după ce se iesedin blocul în care a fost declarată.

    Dacă într-un bloc îmbricat este declarată o nouă variabilă cu acelas, i nume, aceasta din urmă o "ascunde" pe cea de penivelul superior.

    Deocamdată cu aceaste reguli vă vet,i descurca cu declaratul variabilelor. Le vet,i învăt,a mai us, or, lucrând s, i observândefectele.

    2.5.2 Alte observat, ii

    Adresa de memorie a unei variabile diferă de la o rulare la alta. Aceasta este o măsură de securitate. Cineva (de obiceiun virus) care preia controlul calculatorului poate citi foarte usor datele din memorie dacă s, tie la ce adresă se află.Gândit,i-vă că vă cites, te user/parola când vă logat,i undeva. Din fericire, astfel de situat,ii sunt mai rare, tocmai datorităalegerii aleatoare a locat,iei variabilelor, de către sistemul de operare2. Evident, dacă este important, inginerul poatespecifica locat,ia de memorie. Util dacă lucrat,i pe dispozitive cu memorie foarte put,ină.

    Ce este vital în a s, ti despre variabile:

    • O variabilă defines, te o locat,ie de memorie. În timpul execut,iei, numele este înlocuit în expresii de valoareastocată acolo.

    • Cantitatea de memorie alocată este dictată de tipul variabilei.

    • Există operatori care pot lucra s, i direct cu adresa unei variabile. Dar în operat,iile unde astfel de operatori nusunt folosit,i, aducerea s, i scrierea valorilor din s, i în memorie este transparentă.

    • Fiecare variabilă are un tip s, i un nume. Tipul este necesar compilatorului atunci când efectuează operat,ii curespectiva valoare. În procesor există instruct,iuni separate pentru adunare cu semn, fără semn, în virgulă mobilă,etc. Compilatorul trebuie să s, tie cu ce instruct,iune mas, ină să efectueze operat,iile.

    • Numele este util doar pentru noi. Acesta va fi convertit după compilare într-o adresă de memorie.

    • NU putem lucra cu o variabilă nedeclarată înainte. Asta înseamnă că instruct,iunea de declarare trebuie să aparăînaintea primei utilizări, în blocul curent. Atent,ie la blocurile îmbricate s, i blocurile "surori"!

    • Ignorarea regulilor de vizibilitate pot duce la bug-uri s, i erori de compilare.

    2 Există sisteme de "izolare" a programelor, la nivelul sistemului de operare. Un virus însă poate să se "strecoare" s, i să aibă aceleas, i drepturi cuOS-ul. Asta ignorând fenomene ca Spectre sau Meltdown (căutat,i pe internet "Meltdown and Spectre bugs" s, i vă îngrozit,i)

    2.5. Memoria si variabilele 15

  • Programarea Calculatoarelor, Versiune 0.32

    2.5.3 Init, ializarea variabilelor s, i constante

    Ultimul punct atins despre variabile în această iterat,ie este despre cum se init,ializează la declarare. Am văzut laexemplul cu for că putem avea construct,ii de genul int i = 0 asta făcând ca la locat,ia i să păstrăm un întreg pe4 octet,i5 s, i să init,ializăm zona cu zero.

    Cifra 0 este o constantă numerică în baza 10, de tip int. Adică constanta va ocupa 4 octet,i5 s, i este reprezentată cusemn! Putem modifica acest lucru de exemplu 0l pentru a o face de tip long int. Putem scrie constante în baza16, folosind prefixul 0x. Foarte des când lucrăm cu adrese. 0xA este 16.

    Tipul standard pentru constante în virgulă mobilă este double. Putem folosi notat,ia s, tiint,ifică, 1e3 este 1000.

    Mai avem câteva feluri de constante, caracter s, i s, ir de caractere. Un caracter este pus între apostrof ' iar s, irul decaractere între ghilimele ". De obicei un caracter ocupă un octet s, i este reprezentat fără semn. Există o convent,ie înC, un s, ir de caractere este o zonă de memorie terminată cu un octet ce cont,ine doar 0.

    Foarte important, constanta 'a' ocupă un octet iar constanta "a" ocupă doi. Octetul cu pattern-ul de bit,i a caracteruluia urmat de octetul cu pattern-ul de bit,i al ciferi 0.

    Este legal să folosit,i o constantă caracter acolo unde se acceptă un număr întreg. Este perfect valid să scriet,i 'a' + 1.Expresia va lua valoarea 'b'. Sau valoarea zecimală 98. Depinde de cine interpretează pattern-ul de bit,i 01100010.

    În apelul de funt,ie printf primul parametru este un s, ir de caractere. Compilatorul alocă automat memorie pentruacest s, ir de caractere iar la execut,ie se va copia adresa rezervată în interiorul codului de la printf. Vom reveni înIterat,ia 2 cu detalii.

    2.6 Intrări s, i ies, iri

    2.6.1 Ies, irea în consola text

    Am tot vorbit de funct,ia printf acum a venit momentul să vedem mai multe detalii. Nu uitat,i, într-o expresie,operatorul % defines, te operat,ia de modulo. S, i constanta de tip s, ir de caractere este o bucată de text (pe o linie)delimitată de ghilimele.

    Examinând exemplele de mai sus (printf("%d ", i)) observăm că acest caracter % apare în interiorul s, iruluide caractere.

    Funct,ia printf din biblioteca standard este responsabilă de afis, area în consolă a unui text. Funct,ia acceptă ca primparametru un s, ir de caractere, urmat de zero sau mai mult,i parametri. Există un cod complex în interiorul funct,iei caredescompune s, irul de la intrare, caută caracterul % s, i pentru fiecare caracter % va căuta parametrul corespunzător dinrestul parametrilor de intrare. Complicat? Cam da.

    Să ne uităm la printf("%d ", i). Primul parametru al funct,iei este s, irul de caractere "%d " iar al doilea estevariabila i.

    Codul din biblioteca standard, va începe să interpreteze s, irul, caracter cu caracter. Dacă nu e caracterul %, afis, eazăcaracterul curent pe ecran. Când întâlnes, te %, intră într-un mod special.

    1) Se identifică parametrul corespunzător din rîndul parametrilor de intrare. În cazul nostru, i.

    2) Caracterul imediat de după % va defini modul în care, codul din printf va interpreta pattern-ul de bit,i aparametrului de intrare.

    Construct,ia %d se numes, te specificator de format. Pentru fiecare tip, există o literă diferită. Dacă pe ecran vedet,ibălării, o sursă ar fi specificatorul gres, it. Caz frecvent, afis, area unui float ca int. Într-un int, numărul este păstratca s, i Two's complement dar un float în standardul IEEE-754. Semnificat,ia bit,ilor este radical diferită!

    5 Depinde de arhitectură, dar NU vom mai tot relua acest aspect.

    16 Chapter 2. Iterat, ia 1

  • Programarea Calculatoarelor, Versiune 0.32

    Cât,iva specificatori utili: %d pentru int, %f pentru float, %c pentru caracter s, i %s pentru un s, ir de caractere.Se pot face formatări complexe, se poate controla numărul de zecimale, numărul minim de caractere afis, ate, formats, tiit,ific, afis, are în hexazecimal, etc etc. Vă recomand să studiat,i un pic documentat,ia funct,iei printf.

    Important: Nu vi se va cere, la examen, să s, tit,i pe de rost tot,i specificatorii de format! Dar cât,iva, ît,i vei folosi as, a dedes încât vă vor intra în automatism. Necunoas, terea lor de obicei denotă faptul că at,i cam sărit activităt,ile de laborator.

    Până acum nu ne-am legat de #include . Pe scurt, aceasta este o comandă pentru prima componentădin toolchain (denumită preprocesor). Pe scurt, comanda va încorpora cont,inutul fis, ierului stdio.h în codul nostru.Apoi codul va fi livrat către compilator. În stdio.h este declarată funct,ia printf. Numele stdio vine de laSTandard Input Output iar printf de la PRINT Formatted. Există mai multe surori ale funct,iei:

    • sprintf - String PRINT Formatted, care în loc să "tipărească" pe ecran, scrie output-ul într-o zonă de memorie

    • fprintf - File PRINT Formatted, care trimite output-ul într-un fis, ier.

    Constantele de tip caracter se păstrează pe 8 bit,i, adică putem avea maxim 255 de caractere. Cifra 0 (adică 00000000în binar) denotă sfârs, itul s, irului s, i este tratată altfel. Corespondent,a dintre pattern-ul de bit,i s, i caracterul afis, at pe ecran(sau interpretat de procesor) este dată de codul ASCII. S, i este o convent,ie universal acceptată în programare. Litereledin codul ascii sunt cele din limba engleză. Pentru că în lume există mult mult mai multe tipuri de litere (chinezes, ti,chirilice, diacriticele din limba Română, Germană, Franceză. etc etc) codul ASCII a fost extins cu Unicode UTF-8(evident treburile sunt MULT mai stufoase). Acest cod foloses, te mai mult,i bit,i pentru a coda un caracter. Funct,iilecare procesează caractere (inclusiv printf) trebuie să s, tie dacă are de a face cu un s, ir de caractere ASCII sau s, iruleste codat în alt standard. Deocamdată insist să NU FOLOSIT, I diacritice sau alte semne speciale în codul vostru! Niciîn codul sursă (comentarii, nume de variabilă) s, i nici în constantele de tip caracter/text.

    2.6.2 Citirea de la tastatură

    La începutul materialului am povestit despre cum procesorul ascultă dacă s-a apăsat sau nu o tastă s, i react,ionează laapăsare. Există un astfel de "circuit" (până la urmă tot o bucată de cod) în calculator dar nu procesorul. Circuitul,înt,elege mesajele trimise de la tastatură s, i le stochează într-o zonă specială denumită buffer de tastatură. De aici,programul nostru le poate citi.

    Funct,ia cea mai utilă, care cites, te pattern-urile de bit,i din buffer-ul de tastatură s, i le decodifică conform specificat,iilornoastre este scanf.

    scanf vine de la SCAN Formatted. Se găses, te tot în biblioteca stdio.h Ca s, i la printf avem variantele sscanf s, ifscanf pentru a decoda s, iruri de caractere s, i respectiv, a citi din fis, iere.

    Funct,ia scanf acceptă un parametru s, ir de caractere care cont,ine nis, te specificatori de format. Următorii parametrisunt adresele de memorie unde va fi stocat rezultatul decodificării.

    Deocamdată vă arăt apelul de funct,ie s, i intrăm în detalii mai încolo. Pentru a citi un întreg trebuie să:

    • Avem o zonă de memorie în care să putem stoca întregul (declarăm o variabilă)

    • Utilizăm %d ca specificator de format

    • Trimitem adresa de memorie unde dorim să se facă memorarea, la scanf.

    Atent,ie, după cum spuneam la capitolul despre funct,ii, compilatorul copiază cont,inutul memoriei parametrilor careîi dăm la funct,ie, în zona de memorie a variabilelor definite în funct,ie. Aici e un pic de subtilitate, pentru că, dacăapelăm o funct,ie f(i), funct,ia va primi o copie a zonei de memorie i în momentul apelulu. Dacă funct,ia va vroi sămodifice ceea ce se află la adresa lui i va trebui să lucreze direct cu adresa de memorie a variabilei i.

    Această capacitate a limbajului C de a lucra direct cu adresele de memorie (În curând faimos, ii s, i mult urât,ii operatori* s, i &) dau o fort, ă inimaginabilă limbajului C. S, i ca orice putere mare, ea se poate folosi ca să facem lucruri frumoasesau ca programatorul să îs, i dea peste degete. Depinde de voi! Bun, revenind, deocamdată e suficient să s, tit,i că lucrul

    2.6. Intrări s, i ies, iri 17

  • Programarea Calculatoarelor, Versiune 0.32

    cu memoria este mai dificil de stăpânit DAR este un element central în C. (vital în meseria de Inginer s, i bineînt,eles,temeinic verificat la examen)

    Exemplu de citire a unui întreg. Vet,i putea folosi instruct,iunile de mai jos:

    #include int main(){

    int i;scanf("%d", &i);printf("Am citit %d", i);return 0;

    }

    Se declară variabila i iar singurul lucru diferit este modul în care se trimite i ca parametru la scanf. Scriem &ipentru a afla s, i trimite adresa rezervată pentru i. Valoarea adresei lui i va fi copiată într-o zonă de memorie rezervatăde codul scanf, zonă de memorie capabilă să manipuleze adrese de memorie.

    Intern scanf se as, teaptă ca pentru fiecare caracter % din s, irul de caractere primit să primească s, i o adresă. Atent,ie, vaprimi o adresă pe care o va putea manipula. Această adresă va fi stocată într-o variabilă specială, variabilă care poatemanipula adrese. În Tabelul 2.1 avem tipul void* care permite exact acest lucru.

    Codul din scanf cites, te buffer-ul de tastatură s, i convertes, te s, irul de caractere găsit acolo conform specificatoruluide format. După conversie pattern-ul de bit,i va fi stocat la adresa de memorie primită ca parametru. Speficicatorul deformat spune s, i câtă memorie va fi "umplută" cu acest pattern de bit,i. Nu există posibilitatea ca scanf să s, tie câtămemorie este rezervată.

    Un exemplu pe codul anterior: Dacă la specificatorul de format avem %d s, i în buffer sunt caracterele -1386 laadresa lui i se va stoca pattern-ul de bit,i 11111111111111111111111101110110 adică valoarea -138 în Two'scomplement presupunând o arhitectură unde int ocupă 4 octet,i (32 bit,i).

    Gres, eli frecvente care se fac:

    1) Uitat,i să trimitet,i o adresă (mai ales când vet,i începe să lucrat,i cu variabile ce memorează adrese)

    2) Specificatorul de format nu corespunde cu tipul variabilei. scanf va coda ceea ce a citit într-un pattern de bit,icorespunzător. Dacă variabila declarată are un tip incompatibil (ex float vs int) vor apărea probleme

    3) Nu avet,i memorie rezervată la adresa trimisă spre scanf. Eroare de obicei corelată cu (1).

    Ca ultim exercit,iu, modificat,i codul de afis, are a numerelor pare pentru a afis, a primele numere pare non negative maimici decât un întreg citit de la tastatură.

    După ce vă iese, adăugat,i cod de validare a intrării. Numărul citit trebuie să fie non negativ, să fie rezonabil de micpentru a încăpea pe ecran, etc. Afis, at,i mesaje pentru fiecare situat,ie invalidă. Nu uitat,i de abordarea iterativă! Lafiecare modificare, compilat,i s, i rulat,i! Nu scriet,i mult cod fără să îl verificat,i!

    Succes!6 Adică caracterele -, 1, 3, 8, urmat de un caracter alb.

    18 Chapter 2. Iterat, ia 1

  • Programarea Calculatoarelor, Versiune 0.32

    2.7 Lean

    Am văzut un prim element fundamental al abordării de tip lean. Iterat,ia. Am văzut-o în exemplele de laborator, amvăzut-o la modul în care vi s-au prezentat cunos, tint,ele de C.

    Ce nu at,i văzut până acum este modul în care alegem "subproblemele" la care lucrăm. Există abordarea standard,folosită în mediul de startup (business) sau în cercetare. A doua abordare este cea pe care o facet,i când învăt,at,i ceva.

    2.7.1 Abordarea standard

    Dacă vrei să ai succes cu business-ul, metodologia spune că trebuie să es, uezi. Să es, uezi rapid, să es, uezi ieftin. Lucrulsau scopul cu care pornes, ti iterat,ia este de obicei cel mai riscant lucru pentru business. De ce? Pentru că dacă NUîl pot,i rezolva sau ocoli, nu are rost să te apuci de respectiva treabă. Aici intră poate mai put,in dificultăt,i tehnice(exceptând cazul în care vrei să rezolvi teleportarea) s, i mai mult dificultăt,i ce t,in de piat, ă.

    Ca business, va trebui să răspundet,i rapid la întrebări de genul "Va exista cerere?" "Voi putea vinde cu pret,ul X?" etcetc.

    La fel este s, i în proiectele experimentale, orientate pe cercetare. Se formulează ipoteze care sunt validate sau infirmateîn urma implementării s, i efectuării experimentului. Odată ce o ipoteză este verificată, se pate trece la următoarea.

    2.7.2 Abordarea când învăt,at, i

    Dacă la abordarea standard, t,elul mare era de a realiza ceva (venituri financiare mari, succes în cariera de cercetător),aici scopul fundamental este de a acumula sau sedimenta cunos, tint,e noi.

    Vă recomand ca la abordarea iterativă a problemelor să începet,i tot timpul cu ceea ce s, tit,i. Fiecare nouă iterat,ie să văîndrepte spre zona necunoscută, pas cu pas. As, a, atunci când "ceva nu iese" suntet,i siguri că nu iese din cauza iterat,ieicurente s, i nu din cauză că at,i gres, it ceva în urmă cu 100 de linii de cod. Asta deoarece acele linii au fost scrise într-oiterat,ie anterioară. Iterat,ie, care, ca finalitate, a avut s, i o parte de testare a ceea ce at,i implementat.

    Mai jos sunt arătat,i principalii pas, i ai metodologiei Lean.

    Selectare problem 

    Testare Proiectare

    Implementare

    Figure2.1: Pas, ii metodologiei lean. Atent,ie, ciclul se reia până când problema este gata.

    Selectare problemă Vă aleget,i o subproblemă cunoscută, de exemplu citirea de la tastatură. Subproblema se mainumes, te s, i obiectivul iterat,iei. Dacă pe parcurs acest obiectiv se schimbă, iterat,ia se "resetează"

    Proiectare Vă gândit,i cum să abordat,i problema propusă. Vă putet,i folosi de o hârtie s, i creion. Putet,i căuta pe internetdocumentat,ii, how-to sau putet,i decide că problema e prea complexă s, i mai trebuie împărt,ită în mai multe bucăt,i. Înacest caz, revenit,i la pasul anterior. (Aleget,i o nouă subproblemă)

    Implementarea Scriet,i cod conform pasului de la proiectare. Compilat,i, rulat,i codul, asigurat,i-vă că ceea ceimplementat,i este valid. Dat,i un input la problemă s, i asigurat,i-vă că nu at,i scris ceva gres, it. Doar cine nu munces, te,nu gres, es, te.

    2.7. Lean 19

  • Programarea Calculatoarelor, Versiune 0.32

    Testarea S, tit,i care este obiectivul iterat,iei, acum este momentul să vă asigurat,i că ceea ce at,i implementat corespunde.Putet,i rezolva pe hârtie câteva cazuri particulare pe care le introducet,i la input s, i observat,i ies, irea. De cele mai multe oriaceastă etapă presupune s, i scriere de cod (ex. printf-uri). (Poate la alte materii vet,i auzi s, i de testarea regresivă sauUnit Testing unde codul de test, este considerat parte integrantă din proiect s, i este verificat la fiecare modificare aproiectului.) Dacă identificat,i bug-uri, corectat,i. Dacă at,i identificat o eroare de logică, (ex. at,i ratat obiectivul) reluat,itot procesul. Probabil că etapa de proiectare a fost necorespunzătoare.

    Iterat, i Cel mai important lucru la această abordare! Repetat,i procesul de mai sus! Important, NU s, terget,i codul detest. Comentat,i-l. Sigur vă va trebui în alte iterat,ii când vet,i face modificări la codul deja scris. Cu fiecare iterat,ietrebuie să vă apropiat,i de lucrurile necunoscute sau mai grele ale problemei mari. Când vet,i ajunge la ele, vă vet,iputea focusa strict la ele, deoarece s, tit,i că elementele de care depinde această problemă mai grea, există s, i sunt corectimplementate.

    2.7.3 Abordarea când stăpânit, i instrumentele

    La un moment dat vet,i ajunge să s, tit,i destul de bine limbajul de programare. Nu este foarte productiv să începet,i culucrurile cunoscute. Putet,i să abordat,i "din prima" subproblema mai grea. Poate avet,i nis, te cerint,e mai deosebite (exsortare). Vă putet,i apuca să rezolvat,i sortarea, după care să abordat,i citirea s, i/sau afis, area datelor.

    Pas cu pas, pe măsură ce acumulat,i tot mai multe cunos, tint,e s, i instrumente, vet,i ajunge să abordat,i în prima iterat,ielucrul cel mai riscant/necunoscut. Despre restul, vet,i putea estima atât volumul de muncă necesar cât s, i instrumentelecare le vet,i folosi.

    Succes!

    20 Chapter 2. Iterat, ia 1

  • CHAPTER 3

    Iterat, ia 2

    3.1 Introducere

    În acest moment avet,i câteva "blocuri" cu care puteti construi programe simple. Iterat,ia curentă va aprofunda not,iunileînvăt,ate în iterat,ia 1 fără a adăuga multe elemente complet noi. Vom merge pe verticală. Atentie, NU veti deveniexperti în C sau în Programarea Calculatoarelor nici după această iterat,ie s, i nici la finalul cursului. Vă mai trebuiemulte cunos, tint,e de la alte materii precum s, i cât,iva ani buni de lucru în product,ie. Cursul acesta vă învat, ă not, iunilede bază care vă vor fi utile în a controla un procesor s, i a putea să vă adaptat, i rapid la noi limbaje de programaresau arhitecturi. Cam tot ce există acum pe piat, ă, ca hardware, (profesionist sau amator) se poate controla cu ajutorulC-ului.

    Am lăsat discut,ia în punctul în care s, tit,i să vă rezervat,i memorie, să efectuat,i calcule matematice simple, să folosit,ivariabilele în instruct,iuni de control, s, i să citit,i/scriet,i cont,inutul variabilelor folosindu-vă de tastatură s, i ecran.

    În iterat,ia curentă intrăm mai în detaliu despre cum lucrează procesorul cu memoria s, i cum organizează limbajul Cmemoria.

    3.2 Tipuri de memorie accesibile programului

    La cel mai jos nivel memoria este văzută ca un s, ir de locat,ii, fiecare locat,ie putând stoca 8 bit,i. La nivel de aplicat,ieînsă există mai multe categorii de memorie, fiecare cu specificul ei. Această categorisire este impusă de arhitecturaprocesorului s, i de sistemul de operare. S, i este o convet,ie între programatori s, i cei care au realizat arhitectura.

    Avem memoria care t,ine codul, care memorează programul nostru. Nu scriem în această memorie dar putem facereferire prin adrese, la adrese (bucăt,i de cod sau date) de aici.

    Avem apoi memoria de lucru. Numită Heap. Aceasta este gestionată de funct,ii speciale din C. Cu ajutorul sistemuluide operare, capacitatea acestei memorii poate depăs, i dimensiunea memoriei fizice (RAM) disponibilă pe calculator.Orice date care ocupă spat,iu mult vor trebui stocate aici.

    Există memoria statică, care este alocată de compilator. Aici se păstrează variabilele care sunt vizibile în tot codulprecum s, i constantele pentru care trebuie memorie.

    21

  • Programarea Calculatoarelor, Versiune 0.32

    Pentru a gestiona apelurile de funct,ii s, i pentru a stoca un anumit fel de variabile există o zonă de memorie numităstivă. Este o zonă mică ca dimensiune, care se umple repede dacă nu suntet,i atent,i. Erorile de stivă sunt foarte foartefrecvente, de unde s, i numele celui mai celebru site cu răspunsuri pentru programatori: Stack Overflow1

    Locul unde se alocă variabilele s, i cantitatea de memorie disponibilă depinde de locul s, i modul cum lucrăm cuvariabilele.

    3.2.1 Variabile globale fis, ierului curent

    Acestea sunt declarate în exteriorul oricărei funct,ii. Ele sunt vizibile din locul în care au fost declarate până la sfârs, itulfis, ierului curent.

    Există posibilitatea ca în programul nostru să avem mai multe fis, iere. Vom vedea mai încolo cum "comunicăm" s, i cumpartajăm memorie între diverse bucăt,i din program (Un fis, ier .c este considerat un modul al programului)

    Aceste variabile pot fi schimbate de orice funct,ie din fis, ierul curent. De aceea este de preferat a se evita folosirea lor.Există modificatori (cuvântul cheie const) care împiedică acest lucru. Îl vom atinge mai încolo.

    Variabilele acestea se alocă în zona statică a programului. Alocarea s, i init,ializarea lor se face înainte de execut,iaprimei linii din funct,ia main(). Este treaba compilatorului să realizeze acest lucru.

    Deasemenea, în funct,ie de compilator, pot apărea probleme dacă există alte variabile declarate în alte module, cuacelas, i nume.

    Recomandarea ar fi să le folosit,i doar pentru constante sau setări globale ale aplicat,iei.

    3.2.2 Variabile locale funct, iei/blocului curent

    Pe scurt, acestea sunt variabilele declarate între acolade. Ele sunt alocate pe stivă. Dar să intrăm în detalii. La intrareaîntr-o funt,ie sau bloc de instruct,iuni compilatorul alocă pe stivă toate declarat,iile de variabile întâlnite în bloc/funct,ie.La ies, ire din bloc/funct,ie, ele sunt s, terse (dealocate).

    Pe stivă se păstrează s, i parametrii de intrare ai funct,iei (vom vedea mai multe la funct,ii).

    Acelas, i rat,ionament se aplică s, i la blocuri de instruct,iuni. De exemplu, o variabilă declarată în interiorul unui ciclufor, va fi alocată pe stivă s, i va fi s, tearsă când execut,ia codului va ies, i din blocul for.

    Acesta este motivul pentru care variabilele din interiorul unui bloc sau a unei funct,ii NU sunt vizibile in exterior, darsunt vizibile în blocurile aflate în interiorul blocului curent.

    Atent,ie, apelul unei funct,ii presupune intrarea într-un nou bloc de instruct,iuni. Indiferent de unde este apelată funct,ia,codul din funct,ie NU "vede" memoria alocată în blocul de unde a fost apelată.

    Să vedem câteva exemple:

    Listing 3.1: Vizibilitatea variabilelor

    1 int g1;2 void some_func(){3 int a, b;4 {5 int i, b;6

    7 }8

    9 }10

    (continues on next page)

    1 https://stackoverflow.com/

    22 Chapter 3. Iterat, ia 2

    https://stackoverflow.com/

  • Programarea Calculatoarelor, Versiune 0.32

    (continuare din pagina precedentă)

    11 int main()12 {13 int i, j;14 some_func();15 return 0;16 }

    • Variabila g1 este vizibilă (poate fi folosită) peste tot.

    • Variabilele i s, i j declarate la linia 13 sunt vizibile doar în codul funct,iei main() Ele NU sunt vizibile înfunct,ia some_func() sau în altă funct,ie din program

    • Variabilele i s, i b declarate la linia 5 sunt vizibile doar până la linia 7

    • Variabila i din linia 5 este diferită (ca locat,ie s, i vizibilitate) de variabila i din linia 13. Ele se pot folosiindependent s, i nu au efect una asupra celeilalte.

    • Variabila b din linia 5 "ascunde" variabila b din linia 3. Adică, orice operat,ie între liniile 5 s, i 7 vor afecta zonade memorie declarată la linia 5 s, i va ignora zona de memorie de la linia 3. Odată ies, it din blocul acesta (adicădupă linia 7) variabila b declarată în linia 3 va fi din nou vizibilă.

    Aceste reguli vă ajută să refolosit,i numele variabilelor în diverse funct,ii sau blocuri de cod. Atent,ie mare doar laascunderea variabilelor.

    Variabilele definite local se numesc s, i variabile automatice pentru că, de dealocarea lor se ocupă automat compilatorul.Aceasta este o facilitate foarte importantă, prezentă s, i în alte limbaje de programare.

    Când at,i modificat codul de la instruct,iunea for (Cod 2.2) adăugând doar o instruct,iune printf după terminareaciclului probabil că at,i obt,inut o eroare de compilare. Tocmai din cauză că variabila i a fost dealocată de compilatorcând s-a ies, it din blucla for.2

    Important: Stiva are dimensiune limitată! Aproximativ 64 KB, din care o parte este deja consumată de sistemul deoperare, înainte de a se începe execut,ia programului.

    Sunt două moduri uzuale în care se poate depăs, i stiva:

    • Alocarea unei bucăt,i de memorie mare (eg un tabel cu câteva zeci de mii de valori)

    • Alocarea de foarte multe ori a unei bucăt,i relativ mici de memorie, prin apel recursiv.

    În general, pentru variabile simple, contoare, variabile temporare, se poate folosi declararea locală.

    Pentru informat,iile citite de la diverse intrări, pentru datele cu volum mare (ex s, iruri de caractere, matrici, etc) sefoloses, te memoria heap.

    Mare atent,ie, la rezervarea memoriei, de obicei NU are loc s, i init,ializarea cu zero a zonei de memorie. Se întâmplăcând compilatorul este setat în modul Debug să adauge s, i o init,ializare cu zero. Dar acest lucru nu este garantatatunci când codul este compilat pentru a fi pus pe dispozitiv sau livrat la client (modul Release). As, a că dacă primafolosire a variabilei este ceva de genul i = i + 1 s-ar putea să avet,i parte de bug-uri foarte dificil de localizat.

    Acest tip de bug-uri se încadrează perfect în expresia "But it works on my computer!"

    2 Unele compilatoare nu dealocă variabilele declarate în interiorul primei expresii din instruct,iunea for. Mai ales cele de la Microsoft. De aceea,câteodată, astfel de construct,ii "merg".

    3.2. Tipuri de memorie accesibile programului 23

  • Programarea Calculatoarelor, Versiune 0.32

    3.2.3 Accesarea memoriei Heap

    Foarte pe scurt (vom face mai întâi pointerii), există două funct,ii de manipulare a acestei zone de memorie.

    • Funct,ia malloc care rezervă memorie

    • Funct,ia free care notifică sistemul de operare că nu mai e nevoie de bucata rezervată.

    Aceste funct,ii operează cu variabile de tip adresă de memorie. Adică, pattern-ul de bit,i ce va fi stocat la adresarezervată variabilei va fi interpretată de compilator ca o adresă. Complicat? Pare îmbârligat? Mai citit,i de 3 ori frazaanterioară pentru că, în mod uzual vet,i lucra cu variabile care stochează, la adresa de memorie rezervată lor, valoareaunei adrese, adresă unde se stochează valoarea altei adrese spre o zonă de memorie unde se află un întreg sau float.Da, s, tiu, bine at,i venit la Programarea Calculatoarelor!

    3.2.4 Declararea variabilelor

    Câteva remarci referitoare la cum declarăm variabilele. Până acum at,i văzut, instruct,iunea este destul de simplă:

    tip nume;

    Pot avea mai multe nume separate prin virgulă, toate având acelas, i tip. Exemplu: int i, j, k;.

    În cazul instruct,iunii de mai sus, TOT CE SE ALFĂ ÎN STÂNGA NUMELUI ESTE TIPUL VARIABILEI.Această observat,ie pare banală dar cont,ine nis, te subtilităt,i:

    De exemplu, unsigned int a;. Tipul lui a este unsigned int. Nimic greu, până când dat,i de as, a ceva:struct clasa *c;. Perfect valid. Tipul lui c este un pointer la o structură de date numită clasa.

    Listing 3.2: Exemplu de tip compus, unde regula de mai sus se aplică

    struct {int a;int b;

    } s1;

    Tipul lui s1 este tot ceea ce se alfă în stânga. Ca s, i la orice regulă, avem s, i except,ii (le vedem mai încolo)

    La declarare, de obicei pot să fac s, i init,ializarea cu o constantă. De exemplu:

    int a = 10;int b = 0xAF30;char c = 'A';float f = 34.2f;

    3.3 Variabile (date) compuse

    Am văzut cum putem lucra cu variabile simple, unde fiecare nume defines, te o locat,ie de memorie. De cele mai multeori acest lucru nu este suficient. Vrem de exemplu să stocăm un s, ir de valori citit de la o sursă externă (de exemplu oimagine sau un sunet) Nu putem stoca fiecare parte din imagine în câte o variabilă.

    Mai sunt situat,ii în care vrem să grupăm mai multe tipuri de date, pentru a descrie un concept. Ves, nicul exempluclasic, conceptul de persoană. Trebuie să stochez nume, data nas, terii, CNP-ul, poate adresa, ceva ID-uri speciale, etc.Pot declara variabile pentru fiecare element dar ce fac dacă am nevoie să descriu 10 persoane?

    24 Chapter 3. Iterat, ia 2

  • Programarea Calculatoarelor, Versiune 0.32

    3.3.1 Tablouri

    Pe scurt, un tablou este o bucată de memorie continuă, care ajută în situat,iile în care avem nevoie să stocăm acelas, i tipde date. Iarăs, i exemplul clasic, un vector unidimensional de întregi.

    Listing 3.3: Declararea unui tablou simplu

    int tab[4] = {0, 1, 2, 3};

    Declarat,ia mai completă a unui tabel arată astfel:

    Listing 3.4: Declararea unui tablou (sintaxa completă)

    tip nume[dim1][dim2] ... [dimn] = {{ ... {v1, v2, v3 ... } ... }};

    Am prezentat mai sus s, i declararea s, i init,ializarea. Spre deosebire de o variabilă simplă avem parantezele drepte s, iacoladele după egal.

    dim1 ... dimn specifică câte elemente avem pe fiecare axă. Aceste expresii trebuie să poată fi evaluate la compilare3.Init,ializarea se face specificând în acolade, elementele. Trebuie să avem EXACT atâtea nivele de îmbricare s, i EXACTatâtea elemente câte am declarat.

    Partea de init,ializare este opt,ională.

    În instruct,iunea de mai sus am "definit" un hipercub cu n dimensiuni (sau un tensor). În practică rar trecem de 3dimensiuni.

    Să dăm câteva exemple:

    • int tab[10]; Tabel de întregi cu 10 elemente.

    • char sir[100] = "Popescu"; va aloca 100 de caractere iar în primele 7 va scrie Popescu. Al 8-leava fi 0. Vom vedea la s, irurile de caractere, mai multe detalii.

    • double coef[3] = {3.32, 4.21, 334}; Tabel cu 3 double la care li se setează valorile init,iale.

    • double arr[2][100]; Un tabel cu două rânduri s, i 100 de elemente pe fiecare rând (100 de coloane)

    Dacă declarat,ia tabloului are loc global atunci init,ializarea are loc la compilare. Ca s, i la dimensiuni, valorile cu carese face init,ializarea trebuie cunoscute la compilare.

    Dacă declarat,ia este locală, init,ializarea se face la execut,ie as, a că putem avea orice expresie legală ca s, i elemente deinit,ializare.

    Mai există o formă de init,ializare în care nu specificăm limitele dimensiunilor, acestea putându-se dedude dininit,ializare:

    int tab[] = {1, 2, 5, 2};char sir[] = "Popescu";

    Compilatorul va s, ti că acest tabel (tab) are dimensiunea de 4 elemente iar sir 8. Din păcate nu funct,ionează decâtcu prima dimensiune. Restul, trebuie specificate manual.

    În cazul tabelelor multidimensionale, în memorie, tabelele se stochează în modul C contiguous. Asta înseamnaă căvalorile consecutive de pe un rând sunt consecutive în memorie. S, i că după ultimul element de pe rândul k urmeazăprimul element de pe rândul k+1.

    3 Unele compilatoare, acceptă, la declararea unui tabel local, ca expresia să cont,ină calcule ce nu se pot face decât în momentul execut,iei codului(ex. depind de parametrii funct,iei). Căutat,i în specificat,iile C99 si C++11 acest lucru ca să vă convinget,i că trebuie să evitat