C: Ge exempel på vad man kan använda struct till?

Permalänk

C: Ge exempel på vad man kan använda struct till?

Hej!

Kan någon ge enkla exempler vad man kan använda struct till i C?
Varför måste typedef användas i struct för? Vad gör den?

Är struct ungefär som klasser?

Permalänk
Permalänk

Det är så opedagotiskt förklarat på wikipedia.
Jag har ändå läst denna, men det gav inte så mycket.

Jag vet om att man kan ha variabler i en struct....men till vilken nytta?
Kan man inte bara skriva ut variablerna som dom är?

Permalänk
Skrivet av heretic16:

Det är så opedagotiskt förklarat på wikipedia.
Jag har ändå läst denna, men det gav inte så mycket.

Jag vet om att man kan ha variabler i en struct....men till vilken nytta?
Kan man inte bara skriva ut variablerna som dom är?

Säg att du gör ett multiplayer spel och ska spara alla spelare i minnet. Då är det rätt bra att kunna stoppa undan dem i en struct så att man inte har en massa listor liggandes exempel:

int *x, *y; char **name;

Blir då istället:

struct player { int x, y; char *name; } struct player *players;

Och man kan enkelt skicka över datan mellan olika funktioner:

void do_player_stuff (struct player player) { player.x += 1; player.y -= 1; printf("%s walked one step north, and one step east.", player.name); }

Istället för:

void do_player_stuff (x, y, name) { x += 1; y += 1; printf("%s walked one step north, and one step east.", name); }

Det kanske är svårt att se nyttan när det bara är så få variabler, men när det blir mer och mer avancerat så är det väldigt skönt att kunna göra såhär. En annan sak man också vinner på är att koden blir enklare att förstå. Den förklarar sig själv på ett helt annat sätt. Ungefär samma anledning som man gör typdefs på enkla datatyper (inte enbart därför, men det ligger en del i det.)

C gurus får gärna se över ifall jag sagt något dumt

Permalänk
Medlem
Skrivet av heretic16:

Det är så opedagotiskt förklarat på wikipedia.
Jag har ändå läst denna, men det gav inte så mycket.

Jag vet om att man kan ha variabler i en struct....men till vilken nytta?
Kan man inte bara skriva ut variablerna som dom är?

Tycker det var väldigt pedagogiskt förklarat och med många exempel. En struct är som en resväska: tänk hur rörigt det skulle bli att åka på semester utan en sån.

Skickades från m.sweclockers.com

Visa signatur

Kom-pa-TI-bilitet

Permalänk

Struct är egentligen nästan som det låter strukturera upp data, du skapar en medveten relation mellan olika variabler. T.ex. har du en

struct WOW_Login_Info { char userName[200]; char Password[64]; int64 UniquePlayerID };

Tar du en funktion som har WOW_Login_Info, så är det iaf ett medhjälp till att snabbt få en uppfattning om vad som verkligen händer (tillsammans med funktionsnamnet och eventuellt andra parametrar). I regel blir koden lättare att följa på sådana sätt (t.ex. blir det det kortare och snabbare att skriva input parametrar till funktioner, speciellt om det är en funktion du använder ofta). Det är klart att du alltid kan skippa struct helt om du verkligen vill, men tänk om du vill lägga in en variabel till om Login informationen till wow, t.ex. int64 VariablePlayerID, har du då det i structar så är det bara att deklarera variabeln i structen, och alla funktioner får variabeln också.

struct WOW_Login_Info { char userName[200]; char Password[64]; int64 UniquePlayerID; int64 VariablePlayerID; };

Om du har skrivit manuellt in parametrar överallt, så är det bara att göra det igen varje gång du gör en förändring. Detta är relevant speciellt om det flera funktioner utnyttjar datan, tänk dig om t.ex. 10-20 eller kanske ännu mer funktioner använder den? Detta är bara ett exempel på en relativt liten förändring som kan ske. Ett större projekt blir helt enkelt mer lättskött.

@martinrlilja i regel brukar man skicka som pekare (eller referens) för att undvika onödig datakopiering beroende på datatyp.

Visa signatur

