Toon posts:

[C++] Een beetje in de war met pointers en arrays

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met het leren van C++ en ben daarom aan het oefenen met pointers.
Ik heb een gelinkte lijst gemaakt waarvan elk element bestaat uit een naam en een tekenreeks:

C++:
1
2
3
4
5
6
struct element
{
  int value;
  char name[255];
  element *next;
};


Verder heb ik een functie om een element toe te voegen:

C++:
1
2
3
4
5
6
7
8
void AddElement(list *TargetList, int value, const char *name)
{
  element *NewElement = new element;
  NewElement->value = value;
  strcpy(NewElement->name, name);
  
  // ... nog wat code om de plaats in de lijst te bepalen, niet relevant
}


Deze functie roep ik aan:

C++:
1
  AddElement(IDList, 1, "sir5");


Element bevat ruimte voor 255 tekens. AddElement krijgt alleen een pointer naar het begin de array, namelijk const char *name. Zover snap ik het allemaal nog.
Maar wat ik niet snap is hoe er wordt bepaald hoe lang mijn aangeboden tekenreeks is? AddElement krijgt namelijk, net als strcpy alleen een pointer naar het eerste element. Wordt dit intern bijgehouden of wordt het bepaald door te kijken waar de \0 zit?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat wordt bepaald door te kijken waar de \0 zit. strlen () doet hetzelfde. In het geval van de strcpy brengt dit niet extra overhead met zich mee, mocht je dat misschien denken, want er wordt gewoon doorgekopieerd totdat de \0 tegen wordt gekomen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

strcpy werkt als volgt:
C:
1
2
3
4
void strcpy(char* Dest, const char* Src)
{
while(*(Dest++) = *(Src++));
}

Professionele website nodig?


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
curry684 schreef op 23 September 2003 @ 21:01:
strcpy werkt als volgt:
C:
1
2
3
4
void strcpy(char* Dest, const char* Src)
{
while(*(Dest++) = *(Src++));
}
Lekker cryptisch is dat weer (nogal C style inherent vind ik dat :+ )
Even voor onze topicstarter:
Een dereference van de Dest pointer zal 0 opleveren als het adres het /0 character bevat. Dus zolang hij geen /0 tegen komt, copieert hij het teken in Src naar Dest.

Het had dus ook zo gekund (wat verboser en ook trager ;) )
C++:
1
2
3
4
5
6
7
        char compare;
        do {
                *Dest = *Src;
                compare = *Dest;
                Src++;
                Dest++;
        } while( compare );

[ Voor 13% gewijzigd door Glimi op 23-09-2003 22:09 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Glimi schreef op 23 September 2003 @ 21:34:
Lekker cryptisch is dat weer (nogal C style inherent vind ik dat :+ )
Maar wel correct! Dat kan ik van jouw code (helaas) niet zeggen:
C++:
1
2
3
4
5
do { 
   *Dest = *Src; 
   *Dest++; 
   *Src++; 
while( *Dest != '/0' )
Er zijn twee dingen fout; ten eerste hoog je de waarde waar Dest en Src naar verijzen op, in plaats van de pointerwaarden zelf (waardoor je dus hoogstwaarschijnlijk een oneindige lus krijgt!). Zelfs als je de sterretjes op de 3e en 4e regel weghaalt, werkt het niet, want dan heb je Dest al opgehoogd voordat je de lusconditie bereikt. Je vergelijkt dan een ongeinitialiseerde waarde in het geheugen; de waarde daarvan is niet bepaald.

[ Voor 174% gewijzigd door Glimi op 23-09-2003 21:55 ]


  • cobratbq
  • Registratie: Maart 2001
  • Laatst online: 17-12-2015
Er zijn twee dingen fout; ten eerste hoog je de waarde waar Dest en Src naar verijzen op, in plaats van de pointerwaarden zelf (waardoor je dus hoogstwaarschijnlijk een oneindige lus krijgt!). Zelfs als je de sterretjes op de 3e en 4e regel weghaalt, werkt het niet, want dan heb je Dest al opgehoogd voordat je de lusconditie bereikt. Je vergelijkt dan een ongeinitialiseerde waarde in het geheugen; de waarde daarvan is niet bepaald.
Ondanks dat hielp het me wel om de code te begrijpen 8)7

edit:
Die onbedoelde edit is te verhelpen, aangezien ik net de gewiste tekst quote 8)

