Permalänk

Varför används pekare i C?

Jag har inte förstått än varför man ska använda pekare. Jag stötte på det problemet och jag valde struct istället för pekare när jag skulle retuera två variabler från en funktion.

Som jag har fattat pekare så kan man kolla vart t.ex int a = 2; ligger någonstans i minnet. Vet man adressen dit så kan man, oavset vart man står i tråden, plocka fram värdet igen.

[size="1"]Skickades från [url]m.sweclockers.com[/urlsize]

Permalänk
Medlem

När du returnerar en strut sa maste kompilatorn göra en kopia av structen när du gör return, detta betyder att du maste kopiera 2*4bytes=8bytes. Returnerar du en pekare sa kopieras enbart pekaren pa 4bytes(32bit=4bytes). Sa det är snabbare och allokerar mindre minne.

Just i detta fall är det kanske inte signifikant och kompilatorn gör en hel del magi i bakgrunden, men det är det enkla raka svaret.

Pekare känns kanske märkligt i början men när du har arbetat en del med dem kommer du fraga varför andra sprak inte har dem

http://en.wikipedia.org/wiki/Memory_management
http://en.wikipedia.org/wiki/C_dynamic_memory_allocation

Permalänk

Jaha. Så båda fungerar exakt lika bra, men pekare drar mindre minne, men man behöver skriva lite extra?

Permalänk
Medlem

Jag hade nog lagt fokus på att lära mig pekare om jag vore du, kommer du ha stor nytta av sen

Visa signatur

Fractal Design Node 304 -> ASUS ROG STRIX Z370-I GAMING ->i5 8600K -> be quiet! Pure Rock -> MSI GeForce RTX 4070 VENTUS 2X E 12G OC -> Corsair Vengeance LPX 3200 32GB -> Seasonic FOCUS Plus 650W Gold -> Samsung 960 EVO 500GB -> 2 * Western Digital Black 2 TB -> Samsung 850 EVO Basic SSD 500GB

Permalänk

Du använder som nämt innan pekare för det är mer dynamiskt och använder även oftast mindre minne. Det är oftast inte mycket mer att skriva, dock blir det lite mer att tänka på med tilldelningar, delete och allt annat som följer med

Det finns även fördelar när man ska optimera koden så den kan köras snabbare, men det är nog lite tid innan du kommer dit ^^

Permalänk
Medlem

Välj den väg som passar dig och vad du vill uppna.

Ett tips är att kombinationen med pekare och struct är riktigt, riktigt grym.

typedef struct { int op1; int op2; int res; } addStructT; int addition( addStructT *fubar ) { fubar->res = fubar->op1+fubar->op2; if( 0<=fubar->res ) return 1; else return 0; } int main() { addStructT fubar; fubar.op1 = 1; fubar.op2 = 1; if ( addition(&fubar) ) printf("positive sum: %i",fubar->res); else printf("negative sum: %i",fubar->res); return 0; }

strukturen ovan allokeras endast en gang, och endast en pekare är kopierad till funktionen. sa funktionen arbetar direkt i variablerna i main. man anvnder ofta return värdet som en status variable.

Permalänk

Så struct är sämre än pekare?

Permalänk
Medlem

En pekare är adressen till en variabel och inte en struct.

Det är rätt snajdigt att använda pekare när man ska spara och läsa saker i EEPROM t.ex.

Visa signatur

Ryzen 9 5950X, 32GB 3600MHz CL16, SN850 500GB SN750 2TB, B550 ROG, 3090 24 GB
Har haft dessa GPUer: Tseng ET6000, Matrox M3D, 3DFX Voodoo 1-3, nVidia Riva 128, TNT, TNT2, Geforce 256 SDR+DDR, Geforce 2mx, 3, GT 8600m, GTX460 SLI, GTX580, GTX670 SLI, 1080 ti, 2080 ti, 3090 AMD Radeon 9200, 4850 CF, 6950@70, 6870 CF, 7850 CF, R9 390, R9 Nano, Vega 64, RX 6800 XT
Lista beg. priser GPUer ESD for dummies

Permalänk
Skrivet av exodeus:

Välj den väg som passar dig och vad du vill uppna.

Ett tips är att kombinationen med pekare och struct är riktigt, riktigt grym.

typedef struct { int op1; int op2; int res; } addStructT; int addition( addStructT *fubar ) { fubar->res = fubar->op1+fubar->op2; if( 0<=fubar->res ) return 1; else return 0; } int main() { addStructT fubar; fubar.op1 = 1; fubar.op2 = 1; if ( addition(&fubar) ) printf("positive sum: %i",fubar->res); else printf("negative sum: %i",fubar->res); return 0; }

strukturen ovan allokeras endast en gang, och endast en pekare är kopierad till funktionen. sa funktionen arbetar direkt i variablerna i main. man anvnder ofta return värdet som en status variable.