| Silverstone raven rv02 | Intel Core i7 920 @ 3.5ghz + Corsair H50 | Kingston DDR3 HyperX 1333MHz 6x2GB | XFX Radeon 6870 | ASUS P6T SE | Chieftec Super Series 750W |

Permalänk
Datavetare

Du har ju fått flera exempel på hur man kan använda en struct redan, så antar att den delen är utredd.

Att definiera en struktur gör med

struct <namn> { /* medlemmar */ };

d.v.s typedef behövs inte alls.

typedef är egentligen ett dåligt namn på vad detta nyckelord gör i C då det inte skapar nya typer utan ger alias till existerande typer.

typedef struct <namn> { ... } <typ_namn>;

är bara en tillåten sammanslagning av två separata uttryck

  1. definitionen av den nya typen "struct <namn>"

  2. ge "struct <namn>" aliaset <typ_namn>

Man skulle även kunna skriva det som två C-uttryck

struct <namn> { ... }; typedef struct <namn> <typ_namn>;

typedef kan ju även användas på primitiva typer, något som görs väldigt frekvent. Ett exempel väldigt viktigt sådant fall är definition av heltalstyper med en specifik kapacitet. I C säger bara standarden att char är den minsta adresserbara enheten, det finns inget som säger att det ska vara 8-bitar! Sedan säger man att sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long). Sedan C99 finns standardtyper med specifik storlek och här används typedef för att rent logiskt skapa en ny typ (men rent formell sett ur C-kompilators perspektiv är det fortfarande bara ett alias).

För att definiera typen int32_t så gör man typiskt detta på en 32/64-bitars CPU

typedef int int32_t;

medan man måste använda denna definition på en 16-bitars CPU där int kommer vara 16-bitar

typedef long int32_t;

Är struct ungefär som en klass? Båda definierar en ny typ, men i en klass har man klistrat ihop funktioner vars beteende typiskt påverkas av det aktuella tillståndet av den instans av typen som är associerad med anropet, en C struct har ingen direkt motsvarighet. I C++ är class och struct exakt samma sak förutom att en klass definierad med struct har public som förval för medlemmar och en klass definierad med class har private som förval.

Så svaret kan vara både ja och nej lite beroende på hur man ser på det
I praktiken så är svaret också både ja och nej, ibland använder C-programmerare struct exakt som en C++/C#/Java-programmerare använder klasser. Men OOD är långt ifrån det enda sätt att strukturera ett problem och väldigt många problem passar faktiskt rätt illa för OOP och i dessa lägen använder man struct som just bara en typ utan att ha funktioner som är hårt associerade med en viss instans (ungefär som att enbart programmera med statiskt metoder i Java/C#).

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk

Så man kan säga istället för att skapa variabler här och där, så kan man ställa variablerna på ett enda ställe där man kan komma åt dom oavsett vart man är i koden?

Permalänk
Datavetare
Skrivet av heretic16:

Så man kan säga istället för att skapa variabler här och där, så kan man ställa variablerna på ett enda ställe där man kan komma åt dom oavsett vart man är i koden?

Det är en trevlig bieffekt men inte huvudmålet.

"Struktur" kanske är en dåligt svenskt namn, tänk "formulär" i stället. En struktur en specifikation på vad som ska finnas i ett specifikt formulär. Det finns olika formulär (olika "struct") för olika ändamål. Ett viss specifik formulär innehåller alltid samma fält, men ett ifyllt sådan formulär kan ha olika information i fälten.

Det är fullt möjligt att spara samma information direkt på ett blankt papper, men ett förtryckt formulär gör det både enklare för den som ska fylla i formuläret och framförallt blir det enklare för den som ska tolka informationen. En "struct" är samma sak för programmeraren, informationen som sådan skulle kunna sparas på en lång rad olika sätt men en "struct" ger en specifik mall för informationen som då gör det enklare för delar att skapa och tolka informationen.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Skrivet av Yoshman:

Det är en trevlig bieffekt men inte huvudmålet.

"Struktur" kanske är en dåligt svenskt namn, tänk "formulär" i stället. En struktur en specifikation på vad som ska finnas i ett specifikt formulär. Det finns olika formulär (olika "struct") för olika ändamål. Ett viss specifik formulär innehåller alltid samma fält, men ett ifyllt sådan formulär kan ha olika information i fälten.