[ Voor 9% gewijzigd door cobratbq op 23-09-2003 21:55 ]

One ring to rule them all, one ring to find them, one ring to bring them all, and in darkness bind them...


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op 23 september 2003 @ 21:46:
[...]

Maar wel correct! Dat kan ik van jouw code (helaas) niet zeggen:

ten eerste hoog je de waarde waar Dest en Src naar verijzen op, in plaats van de pointerwaarden zelf (waardoor je dus hoogstwaarschijnlijk een oneindige lus krijgt!)
Nee, de ++ heeft een hogere precedence dan de *. De * doet hier dus simpelweg niets

(je bent niet in vorm vandaag Soultaker ;))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
.oisyn schreef op 23 September 2003 @ 21:56:
Nee, de ++ heeft een hogere precedence dan de *. De * doet hier dus simpelweg niets

(je bent niet in vorm vandaag Soultaker ;))
ARGH! Ik blijf inderdaad m'n excuses maken, vandaag. Misschien kan ik gewoon beter m'n mond gaan houden en vanavond proberen meer dan vier uurtjes te slapen. :P

Overigens heb ik zelf de gewoonte om overal haakjes omheen te zetten, om dit soort verwarringen te voorkomen. Al met al demonstreren Glimi en ik wel even dat pointer arithmetic in C niet eenvoudig is; heeft ons gepruts hopelijk toch nog enige didactische waarde. 8)

offtopic:
Behalve hier, ging het vandaag dus ook (o.a.?) hier mis...
[rml]Soultaker in "[ C++] continue"[/rml]
[rml]Soultaker in "[ C++] multi-dimensional arrays"[/rml]
:/

[ Voor 17% gewijzigd door Soultaker op 23-09-2003 22:02 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Soultaker schreef op 23 September 2003 @ 21:46:
Maar wel correct! Dat kan ik van jouw code (helaas) niet zeggen:
OMG, idoot die ik ben ja. ff bijwerken hoor :)

edit:
En nog excuus voor de edit ipv quote
cobratbq schreef op 23 September 2003 @ 21:53:
edit:
Die onbedoelde edit is te verhelpen, aangezien ik net de gewiste tekst quote 8)
Held O+

Verwijderd

Topicstarter
Ah, bedankt voor de uitleg :)
Rest mij nog een klein vraagje: hoe weet "het" dat de pointer die ik doorgeef een pointer naar een array is, en niet een pointer naar een enkel teken?
Of stel ik nu een domme vraag? ;)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 24 September 2003 @ 00:09:
Ah, bedankt voor de uitleg :)
Rest mij nog een klein vraagje: hoe weet "het" dat de pointer die ik doorgeef een pointer naar een array is, en niet een pointer naar een enkel teken?
Of stel ik nu een domme vraag? ;)
Ja ;)

Een pointer is een pointer, oftewel niets meer dan een geheugenadres. Als jij een single char aan strcpy meegeeft zal ie prettig knallen voor je omdat ie nergens een terminating zero tegenkomt :)

ps. bestudeer deze post nog eens goed, het zou je wel eens kunnen helpen het concept te begrijpen als je 'm goed analyseert met je boek ernaast :)

[ Voor 18% gewijzigd door curry684 op 24-09-2003 08:09 ]

Professionele website nodig?


Verwijderd

Topicstarter
Ok, thank you very much, weer wat geleerd :)
Pagina: 1