Så den kan lagra många värden utan att deklarera mer än två variabler typ?
Förstog inte riktigt vad koden gjorde.

Permalänk
Inaktiv

Du tycks blanda ihop struct/class med pekare.
En pekare är ingen struct, en pekare är endast en adress till någon variabel i datorns minne. En pekare måste precis som alla andra variabler ha en typ, denna typ kan även vara en struct.

Det finns många fördelar med pekare, en av dessa är snabbare kod.

Du bör lära dig pekare om du vill arbeta med programmering i framtiden.

Permalänk
Medlem
Skrivet av anon120994:

En pekare måste precis som alla andra variabler ha en typ, denna typ kan även vara en struct.

Vilken typ har en void* ?

Permalänk
Hedersmedlem
Skrivet av Dalton Sleeper:

Vilken typ har en void* ?

En generell typ?

Jag skulle säga att en pekare innehåller en adress, pekaren är dock aningen värdelös om man inte vet vad den pekar på. Därför måste man säga att pekaren pekare på en char-array till exempel. Det gör att kompilator vet när man skriver mCharArray[3] så behöver den gå sizeof(char)*3 steg från adressen som pekaren mCharArray håller. En char är ju bara en byte stor. Hade pekaren istället varit för en int-array så hade den behövt gå sizeof(int)*3 där int kanske är 4 bytes stora. Hade pekaren varit av char-typ när du borde använda int kommer du få ut helt fel värden.

Inom pthreads när man skapar nya trådar så skickar man med en funktionspekare för koden som ska köras samt en void-pekare för att få med ett argument till den nya tråden. Då är det smidigt att stoppa en hel hop med argument i en struct och låta void-pekaren peka på sin struct.

Åh, det finns så mycket pekare används för.

Permalänk

Om jag vet adressen till en variabel. Det betyder att jag kan stå vart som helst i tråden, t.ex i ny funktion, och använda mig av variabeln igenom att gå till adressen?

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av heretic16:

Om jag vet adressen till en variabel. Det betyder att jag kan stå vart som helst i tråden, t.ex i ny funktion, och använda mig av variabeln igenom att gå till adressen?

Skickades från m.sweclockers.com

Ja, det kan du göra så länge variabeln fortfarande existerar. Det kan bli problem om du t.ex. använder en pekare till en lokal variabel vars funktion den existerar inom har returnerat (om variabeln inte är deklarerad som static).

Permalänk
Medlem

konceptet med pekare ligger nära hur en CPU fungerar internt med sina adressregister etc. Så även om det verkar lite flummigt så är det precis tvärtom, det är programmering som ligger mkt nära assembler.

Permalänk
Datavetare
Skrivet av Dalton Sleeper:

Vilken typ har en void* ?

Det är en pekare till en minnesposition, inget mer.

Just void* har en speciell status i C då det är alltid tillåtet att använda en variabel av typen void* som både lvalue och rvalue så länge som den andra sidan är en pekare till vilken typ som helst (inklusive void).

Utan denna regel skulle det bli rätt drygt att använda anrop som malloc()/free()/memcpy() etc då man skulle vara tvungen att göra explicita casts.

Visa signatur

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

Permalänk
Datavetare
Skrivet av anon120994:

Du tycks blanda ihop struct/class med pekare.
En pekare är ingen struct, en pekare är endast en adress till någon variabel i datorns minne. En pekare måste precis som alla andra variabler ha en typ, denna typ kan även vara en struct.

Det finns många fördelar med pekare, en av dessa är snabbare kod.

Du bör lära dig pekare om du vill arbeta med programmering i framtiden.

Inte nödvändigtvis sant. ABI (application binary interface) för x86_64 på Linux, Windows och OSX specificerar att strukturer som skickas "by value" till funktioner skickas rent tekniskt som en dold pekare.

Om strukturen är lika med eller mindre än 16 bytes (två 64-bitars register) så är det faktiskt snabbare att skicka den "by value" i stället för att skicka den som pekare då innehållet skickas direkt i register i det första fallet.

Väldigt överkurs, men det finns lägen när "by value" är bättre även i C. I senaste C++ standarden så är det i princip alltid både enklast och mest effektivt att skicka "by value" då standarden kräver att detta ska vara effektivt (sköts via en detalj som kallas "move semantics / move constructor").

Visa signatur

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

Permalänk
Medlem
Skrivet av Yoshman:

Det är en pekare till en minnesposition, inget mer.

Det var lite det jag ville få ur honom, då det skrevs att alla pekare har en "typ".

Permalänk
Datavetare
Skrivet av Dalton Sleeper:

Det var lite det jag ville få ur honom, då det skrevs att alla pekare har en "typ".

void representerar avsaknaden av typ, void* är en definitivt en typ: pekare till en minnesposition.

Visa signatur

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