Det är fullt möjligt att spara samma information direkt på ett blankt papper, men ett förtryckt formulär gör det både enklare för den som ska fylla i formuläret och framförallt blir det enklare för den som ska tolka informationen. En "struct" är samma sak för programmeraren, informationen som sådan skulle kunna sparas på en lång rad olika sätt men en "struct" ger en specifik mall för informationen som då gör det enklare för delar att skapa och tolka informationen.

Alltså kan vi säga att om man vill komma åt variabeln int så kan man skriva

struct Foo { int x; } void funktion() { struct Foo k; k.x = 6; print("%i", k.x); } int main() { struct Foo f; f.x = 5; funktion(); print("%i", fx); } ==> 65

Här skriver jag f.x = 5 och sen skriver jag k.x = 6.
Dock så kommer f.x och k.x lagras i samma int?
Kan man säga så?

Permalänk
Medlem
Skrivet av heretic16:

Alltså kan vi säga att om man vill komma åt variabeln int så kan man skriva

struct Foo { int x; } void funktion() { struct Foo k; k.x = 6; print("%i", k.x); } int main() { struct Foo f; f.x = 5; funktion(); print("%i", fx); } ==> 65

Här skriver jag f.x = 5 och sen skriver jag k.x = 6.
Dock så kommer f.x och k.x lagras i samma int?
Kan man säga så?

