struct – egendefinierad typ struct LECTURE_TYPE { char teacher[99]; float lengthInMinutes; char type; /* L = lecture, E = exercise */ }; Vad är problemet? • Att kunna lagra data som avser flera olika egenskaper för en typ av objekt. – Man kan tänka sig att använda olika variabler: char brand[10]; int doors; char reg[7]; – Inte så bra; dessa variabler kommer ligga i samma hög som andra variabler: int loop,doors, x; char str[99],brand[10],c,reg[7]; Vad är problemet? • Om vi vill lagra många objekt av samma typ – ”Parallella” arrayer (gemensamt index) kaske? – Ex: bil-register med 100 bilar: char brand[100][10]; int doors[100]; char reg[100][7]; – Tilldelning av bil med index i: scanf(”%s”, brand[i]); scanf(”%d”, &doors[i]); scanf(”%s”, reg[i]); – ...ännu sämre Vad är problemet? • Om vi vill sortera listan av bilar? – Sortering kräver att data kopieras från en plats till en annan på något sätt så att den rätta ordningen erhålls – Varje gång data om en bil ska kopieras från en plats till en annan så måste en array i taget hanteras: strcpy(strbuf1, brand[i]); x = doors[i]; strcpy(strbuf2, reg[i]); ... – näst intill katastrof! Vi behöver något nytt! • Lösningen till problemet är just struct ! struct – egendefinierad typ • En struct innehåller valfritt många fält – Fält kallas ibland komponent eller medlem • Varje fält är av valfri typ ex: #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { .... struct – egendefinierad typ • En struct innehåller valfritt många fält – Fält kallas ibland komponent eller medlem • Varje fält är av valfri typ ex: #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { .... Ser ut som deklarationer av variabler men är inte det struct – egendefinierad typ • En struct innehåller valfritt många fält – Fält kallas ibland komponent eller medlem • Varje fält är av valfri typ ex: #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { .... Beskriver vilka delar som typen struct CAR består av struct – egendefinierad typ • En struct innehåller valfritt många fält – Fält kallas ibland komponent eller medlem • Varje fält är av valfri typ ex: #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { .... Hela detta är en definition av en ny typ! Namnet på den typen är struct CAR struct – egendefinierad typ • En struct innehåller valfritt många fält – Fält kallas ibland komponent eller medlem • Varje fält är av valfri typ ex: #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { .... Normalt vill man definiera en struct globalt (dvs utanför alla funktioner) Övning • Definiera en struct som passar till att representera ett rationellt tal. Låt det också finnas en tom mainfunktion. struct – ”container” (behållare) • En egendefinierad typ kan ses som ett sätt att hålla samman data som avser ett och samma object - som en behållare Deklaration av variabler #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { int array[20], i, n; struct CAR bil; ... bil är nu en variabel som kan tilldelas data. Typen är struct CAR. Storleken är (minst) 23 bytes. Den kan innehålla de data som vi tyckte att en bil ska kunna innehålla: brand, doors och reg Övning • Deklarera tre rationella tal i main-funktionen. Access av variabler #include <stdio.h> struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { int array[20], i, n; struct CAR bil; i = 0; bil.doors = 4; n = 42; Fältet doors i variabeln bil tilldelas värdet 4. Övriga fälts värden är odefinierade. Access av variabler struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { Då ett fält i en variabel väljs ut int array[20], i, n; (t.ex. bil.doors) så blir detta char buf[10]; uttryck i alla delar likvärdigt struct CAR bil; med en variabel av fältets typ i = 0; (t.ex. n i detta exempel). bil.doors = 4; n = 42; strcpy(buf, ”Kalle”); strcpy(bil.brand, ”Volvo”); strcpy(bil.reg, ”ABC123”); ... Initiering i deklaration struct CAR { char brand[10]; int doors; char reg[7]; }; Påminner om arrayers initiering int main(void) { int array[20], i, n; char buf[10]; struct CAR bil = {”Volvo”, 4, ”ABC123”}; ... Ett fält i taget • För arrayer kan bara ett element i taget användas • För structer är det på liknande sätt: ett element i taget struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { struct CAR bil1, bil2, bil3; bil1 = bil2 + bil3; printf(”%d\n”, bil1); FEL! Övning • Tilldela ett rationellt tal något värde i deklarationen. • Ge ett annat ett värde från användaren. • Tilldela det tredje produkten av de två första. ...med ett undantag • Tilldelning fungerar! struct CAR { char brand[10]; int doors; char reg[7]; }; int main(void) { struct CAR bil1={”Volvo”, 4, ”ABC123”}, bil2; bil2 = bil1; Funktioner och structer • Precis som vanliga variabler – Som inargument • void addAge(struct person employee, int age); – Som returvärde • struct person InitNewEmployee(void); • En struct innehåller flera värden!!!! Exempel struct + funktion #include <stdio.h> struct person { char namn[30]; int alder; int skostorlek; }; /* funktionsdeklaration */ struct person mataInPers(void); int main(void) { struct person mataInPers(void) { struct person a; char buf[100]; gets(a.namn); gets(buf); a.alder=atoi(buf); gets(buf); a.skostorlek=atoi(buf); struct person p; /* funktionsanrop */ p = mataInPers(); ... printf(”%s”,p.namn); } return a; Övning • Gör funktionen ”init_rational” som tar två heltal som indata och som returnerar ett rationellt tal vars delar består av funktionens indata • Gör funktionen ”mult_rational” som tar två rationella tal och returnerar ett trejde som är produkten av de två parametrarna • Gör funktionen ”print_rational” som skriver ut ett rationellt tal Arrayer av structer • Definition – struct verktygstyp { int pris; char elektrisk; }; char sort[20]; • Deklaration – struct verktygstyp verktyg[50]; • Tilldelning – strcpy(verktyg[5].sort, ”Borrmaskin”); – verktyg[5].pris =399; – verktyg[5].elektrisk =’j’; Pekare och structer struct meningtyp { char str[100]; int antal_ord; }; ... struct meningtyp *mp, mening; mp = &mening; • För att komma åt ett fält i en utpekad structvariabel måste pekaren avrefereras. Punktoperatorn har högre prioritet än avreferering så använd (): (*mp).antal_ord = 5; strcpy((*mp).str, ”Detta är en fin mening”); Alternativ syntax struct meningtyp { char str[100]; int antal_ord; }; ... struct meningtyp *mp, mening; mp = &mening; • Det finns en alternativ syntax som bara kan användas för kombinationen pekare och struct: mp­>antal_ord = 5; strcpy(mp­>str, ”Detta är en fin mening”); betyder samma (*p).field p­>field Exempel struct + funktion + pekare #include <stdio.h> struct person { char namn[30]; int alder; int skostorlek; }; /* funktionsdeklaration */ void mataInPers(struct person *p); void main(void) { void mataInPers(struct person *p) { char buf[100]; struct person p; gets(p->namn); gets(buf); p->alder=atoi(buf); gets(buf); p->skostorlek=atoi(buf); /* funktionsanrop */ mataInPers( &p); } printf(”%s”,p.namn); } Övning • Skriv ytterligare en funktion i ditt ”struct-program”: – Funktionen ber användaren skriva in ett rationellt tal – Parametern till funktionen är en pekare till ett rationellt tal – Om du har tid över: • En funktion som adderar två rationella tal, resultatet placeras i ett tredje. Alla tre talen accessas via pekare.