PCLP Laborator11: Parametrii liniei de comandă. Preprocesorul. Funcții cu număr variabil de parametri. Opțiuni de compilare

Obiective

În acest laborator vom studia:

De fiecare dată când uitați sa eliberați memoria sau să închideți un fișier, un ponei moare. Aveți grijă de ei!

Materiale utile

Exerciții

  1. Să se realizeze un program care să afișeze numărul și parametrii liniei de comandă primiți. Hint: Exemplul1

    # presupunem existența executabilului gigel
    
    $ ./gigel e pe val! _2020
    argc = 5
    
    argv[0] = ./gigel
    argv[1] = e
    argv[2] = pe
    argv[3] = val!
    argv[4] = _2020
    
  2. Scrieți un program C care primește argumente în linia de comandă. Acesta trebuie să respecte următoarele reguli:

    darius@pc:$ gcc gigel.c -o gigel
    
    $ ./gigel
    Gigele, cel putin doua!
    darius@pc:$ echo $?
    2
    
    $ ./gigel e
    Gigele, cel putin doua!
    darius@pc:$ echo $?
    2
    
    $ ./gigel e pe
    Gigele, da-mi numere naturale!
    darius@pc:$ echo $?
    255
    
    $ ./gigel 1 2
    1 2
    darius@pc:$ echo $?
    0
    
    darius@pc:$ ./gigel 20 10 234
    10 20 234
    darius@pc:$ echo $?
    0
    
    darius@pc:$ ./gigel -1 -2
    Gigele, da-mi numere naturale!
    darius@pc:$ echo $?
    255
    
  3. Realizați un macro SWAP(x, y).

    Hint: Puteți folosi sizeof pentru a determina câtă memorie este necesara pentru variabila de interschimbare. De asemenea, puteți consulta și Exemplul 5.

    void test_int() { // interschimbare variabile de tip int
        int xi = 2, yi = 3;
        printf("%d %d\n", xi, yi);
        SWAP(xi, yi);
        printf("%d %d\n", xi, yi);
    }
    
    void test_char() { // interschimbare variabile de tip char
        char xc = 'A', yc = 'B';
        printf("%c %c\n", xc, yc);
        SWAP(xc, yc);
        printf("%c %c\n", xc, yc);
    }
    
    void test_ptr() { // interschimbare variabile de tip char*
        char* xs = "GIGEL", *ys = "NOT GIGEL";
        printf("%s %s\n", xs, ys);
        SWAP(xs, ys);
        printf("%s %s\n", xs, ys);
    }
    
    void test_struct() { // interschimbare variabile de tip struct
        student_t xstud, ystud;
        // citire xstud, ystud
        // afisare xstud, ystud
        SWAP(xstud, ystud);
        // afisare xstud, ystud
    }
    
  4. Modificați programul de la exercițiul 2 astfel încât dacă la compilare este definit un anumit simbol, lista va fi sortată crescător sau descrescător.

    Folosiți o directivă #error pentru a preveni compilarea programului dacă niciunul dintre simboluri nu este definit.

    Hint: Pentru acest exercițiu, s-ar putea să vă fie utile directivele #ifdef sau #ifndef.

    # daca nu se defineste un simbol, programul nu va compila
    darius@pc:$ gcc gigel.c -o gigel
    gigel.c: In function 'cmp':
    gigel.c:21:3: error: #error "Please define SORT_ASC or SORT_DESC"
    21 |  #error "Please define SORT_ASC or SORT_DESC"
        |   ^~~~~
    
    # daca se defineste SORT_ASC, programul va compila
    darius@pc:/darius/git/pc/lab/lab13$ gcc gigel.c -o gigel -DSORT_ASC
    # lista afisata este sortata crescator
    darius@pc:/darius/git/pc/lab/lab13$ ./gigel 30 20 10 20 30
    10 20 20 30 30
    
    # daca se defineste SORT_DESC, programul va compila
    darius@pc:/darius/git/pc/lab/lab13$ gcc gigel.c -o gigel -DSORT_DESC
    # lista afisata este sortata descrescator
    darius@pc:/darius/git/pc/lab/lab13$ ./gigel 30 20 10 20 30
    30 30 20 20 10
    
  5. Analizați împreună cu asistentul exemplul funcției listf din secțiunea de teorie de pe ocw.

    a. Rulați programul dat în exemplu.

    b. Modificați programul anterior a.i. să apelați funcția listf pentru a afișa valorile corespunzătoare pentru următoarele funcții matematice:

      i. sin

      ii. cos

      iii. exp

      iv. log10

      v. sqrt

      vi. fabs

ATENȚIE! Se dorește implementarea unei soluții modularizate, de aceea obligatoriu se va defini un vector de pointeri la funcții. Orice altă soluție nu se va puncta.

  1. Realizați implementarea funcției cu număr variabil de parametri numită gcd, care să permită aflarea celui mai mare divizor comun (gcd) al parametrilor dați (cel puțin două elemente care sunt numere naturale). Puteți presupune că lista se termină cu un număr negativ.

Hint: Exemplu 8 din teoria indicată de pe ocw.

Exemplu:

printf("%d\n", gcd(5, 10, -1));
// va printa 5 pentru ca gcd(5, 10) = 5

printf("%d\n", gcd(5, 10, 2, 100, -1));
// va printa 1 pentru ca gcd(5, 10, 2, 100) = 1

printf("%d\n", gcd(500, 10, 25, 75, -1));
// va printa 5 pentru ca gcd(500, 10, 25, 75) = 5

printf("%d\n", gcd(1024, 48, 64, 256, 2048, -1));
// va printa 16 pentru ca gcd(1024, 48, 64, 256, 2048) = 16

Problemset (extra)

Vă propunem să lucrați acasă probleme din PCLP Laborator11: Problemset (extra).