Nej. Du deklarerar ju f och k separat samt i olika scopes (http://www.tutorialspoint.com/cprogramming/c_scope_rules.htm) så de har inget med varandr aatt göra annat än att de användes sig av strukturen Foo.

Permalänk

Det fina med strukturer är det är enkelt att i efterhand lägga till eller ta bort variabler.

Permalänk
Skrivet av iXam:

Nej. Du deklarerar ju f och k separat samt i olika scopes (http://www.tutorialspoint.com/cprogramming/c_scope_rules.htm) så de har inget med varandr aatt göra annat än att de användes sig av strukturen Foo.

Så jag kan inte göra två stycken "saker" som håller variabler av struct Foo ?

Har jag en gång gjort struct Foo f så kan jag inte göra struct Foo k ?

EDIT:
Eller säger vi helt enkelt att struct är ett paket med variabler där man lätt kan skriva och läsa till?

Permalänk
Skrivet av heretic16:

Så jag kan inte göra två stycken "saker" som håller variabler av struct Foo ?

Har jag en gång gjort struct Foo f så kan jag inte göra struct Foo k ?

Jodå det kan du. Vad han poängterade (baserat på ditt tidigare inlägg som kanske inte var helt tydlig) var att deras innehåll lagras i var sin variabel, aldrig i samma. Se nedan,

Citat:

Här skriver jag f.x = 5 och sen skriver jag k.x = 6.
Dock så kommer f.x och k.x lagras i samma int?
Kan man säga så?

Ditt exempel ser rätt ut, men din förklaring stämmer ej. Du hämtar ut värdet med samma "namn" (x i det här fallet) men de lagras i var sin separat int.

En struct är i princip en samling variabler som ligger precis bredvid varandra i minnet. Skapar du två stycket int så hamnar de på helt olika ställen i minnet. Skapar du två stycken struct så får du två stycken block minnen som ligger på olika ställen i minnet medan variablerna från vardera struct ligger inom samma block.

Permalänk
Skrivet av Korkskruv:

Jodå det kan du. Vad han poängterade (baserat på ditt tidigare inlägg som kanske inte var helt tydlig) var att deras innehåll lagras i var sin variabel, aldrig i samma. Se nedan,

Ditt exempel ser rätt ut, men din förklaring stämmer ej. Du hämtar ut värdet med samma "namn" (x i det här fallet) men de lagras i var sin separat int.

En struct är i princip en samling variabler som ligger precis bredvid varandra i minnet. Skapar du två stycket int så hamnar de på helt olika ställen i minnet. Skapar du två stycken struct så får du två stycken block minnen som ligger på olika ställen i minnet medan variablerna från vardera struct ligger inom samma block.

Jag börjar förstå det här nu.
Vi säger vi helt enkelt att struct är ett paket med variabler där man lätt kan skriva och läsa till oavsett vart man är i koden, istället för att ha variablerna lite här och där?

Permalänk
Skrivet av heretic16:

Jag börjar förstå det här nu.
Vi säger vi helt enkelt att struct är ett paket med variabler där man lätt kan skriva och läsa till oavsett vart man är i koden, istället för att ha variablerna lite här och där?

Precis, och när man behöver lägga till fler egenskaper till paketet så gör man det på ett ställe och slipper därmed leta runt i koden för att skicka runt nya variabler en i taget.

Permalänk
Medlem
Skrivet av heretic16:

Jag börjar förstå det här nu.
Vi säger vi helt enkelt att struct är ett paket med variabler där man lätt kan skriva och läsa till oavsett vart man är i koden, istället för att ha variablerna lite här och där?

"oavsett vart man är i koden", nej. Så länge den inte är deklarerad för globalt scope.

Permalänk
Skrivet av iXam:

"oavsett vart man är i koden", nej. Så länge den inte är deklarerad för globalt scope.

Har skrivit en liten kod.

#include <stdio.h> #include <stdlib.h> struct bok { char namn[20]; int sidor; }; void bok1() { struct bok b; namn.a = "Andersson"; sidor.a = 20; } void bok2() { struct bok a; namn.b = "Gustavsson"; sidor.b = 50; } int main() { bok1(); bok2(); }

Så när jag använder mig av namn.b så är det "Gustavsson" och sidor.b så är det 50.
Samma sak när jag använder mig av namn.a så är det "Andersson" och sidor.a så är det 20.

Eller kanske tänkte fel nu?

Permalänk
Medlem
Skrivet av heretic16:

Har skrivit en liten kod.

#include <stdio.h> #include <stdlib.h> struct bok { char namn[20]; int sidor; }; void bok1() { struct bok b; namn.a = "Andersson"; sidor.a = 20; } void bok2() { struct bok a; namn.b = "Gustavsson"; sidor.b = 50; } int main() { bok1(); bok2(); }

Så när jag använder mig av namn.b så är det "Gustavsson" och sidor.b så är det 50.
Samma sak när jag använder mig av namn.a så är det "Andersson" och sidor.a så är det 20.

Eller kanske tänkte fel nu?

Jadu. Varken koden eller tankesättet är rätt.
Till att börja med så är syntaxen fel. Det ska vara "b.namn" och inte "namn.b".
Sen är ju a och b deklarerat (åter igen) i olika "scopes".
Så istället för att "spela lotto" när du programmerar så rekommenderar jag dig till att läsa på mer innan.

Permalänk
Medlem
Skrivet av heretic16:

Jag börjar förstå det här nu.
Vi säger vi helt enkelt att struct är ett paket med variabler där man lätt kan skriva och läsa till oavsett vart man är i koden, istället för att ha variablerna lite här och där?

Istället för att skicka en mängd värden till en funktion kan du skicka en struct-pekare till en funktion. Det är nästan alltid bättre att skicka värden till en funktion än att låta funktionen plocka värden från det globala scopet.

Dvs, istället för

int sum(int a, int b, int c, int d, int e) { return a + b + c + d + e; }

så kan du göra

typedef struct { int a; int b; int c; int d; int e; } Numbers; int sum(Numbers* n) { return n->a + n->b + n->c + n->d + n->e; }

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av iXam:

Jadu. Varken koden eller tankesättet är rätt.
Till att börja med så är syntaxen fel. Det ska vara "b.namn" och inte "namn.b".
Sen är ju a och b deklarerat (åter igen) i olika "scopes".
Så istället för att "spela lotto" när du programmerar så rekommenderar jag dig till att läsa på mer innan.

Ett tillägg är också att du inte kan tilldela en sträng till en char array efter dess deklaration, du måste använda dig av t.ex. strcpy.

char namn[4] = "Hej"; /* OK */ char namn2[4]; namn2 = "Hej"; /* Inte ok */ char namn3[4]; strcpy(namn3, "hej"); /* OK */