Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2016-06-05, 17:42
  #1
Medlem
Hej!

Jag har försökt lära mig det här med pekare, men inte lyckats få polletten att trilla ner riktigt. Jag skulle verkligen behöva ha någon som kan förklara för mig, riktigt pedagogiskt, på "for dummies"-nivå hur detta med pekare fungerar, för att jag ska kunna förstå detta.

Snälla, finns det någon vänlig själ här inne, som kan förklara för mig, så jag verkligen förstår?

Tack på förhand!
Citera
2016-06-05, 18:07
  #2
Medlem
Vad är det mer specifikt du inte förstår? Det är ju bara adresser till minne. Typ som adressen på din brevlåda.
Citera
2016-06-05, 18:13
  #3
Medlem
christerys avatar
Denna tyckte jag förklarade det bra, men du kanske får tänka till lite. http://www.cplusplus.com/doc/tutorial/pointers/

En pekare är bara nåt som vet om en adress, i en array vet den om var första elementet ligger och är det nu en char så kan man använda andra anrop för att skriva ut tills den hittar en char 0 tex.

Värdet av vad en pekare pekar på får ut med * operatorn, igen om den pekar på en sträng så får du bara ut första tecknet i strängen och inte hela, men då kan du öka på pekaren med ++ och skriva ut varje tecken tills du hittar ett \0

Då är det dags att sluta, allt efter det (jo du kan fortsätta) är nåt annat än det du lagrat i din char array.

Vill du veta adressen för en "vanlig" variabel använder du & istället, då kan du tilldela eller skicka en adress till en annan funktion eller en pekare.

Men tänk på det som en adress (till ett hus eller vad som nu passar), den talar inte om vad som finns i huset om du inte frågar med tex * operatorn.

EDIT: Säker på att det är C++ du pillar med? C har ju ovanan att använda pekare överallt.
__________________
Senast redigerad av christery 2016-06-05 kl. 18:18. Anledning: F tangenten bråkar.
Citera
2016-06-05, 19:41
  #4
Medlem
Citat:
Ursprungligen postat av Tiger-Lily
Hej!

Jag har försökt lära mig det här med pekare, men inte lyckats få polletten att trilla ner riktigt. Jag skulle verkligen behöva ha någon som kan förklara för mig, riktigt pedagogiskt, på "for dummies"-nivå hur detta med pekare fungerar, för att jag ska kunna förstå detta.

Snälla, finns det någon vänlig själ här inne, som kan förklara för mig, så jag verkligen förstår?

Tack på förhand!

https://books.google.se/books?id=WaY...st%20C&f=false Visserligen för C, men C++pekare fungerar nästan likadant.
Citera
2016-06-05, 20:06
  #5
Medlem
enowens avatar
Föreställ dig varje [ ] är ett skåp som inte innehåller någonting och varje skåp har ett nummer, från 1 till 10.

Kod:
[ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ]
 
1     2     3     4     5     6     7     8     9    10 

När du skapar en int, som exempel:

Kod:
int i 5

Så läggs siffran 10 in i ett tomt skåp, i det här fallet skåp nummer 1 som innehåller värdet 5:
Kod:
[5] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ]
 
1     2     3     4     5     6     7     8     9    10 

En pekare håller helt enkelt reda på adressen till ett skåp, se exemplet nedan:

Kod:
int i 5;
intpekare = &i

Detta placeras också in i ett skåp, om du tittar på skåp nummer två nu så innehåller den numret till skåp nummer 1:

Kod:
[5] - [1] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ]
 
1     2     3     4     5     6     7     8     9    10 

Om du väljer att skriva ut en pekare så skriver den helt enkelt ut värdet som finns i skåpet:

Kod:
std::cerr << pekare << std::endl;
//skriver ut: 1 

Om du dereferencerar en pekaren (genom att ha * innan namnet) så säger du istället, "värdet i mitt skåp är egentligen bara ett nummer till ett annat skåp, jag vill veta vad det skåpet har för värde":

Kod:
std::cerr << *pekare << std::endl;
//skriver ut: 5 

That's it. Det är vad en pekare är. Om du undrar varför man behöver detta överhuvudtaget så är anledningen följande:
Säg att du har en funktion som heter Add10():

