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.