Curs 1 - Introducere în Programarea în C

În acest curs vom explora bazele programării în limbajul C, începând cu arhitectura calculatorului și continuând cu structura unui program C.

1. Arhitectura Calculatorului și Rolul său în Programare

Arhitectura unui calculator definește modul în care hardware-ul gestionează datele și instrucțiunile. Cele mai importante componente sunt:

- CPU (Unitatea Centrală de Procesare): Execută instrucțiunile programului și efectuează calcule.

- Memoria RAM: Păstrează datele temporare necesare pentru rularea programelor.

- Stocarea (SSD/HDD): Conține sistemul de operare și fișierele programelor.

- Perifericele (Tastatură, Monitor, Placă de rețea, etc.): Interfața cu utilizatorul și alte dispozitive.

În funcție de arhitectura hardware, un program trebuie compilat pentru platforma țintă. De exemplu, codul compilat pentru x86_64 nu poate rula direct pe un procesor ARM fără o recompilare.

2. Prezentare Generală a Microprocesorului

Microprocesorul (CPU) este componenta principală care execută instrucțiunile programului. Caracteristicile sale influențează modul în care compilatorul generează codul binar.

- Arhitectura CPU (x86, ARM, RISC-V): Definirea setului de instrucțiuni pe care CPU-ul le poate executa.

- Modul de adresare a memoriei: Cum sunt accesate și gestionate datele în memorie.

- Niveluri de cache și optimizări: Compilatorul poate genera cod optimizat pentru performanță mai bună.

3. Cum Funcționează Compilarea unui Program C

Compilarea este procesul prin care codul sursă este transformat în cod executabil. În C, acest proces se realizează în mai multe etape distincte.

source: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

Compilatorul GCC (GNU Compiler Collection) realizează conversia codului C în fișier executabil prin patru etape majore:

a) Faza 1: Preprocesare (`-E`)

Se expandează macro-urile (`#define`), se includ fișierele (`#include`) și se elimină comentariile. Rezultatul este un fișier `.i`.

gcc -E program.c -o program.i

b) Faza 2: Compilare (`-S`)

Codul C este transformat în cod asembler, specific arhitecturii CPU. Rezultatul este un fișier `.s`.

gcc -S program.i -o program.s

c) Faza 3: Asamblare (`-c`)

Codul asamblator este transformat în cod mașină (binar) într-un fișier obiect `.o`.

gcc -c program.s -o program.o

d) Faza 4: Linking

Se combină fișierele obiect și se leagă bibliotecile pentru a obține fișierul executabil final.

gcc program.o -o program

4. Utilizarea Makefile pentru Automatizarea Compilării

Makefile ajută la gestionarea procesului de compilare, permițând recompilarea doar a fișierelor modificate.

program: program.c
	gcc -o program program.c

Compilarea se realizează acum prin rularea comenzii:

make

5. Tipuri de Date în C

Limbajul C suportă mai multe tipuri de date primitive și structurate:

a) Tipuri de date primitive

- int: Numar întreg

- float: Număr real cu precizie simplă

- double: Număr real cu precizie dublă

- char: Caracter ASCII

- void: Tip fără valoare, folosit în funcții

#include <stdio.h>
int main() {
    int a = 10;
    float b = 5.5;
    double c = 10.23456789;
    char d = 'A';
    printf("Int: %d, Float: %.2f, Double: %.8f, Char: %c\n", a, b, c, d);
    return 0;
}

b) Tipuri de date derivate

- Structuri (`struct`)

- Uniuni (`union`)

- Enumerări (`enum`)

- Pointeri (`*`)

6. Instrucțiuni în C

Limbajul C include instrucțiuni de control al fluxului programului, cum ar fi condiționale și bucle.

a) Instrucțiuni Condiționale

Instrucțiunile `if-else` și `switch` sunt utilizate pentru a controla execuția unui program în funcție de condiții logice.

#include <stdio.h>
int main() {
    int numar = 5;
    if (numar > 0) {
        printf("Numarul este pozitiv\n");
    } else {
        printf("Numarul nu este pozitiv\n");
    }
    return 0;
}

Instrucțiunea `switch` este utilizată pentru a gestiona multiple cazuri.

int main() {
    int optiune = 2;
    switch (optiune) {
        case 1: printf("Ai ales 1\n"); break;
        case 2: printf("Ai ales 2\n"); break;
        default: printf("Opțiune invalidă\n");
    }
    return 0;
}

b) Instrucțiuni de Repetiție (Bucle)

Buclele `for`, `while` și `do-while` sunt utilizate pentru a repeta execuția unor instrucțiuni.

int i;
for (i = 0; i < 5; i++) {
    printf("Iteratia %d\n", i);
}
int i = 0;
while (i < 5) {
    printf("Iteratia %d\n", i);
    i++;
}
int i = 0;
do {
    printf("Iteratia %d\n", i);
    i++;
} while (i < 5);

7. Structura unui Program Simplu în C

#include <stdio.h>
int main() {
    printf("Hello, World!\n");
    return 0;
}

Resurse suplimentare: