Ik zit als beginner een beetje te klooien met pointers en nu wilde ik voor de aardigheid bekijken welke geheugen-adressen het systeem gebruikt voor de variabelen.
Het stukje code dat ik daarvoor gemaakt had ziet er zo uit:
Int a;a = 25printf(" A= %d\n" , &a );
Ik krijg dan op de printf de volgende foutmelding:Format '%d' expects type 'int', but argument 2 has type 'int *'Hij retourneert trouwens wel een waarde: -1073744324, of als ik placeholder voor hex-getallen gebruik, BFFFF63C
Ik snap wel wat de fout is, maar hoe moet het dan wèl?Zelfde vraag voor het uitprinten van pointers...
Bij voorbaat dank!
printf(" A= %d\n" , (int) &a );
int main(){ int a = 5; int *pa = &a; printf("a = %d\n", a); printf("pa = %.8x\n", (int) pa); printf("*pa = %d\n", *pa); return 0;}
Syncan om 16:32, 27-01-2011Maar wel gek eigenlijk, want als je bij placeholder al %d geeft, dan moet-ie het toch snappen dat het een int is?
De compiler probeert je te waarschuwen voor het feit dat er een "int" verwacht wordt als argument in de printf aanroep. Merk op dat dit al een vrij geavanceerde feature van de compiler is. De compiler heeft ingebouwde kennis van de specifieke karakters ("%d") die in de printf string gebruikt worden.
Door er een "cast" voor te plaatsen vertel je aan de compiler dat je weet wat je aan het doen bent. En hopelijk is dat ook zo. In het algemeen is het gebruik van "casts" af te raden maar soms heb je ze inderdaad nodig om van bepaalde compilerwaarschuwingen af te komen.
Waar kan ik trouwens een volledige lijst vinden van de Printf-placeholders? Ik ken er maar een stuk of vijf, zes en het lijkt me dat er vast meer zijn...
LP64 staat voor long-pointer-64, dus dat long ints en pointers 64 bits zijn. En int impliciet 32, dus minder dan de pointer. Verschillende systemen kunnen verschillende groottes hebben, en het is beter om daar rekening mee te houden als je wilt dat je code zonder al te veel aanpassingen op andere systemen draait. De stap van PPC naar x86 en naar 64-bit was lang niet zo groot geweest als meer software niet zo sterk op de 'huidige' systemen was gericht.
Iets concreter: als je voor 64-bit compileert (standaard tegenwoordig), en je pointer omzet naar een int, dan zal dat werken op je Air, maar er gaat informatie verloren. Er zijn meerdere pointers die dezelfde int geven, en als je de int weer omzet naar een pointer zul je zien dat hij niet meer werkt.
intptr_t is een type gedefinieerd in <stdint.h>. Dat is een integer die een pointer kan bevatten. Als je zeker weet dat je het nodig hebt, is het het beste om dat type te gebruiken. Maar meestal is het beter om in de eerste plaats niet met zulke praktijken bezig te zijn.
%p neemt een void * net zoals %d een int en %g een double nemen. printf("%p\n", (void *)some_pointer) dus, om het helemaal netjes te doen.
Er zijn op het internet en op je computer specificaties en documentatie te vinden. Alleen al een paar manieren om man pages te bekijken:- Terminal: man 3 printf- Xcode: Help -> Open man Page... -> 3 printf- Xcode: Help -> Developer Documentation -> printf
De 3 is bij de bovenste twee omdat er ook een "1 printf" is, een shellcommando, dat anders voorrang krijgt. Voor veel functies is de 3 (of 2, die je bij system calls ziet) niet nodig en kan je alleen de naam geven.
Hopelijk is dit een klein beetje beter te begrijpen, al heb ik niet de tijd om op alles helemaal in te gaan.
Macceraar om 19:57, 27-01-2011Sorry dat het meteen zo moeilijk is, maar ik moest even een paar correcties het draadje in gooien.LP64 staat voor long-pointer-64, dus dat long ints en pointers 64 bits zijn. En int impliciet 32, dus minder dan de pointer. Verschillende systemen kunnen verschillende groottes hebben, en het is beter om daar rekening mee te houden als je wilt dat je code zonder al te veel aanpassingen op andere systemen draait. De stap van PPC naar x86 en naar 64-bit was lang niet zo groot geweest als meer software niet zo sterk op de 'huidige' systemen was gericht.Iets concreter: als je voor 64-bit compileert (standaard tegenwoordig), en je pointer omzet naar een int, dan zal dat werken op je Air, maar er gaat informatie verloren. Er zijn meerdere pointers die dezelfde int geven, en als je de int weer omzet naar een pointer zul je zien dat hij niet meer werkt.intptr_t is een type gedefinieerd in <stdint.h>. Dat is een integer die een pointer kan bevatten. Als je zeker weet dat je het nodig hebt, is het het beste om dat type te gebruiken. Maar meestal is het beter om in de eerste plaats niet met zulke praktijken bezig te zijn.%p neemt een void * net zoals %d een int en %g een double nemen. printf("%p\n", (void *)some_pointer) dus, om het helemaal netjes te doen.Er zijn op het internet en op je computer specificaties en documentatie te vinden. Alleen al een paar manieren om man pages te bekijken:- Terminal: man 3 printf- Xcode: Help -> Open man Page... -> 3 printf- Xcode: Help -> Developer Documentation -> printfDe 3 is bij de bovenste twee omdat er ook een "1 printf" is, een shellcommando, dat anders voorrang krijgt. Voor veel functies is de 3 (of 2, die je bij system calls ziet) niet nodig en kan je alleen de naam geven.Hopelijk is dit een klein beetje beter te begrijpen, al heb ik niet de tijd om op alles helemaal in te gaan.
Het is al een stuk beter te begrijpen Ik zal die man-pages ook nalezen. Ik kom oorspronkelijk van Windows, waar ik met Visual C# gewerkt heb. C werkt naar mijn idee veel meer met pointers. Ik heb drie boeken aangeschaft die elkaar ( hopelijk ) aanvullen: Learn C on the Mac, Learn Objective C on the Mac en Learn Cocoa on the Mac, allemaal uitgegeven bij Apress.Samen met wat ik hier op dit forum vind, kan ik dus voorlopig nog wel even vooruit