Kod:
void Add10(int value)
{
    
value value+10;


Om du nu har en variabel som heter i och du vill plussa på 10 på den:

Kod:
int i 10;
Add10(i);
//resultat: i är fortfarande 10 

så kommer Add10 att skapa en kopia av variabeln i och slänga in det i ett tomt skåp och sedan plussa på 10 på den. När funktionen returneras så försvinner kopian och skåpet töms. Med andra ord kommer aldrig variabeln i att ändras. Detta kallas för pass-by-value!

Om du vill ändra originalet, med andra ord variabeln i så kan du skicka in numret till skåpet där i är placerad genom att ändra om Add10 signaturen till följande:

Kod:
void Add10(intvalue)
{
    *
value = *value+10;


Sedan kallar du på funktionen så här:

Kod:
int i 10;
Add10(&i);
//resultat: i är nu 20 

Det som händer nu är att så fort du kallar på Add10 och skickar in adressen till variabeln i så slängs den in i ett tomt skåp:

Kod:
// skåp 1 innehåller värdet för variabeln [b]i[/b] och nu läggs variabeln value till också i skåp nummer 2 och innehåller skåpnummer 1 som värde där i är placerad

[10] - [1] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ] - [ ]
 
1      2     3     4     5     6     7     8     9    10 

Du borde förstå vid de här laget varför du skriver *value = någonting; om inte, läs vidare:

Kod:
void Add10(intvalue) <----- När du anropar funktionen genom Add10(&iså skickar du in skåpsnumret som är 1:
{


Kod:
void Add10(intvalue)
{
    
value value+10//om du inte dereferencerar value så plussar du på 10 på 1, för value innehållet värdet 1 som är skåpsnumret.


men du är ju intresserad av att ändra värdet som skåpnumret refererar till och därav skriver du:

Kod:
void Add10(intvalue)
{
    *
value = *value+10;


Hoppas att du har fått ett litet hum om hur pekare fungerar. I c++ så har du referenser som du använder istället för pekare när det är möjligt och du kan göra många roliga grejer med just pekare. Fortsätt läsa så kommer resten att hamna på plats snart.
__________________
Senast redigerad av enowen 2016-06-05 kl. 20:34.
Citera
2016-06-06, 10:55
  #6
Medlem
Okej, jag har klurat på ett exempel, där jag har svårt att förstå hur jag ska använda pekare.

Säg att jag har en for-sats. for(int i = 0; i < 8; i++)

Detta är ju ett helt vanligt sätt att deklarera en for-sats.

Säg nu att jag vill göra detta med pekare. Det är här jag går bet, för jag förstår inte när, var hur, jag ska peka och vad som gör vad.

För att kunna använda pekare, måste jag ha något att peka mot. Dvs, jag måste fortfarande ha en int i = 0. Jag måste också ha en pekare, som pekar på int i = 0.

så:

int i = 0;
int *pekare = i;

Men sen då? Det är här jag faller platt. for(*pekare = i; *pekare < 8; *pekare++) ???
Citera
2016-06-06, 11:17
  #7
Medlem
Citat:
Ursprungligen postat av Tiger-Lily
Okej, jag har klurat på ett exempel, där jag har svårt att förstå hur jag ska använda pekare.

Säg att jag har en for-sats. for(int i = 0; i < 8; i++)

Detta är ju ett helt vanligt sätt att deklarera en for-sats.

Säg nu att jag vill göra detta med pekare. Det är här jag går bet, för jag förstår inte när, var hur, jag ska peka och vad som gör vad.

För att kunna använda pekare, måste jag ha något att peka mot. Dvs, jag måste fortfarande ha en int i = 0. Jag måste också ha en pekare, som pekar på int i = 0.

så:

int i = 0;
int *pekare = i;

Men sen då? Det är här jag faller platt. for(*pekare = i; *pekare < 8; *pekare++) ???

Vad är det du vill uppnå egentligen? Pekare är inget magiskt universalverktyg som löser allting i C++.
Citera
2016-06-06, 11:39
  #8
Medlem
Trumpetflugans avatar
Citat:
Ursprungligen postat av Tiger-Lily
Okej, jag har klurat på ett exempel, där jag har svårt att förstå hur jag ska använda pekare.

Säg att jag har en for-sats. for(int i = 0; i < 8; i++)

Detta är ju ett helt vanligt sätt att deklarera en for-sats.

Säg nu att jag vill göra detta med pekare. Det är här jag går bet, för jag förstår inte när, var hur, jag ska peka och vad som gör vad.

För att kunna använda pekare, måste jag ha något att peka mot. Dvs, jag måste fortfarande ha en int i = 0. Jag måste också ha en pekare, som pekar på int i = 0.

så:

int i = 0;
int *pekare = i;

Men sen då? Det är här jag faller platt. for(*pekare = i; *pekare < 8; *pekare++) ???
'i' används i det närmaste uteslutande för indexering i for - satser. Om du ska köra med pekare i forsats blir det nog mer sannolikt ngt sånt här :

Kod:
for(int i=0;i<10;++i){
               *
pekare = *pekare ;  //eller *pekare += i;
        

//koden ovan ger dock samma resultat som *pekare += 45; 
Eller liknande.
__________________
Senast redigerad av Trumpetflugan 2016-06-06 kl. 11:55.
Citera
2016-06-06, 12:29
  #9
Medlem
Så, jag kan inte använda pekare i for-satser?

Vad jag vill uppnå? Jag vill uppnå förståelse för hur det fungerar.
Citera
2016-06-06, 13:28
  #10
Moderator
Citat:
Ursprungligen postat av Tiger-Lily
Så, jag kan inte använda pekare i for-satser?

Vad jag vill uppnå? Jag vill uppnå förståelse för hur det fungerar.
Jodå, det kan du göra.
Prova detta:

Kod:
int i = 1;    // Skapar variabeln "i" med värdet 1.
int *pekare;    // Skapar pekaren "pekare" som ännu inte har något värde.

for (pekare = &i ; *pekare < 8 ; (*pekare)++ )
{
    // Mer program här.
}


Förklaring på for satsen:
"pekare = &i" detta initierar pekaren "pekare" till minnesadressen där variabel "i" är lagrad.

"*pekare < 8" loopen ska fortsätta så länge som variabeln som finns på adress "pekare" är lägre än 8.

"(*pekare)++" öka värdet på variabeln som finns i adress "pekare" med 1.
Parentesen är nödvändig eftersom prioritering på olika operatorer gör att själva pekaren räknas upp annars.
Citera
2016-06-06, 13:39
  #11
Medlem
enowens avatar
Citat:
Ursprungligen postat av Tiger-Lily
Så, jag kan inte använda pekare i for-satser?

Vad jag vill uppnå? Jag vill uppnå förståelse för hur det fungerar.

Jag skrev precis hur pekare fungerar (not for dummies but for retards) och ett användningsområde där du kommer att stöta på det och du förstår fortfarande inte?

Varför i helvete vill du använda pekare i en loop för?
Men jo det kan du:

Kod:
#include <iostream>
#include <vector>

int main()
{
    
std::vector<int(*)(int)> vec = {[](int i){return i*2;},[](int i){return i*3;}};
    
decltype(vec)* vecptr = &vec;
    for (
size_t i 0vecptr->size(); ++i)
    {
        
std::cerr << (*vecptr)[i](i) << std::endl;
    }


Du är redo för nästa steg.
Citera
2016-06-06, 14:16
  #12
Medlem
Citat:
Ursprungligen postat av Tiger-Lily
Så, jag kan inte använda pekare i for-satser?

Vad jag vill uppnå? Jag vill uppnå förståelse för hur det fungerar.

Läste du de illustrativa bilderna i länken jag gav dig på google books?

Minnet i C++ är som en lång rad med förvaringsskåp på olika adresser, en pekare är en nyckel som pekar ut just ett specifikt förvaringsskåp, med en pekare som varken är top eller low-level const så kan du ändra två saker med den.
Du kan ändra vilket förvaringsskåp den pekar på, du kan också ändra det som ligger i förvaringsskåpet som den pekar på. T.ex.

int* intPtr = nullptr;
intPtr = new int(5); //Ändrar vilket skåp pekaren pekar på.
*intPtr = 7; //Ändrar vad som ligger i skåpet som pekaren pekar på.
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback