PC Laborator 11: Diferență între versiuni

De la WikiLabs
Jump to navigationJump to search
Linia 127: Linia 127:
     int value;
     int value;
     char string[4];
     char string[4];
    short shorts[2];
};
};


Linia 134: Linia 135:
     * Codurile ascii pentru c, a, si l, in baza 16 sunt:
     * Codurile ascii pentru c, a, si l, in baza 16 sunt:
     * c = 0x63 a = 0x61 l = 0x6c iar terminatorul de string este 0x00.
     * c = 0x63 a = 0x61 l = 0x6c iar terminatorul de string este 0x00.
     * Ne asteptam ca value sa fie deci 0x006c6163 (conventia little endian*).
     * Ne asteptam ca value sa fie deci 0x006c6163 iar
    * shorts[0] = 0x6163 (primii doi bytes in ordine inversa)
    * shorts[1] = 0x006c (ultimii doi bytes in ordine inversa).
     */
     */
     strcpy(var.string, "cal");
     strcpy(var.string, "cal");
     printf("var.value = 0x%08x\n", var.value);
     printf("var.value = 0x%08x\n", var.value);
    printf("var.shorts[0] = 0x%04x\n", var.shorts[0]);
    printf("var.shorts[1] = 0x%04x\n", var.shorts[1]);
     return 0;
     return 0;
}
}
</syntaxhighlight>
</syntaxhighlight>
* https://en.wikipedia.org/wiki/Endianness#Little-endian
* https://en.wikipedia.org/wiki/Endianness#Little-endian

Versiunea de la data 16 decembrie 2015 19:12

Obiective

La sfârșitul acestui laborator studenții vor fi capabili:

  • să definească tipuri de date noi, de tip struct, union și enum;
  • să declare și să utilizele variabile de aceste tipuri în programe

Tipurile de date struct

Tipurile de date struct sunt utilizate pentru a agrega mai multe multe varibile care au sens împreună. De exemplu, dorim să stocăm informații despre o mașină, prin urmare avem nevoie să stocăm marca, modelul, anul de fabricație, numărul de înmatriculare, culoarea, etc. Putem în acest caz să definim o structură numită Masina care să stocheze aceste valori. Variabilele care aparțin unei structuri se numesc câmpuri ale structurii. Un exemplu:

struct Masina {
    char marca[100];
    char model[50];
    unsigned short anFabricatie;
    char numarInmatriculare[8];
    char culoare[10];
};

Câmpurile structurii Masina sunt: marca, model, anFabricatie, numarInmatriculare și culoare.

Atenție: Definiția unei structuri nu implică automat și existența unei variabile de tipul respectiv, așa cum definirea tipului de date int nu implică existența unei varibile de tip int.

Declararea unei variabile de tipul Masina se face exact ca declararea oricărei alte varibile, sub forma: <tip_data> <nume_variabila>, cu observația că tipul de dată va conține și cuvântul cheie struct, deci acesta va fi struct Masina:

struct Masina {
    char marca[100];
    char model[50];
    unsigned short anFabricatie;
    char numarInmatriculare[8];
    char culoare[10];
};

int main() {
    struct Masina masina;
    return 0;
}

Odată definită o variabilă de tip struct, operatorul folosit pentru a accesa câmpurile structurii este .:

#include <stdio.h>

struct Masina {
    char marca[100];
    char model[50];
    unsigned short anFabricatie;
    char numarInmatriculare[8];
    char culoare[10];
};

int main() {
    struct Masina masina;
    printf("Care este marca masinii? ");
    fgets(masina.marca, 100, stdin);
    printf("Care este modelul masinii? ");
    fgets(masina.model, 50, stdin);
    printf("Care este numarul de inmatriculare al masinii? ");
    fgets(masina.numarInmatriculare, 8, stdin);
    printf("Care este culoarea masinii? ");
    fgets(masina.culoare, 10, stdin);
    printf("Care este anul de fabricatie a masinii? ");
    scanf("%hu", &masina.anFabricatie);

    return 0;
}
 Observație: O structură poate avea câmpuri de orice tip, inclusiv de tipul altor structuri.

Un tip de dată de tip structură poate fi folosit ca orice alt tip de dată, spre exemplu pentru a crea vectori de acel tip, dar și pentru a defini funcții care au argumente sau întorc valori de acel tip:

#include <stdio.h>

struct Masina {
    char marca[100];
    char model[50];
    unsigned short anFabricatie;
    char numarInmatriculare[8];
    char culoare[10];
};

struct Masina citesteMasina() {
    struct Masina masina;
    printf("Care este marca masinii? ");
    fgets(masina.marca, 100, stdin);
    printf("Care este modelul masinii? ");
    fgets(masina.model, 50, stdin);
    printf("Care este numarul de inmatriculare al masinii? ");
    fgets(masina.numarInmatriculare, 8, stdin);
    printf("Care este culoarea masinii? ");
    fgets(masina.culoare, 10, stdin);
    printf("Care este anul de fabricatie a masinii? ");
    scanf("%hu", &masina.anFabricatie);
    return masina;
}

void afiseazaMasina(struct Masina masina){
    printf("Masina marca %s si modelul %s are numarul de inmatriculare "
            "%s, culoarea %s si a fost fabricata in anul %hu!\n",
            masina.marca, masina.model, masina.numarInmatriculare,
            masina.culoare, masina.anFabricatie);
}

int main() {
    struct Masina parcAuto[10];
    parcAuto[0] = citesteMasina();

    afiseazaMasina(parcAuto[0]);

    return 0;
}

Tipurile de date union

Spre deosebire de tipurile struct, unde câmpurile unei varibile de tip struct ocupă zone diferite de memorie, câmpurile dintr-un union sunt suprapuse și ocupă aceeași zonă de memorie. Astfel, dacă se scrie într-un câmp, citirea celorlalte câmpuri va dovedi că valoarea acestora s-a modificat:

#include <stdio.h>
#include <string.h>

union CharAndInt {
    int value;
    char string[4];
    short shorts[2];
};

int main() {
    union CharAndInt var;
    /*
     * Codurile ascii pentru c, a, si l, in baza 16 sunt:
     * c = 0x63 a = 0x61 l = 0x6c iar terminatorul de string este 0x00.
     * Ne asteptam ca value sa fie deci 0x006c6163 iar 
     * shorts[0] = 0x6163 (primii doi bytes in ordine inversa) 
     * shorts[1] = 0x006c (ultimii doi bytes in ordine inversa).
     */
    strcpy(var.string, "cal");
    printf("var.value = 0x%08x\n", var.value);
    printf("var.shorts[0] = 0x%04x\n", var.shorts[0]);
    printf("var.shorts[1] = 0x%04x\n", var.shorts[1]);
    return 0;
}

Tipurile de date enum

Exerciții