C/Pointers
From Attie's Wiki
(Difference between revisions)
m |
m |
||
Line 8: | Line 8: | ||
int main(void) { | int main(void) { | ||
− | char *s = " | + | char *s = "cba"; |
char **p = &s; | char **p = &s; | ||
Line 38: | Line 38: | ||
return 0; | return 0; | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | Output: | ||
+ | <source lang="text"> | ||
+ | $ gcc test.c -o test && ./test | ||
+ | s: 0x8048734 <-- the address of the 'c' | ||
+ | &s: 0xBF893E8C <-- the address of the variable s | ||
+ | s[0]: 0x63 <-- the 'c' | ||
+ | *s: 0x63 <-- the 'c' | ||
+ | p: 0xBF893E8C <-- the address of the variable s | ||
+ | &p: 0xBF893E88 <-- the address of the variable p | ||
+ | p[0]: 0x8048734 <-- the address of the 'c' | ||
+ | *p: 0x8048734 <-- the address of the 'c' | ||
+ | p[1]: 0x8048680 <-- INVALID - the value stored just after the variable p (the program may segfault here) | ||
+ | *p[1]: 0x55 <-- INVALID - the value stored at location 0x8048680 (again, the program may segfault here) | ||
+ | (*p)[1]: 0x62 <-- the 'b' | ||
+ | *(p[1]): 0x55 <-- INVALID - the same as *p[1] | ||
+ | (*p): 0x8048734 <-- the address of the 'c' | ||
+ | (*p)++: 0x8048734 <-- the address of the 'c' - the pointer is POST incremented | ||
+ | (*p)[0]: 0x62 <-- the 'b' | ||
+ | (*p): 0x8048735 <-- the address of the 'b' | ||
+ | ++(*p): 0x8048736 <-- the address of the 'a' - the pointer is PRE incremented | ||
+ | (*p)[0]: 0x61 <-- the 'a' | ||
+ | (*p): 0x8048736 <-- the address of the 'a' | ||
</source> | </source> |
Revision as of 23:22, 8 March 2012
A helper for people starting out with pointers:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define P(expr) printf("%10s: 0x%02X\n", #expr, expr) int main(void) { char *s = "cba"; char **p = &s; P( s ); P( &s ); P( s[0] ); P( *s ); P( p ); P( &p ); P( p[0] ); P( *p ); P( p[1] ); P( *p[1] ); P( (*p)[1] ); P( *(p[1]) ); P( (*p) ); P( (*p)++ ); P( (*p)[0] ); P( (*p) ); P( ++(*p) ); P( (*p)[0] ); P( (*p) ); return 0; }
Output:
$ gcc test.c -o test && ./test s: 0x8048734 <-- the address of the 'c' &s: 0xBF893E8C <-- the address of the variable s s[0]: 0x63 <-- the 'c' *s: 0x63 <-- the 'c' p: 0xBF893E8C <-- the address of the variable s &p: 0xBF893E88 <-- the address of the variable p p[0]: 0x8048734 <-- the address of the 'c' *p: 0x8048734 <-- the address of the 'c' p[1]: 0x8048680 <-- INVALID - the value stored just after the variable p (the program may segfault here) *p[1]: 0x55 <-- INVALID - the value stored at location 0x8048680 (again, the program may segfault here) (*p)[1]: 0x62 <-- the 'b' *(p[1]): 0x55 <-- INVALID - the same as *p[1] (*p): 0x8048734 <-- the address of the 'c' (*p)++: 0x8048734 <-- the address of the 'c' - the pointer is POST incremented (*p)[0]: 0x62 <-- the 'b' (*p): 0x8048735 <-- the address of the 'b' ++(*p): 0x8048736 <-- the address of the 'a' - the pointer is PRE incremented (*p)[0]: 0x61 <-- the 'a' (*p): 0x8048736 <-- the address of the 'a'