OSNOVA: a)Struktury b)Unie c)Výčtový typ d)Dynamické proměnné – úvod e)Příklady Jiří Šebesta Ústav radioelektroniky, FEKT VUT v Brně Počítače a programování 1 pro obor EST BPC1E PŘEDNÁŠKA 9
Struktury (1/5) Struktura reprezentuje množinu proměnných sestávající z polo- žek různých typů zapouzdřené do jednoho typu typedef struct friends // my girlfriend { char fname[20]; // her first name char sname[20]; // her surrname int age; // her age char phone[20]; // her phone number } T_friend; Deklarace typu struktura identifikátor typu struktury množina položek pojmenování struktury
Struktury (2/5) Struktura v paměti typedef struct friends { char fname[20]; char sname[20]; int age; char phone[20]; } T_friend; T_friend Arnold; proměnná typu struktury friends
Struktury (3/5) int main(void) { T_friend baby; strcpy(baby.fname, "Anna\0"); strcpy(baby.sname, "Novakova\0"); baby.age = 16; strcpy(baby.phone, " \0"); printf(" %s %s - %d let - tel.: %s", baby.fname, baby.sname, baby.age, baby.phone); getchar(); return 0; } Přístup k položce struktury: Příklad: BPC1E_Ex72.c proměnn á typu struktury položka struktury
dgf Struktury (4/5) typedef struct date // date { int year; // year int month; // month int day; // day } T_date; typedef struct drivelog // drive log book { char driver[20]; // name char in_city[20];// initial city char en_city[20];// ending city T_date in_date; // initial date T_date en_date; // ending date int dist; // distance int in_tacho; // initial st. of tacho. int en_tacho; // ending st. of tacho. } T_drivelog; Struktura ve struktuře:
Struktury (5/5) T_drivelog toyota020, toyota021; strcpy(toyota020.driver, "John"); toyota020.in_date.year = 2011; toyota020.in_tacho = 53210; toyota020.en_tacho = 53372; toyota020.dist = toyota020.en_tacho-toyota020.in_tacho; strcpy(toyota021.driver, "Judith"); strcpy(toyota021.in_city, toyota020.en_city); toyota021.in_tacho = toyota020.en_tacho; toyota021.en_tacho = 53712; toyota021.dist = toyota021.en_tacho-toyota021.in_tacho; Manipulace s položkami struktury: Příklad: BPC1E_Ex73.c
Unie (1/3) Unie: do jedn é proměnn é lze ukl á dat hodnoty různých typů (vyhrazeno společn é m í sto v paměti) union u1 {int i; double d; char c;} U = {'u'}; jmenovka unie seznam složek unie proměnná typu unie Velikost paměti alokované pro unii dána velikostí největší položky (v našem případě 8 bytů pro položku typu double ) STRUKTURA: int a double a char UNIE: int nebo double nebo char
dgf Unie (2/3) typedef union id // ID of item { int id_num; // numerical ID char id_str[10]; // textual ID } T_id; int main(void) { char input_id[10]; int n, t; printf("\n\nInsert ID: "); gets(input_id);// get string from stdin … Deklarace unie identifikátor typu
dgf Unie (3/3) t=0; // test if at least char is not digit for(n=0; input_id[n]!='\0'; n++) if(input_id[n] '9') t=1; // t=0 input_id is a number, t=1 input_id is a string if(t==0)// input_id is a number { item.id_num=atol(input_id); printf("ID contents a number: %d\n", item.id_num); } else// input_id is a string { strcpy(item.id_str, input_id); printf("ID contents a string: %s\n", item.id_str); } Příklad: BPC1E_Ex74.c
dgf Výčtový typ (1/3) Výčtový (enumerativní) typ enum reprezentuje prvkově omezenou množinu symbolických konstant se striktně definovanými celočíselnými hodnotami enum cards {seven, eight, nine, face_card, ace} set_1, set_2; enum cards {seven=7, eight, nine, face_card=20, ace=30} set_1, set_2; Způsob deklarace s automa- tickým přidělením hodnot : identifikátor výčtového typu proměnná daného typu symbolická jména konstant Způsob deklarace s vlastní definic hodnot symbol. konstant :
Výčtový typ (2/3) Operace nad enumerativn í m typem: – pouze přiřazen í !!! enum cards {seven=7, eight, nine, face_card=20, ace=30} set_1, set_2; set_1 = nine; set_2 = 8; // nelze, 8 není enumerátor set_1 -=2; // nelze int num = seven; // dojde k přetypování enumerátoru seven na int
Výčtový typ (3/3) enum zodiac {aries,taurus,gemini,cancer,leo,virgo, libra, scorpio, sagittarius, capricorn, …} eva; eva = virgo; switch(eva) { case aries: printf("She is hard-headed"); break; case taurus: printf("She is reserved"); break; case gemini: printf("She is friendly"); break; case cancer: printf("She is anxious"); break; case leo: printf("She is bossy"); break; case virgo: printf("She is trusty"); break; case libra: printf("She is shaky"); break; … } Př í klad: BPC1E_Ex75.c
Dynamické proměnné – úvod (1/3) Statick á proměnn á : – alokace paměťov é ho m í sta při spu š těn í programu – uvolněn í paměti při ukončen í programu Dynamick á proměnn á : – ř í zen á alokace paměti při běhu programu pomoc í funkce malloc() v C – ř í zen é uvolněn í paměti při běhu programu pomoc í funkce free() v C
Dynamické proměnné – úvod (2/3) Dynamick á proměnn á aplikace: –v běhu programu lze vyhradit a naopak zase uvolnit paměťový prostor –vhodn é pro vět ší bloky dat (např. velk á pole), kter é jsou dočasn é (např. mezivýsledky, kter é již nebudou d á le potřeba) –pr á ce s předem nezn á mou velikost í pole, u statick é proměnn é mus í me vyhradit prostor pro nejhor ší př í pad (max. velikost), např. double x[10000], pak je paměť trvale vyhrazena (dan é funkci)
Dynamické proměnné – úvod (3/3) #include int main(void) { double *x, y; x=(double*)malloc(sizeof(double)); *x=3.14; y=*x; free(x); printf("Ludolf's number: %f", y); printf("Ludolf's number: %f", *x); //free(x); getchar(); return 0; } pr á zdn á adresa pr á zdn á proměnn á void *malloc(size_t size) přetypov á n í uvolněn í m í sta v paměti kam ukazuje x na toto m í sto v paměti ukazuje x vyhrazen í m í sta v paměti o velikosti double Př í klad: BPC1E_Ex76.c
Příklady (1/6) Př. Vytvořte program, který bude pracovat jako datab á ze auto- mobilů. Každ é auto je pops á no značkou a rokem výroby. Ú daje o autech jsou ukl á d á ny do dynamických proměnných, ukazatel é jsou ukl á d á ny do pole. Přid á n í je aktivov á no kl á vesou A, maz á n í ú dajů kl á vesou D, program je ukončen stiskem Q. V datab á zi mus í zůstat nejm é ně jeden záznam.
dgf Příklady (2/6) Definice struktury pro záznam auta car a deklarace pole ukazatelů na 20 záznamů o autech *my_cars[20] jako globální proměnná, v globální proměnné cnt se udržuje počet naplněných záznamů o autech #include typedef struct car // structure for record of car { char type[10]; int year; } T_car; T_car *my_cars[20]; // ptrs. to cars - global int cnt=0; // recorded cars - global
dgf Příklady (3/6) Funkce pro přidání auta Funkce pro zobrazení vymazaného auta void addcar(char *atype, int ayear) { T_car *car; // pointer to a car car=(T_car*)malloc(sizeof(T_car)); strcpy(car->type, atype); // notation 1 (*car).year=ayear; // notation 2 my_cars[cnt++]=car; } void showdelcar(void) { printf("type: %s\n", my_cars[cnt]->type); printf("year: %d\n", my_cars[cnt]->year); }
void erasecar(void) { if(cnt>1) // if at least two cars { cnt--; // one car to be removed showdelcar(); // print the removed car free(my_cars[cnt]); // delete last } else printf("All cars can’t be deleted"); } Příklady (4/6) Funkce pro mazání auta
dgf int main(void) { char cmd, my_type[12]; int my_year; printf("\nA: Add, D: Delete, Q: Quit\n"); scanf("%c", &cmd); fflush( stdin); while(!(cmd=='Q'||cmd= 'q')) { if(cmd=='A'||cmd=='a') { printf("\ntype : "); scanf("%s", &my_type); fflush(stdin); printf("\nyear : "); scanf("%d", &my_year); fflush(stdin); add(my_type, my_year); } Příklady (5/6) Hlavn í funkce - zač á tek
if(cmd=='D'||cmd=='d') erasecar(); printf("\nA: Add, D: Delete, Q: Quit"); scanf("%c", &cmd); fflush(stdin); } return 0; } Příklady (6/6) Hlavní funkce - konec Př í klad: BPC1E_Ex77.c
Téma následující přednášky DĚKUJI ZA POZORNOST – Programování se soubory – Záloha databáze v souboru – Příklady