Printing Pointers in C

I was trying to figure something out with pointers, so I wrote this code:

#include <stdio.h> int main(void) { char s[] = "asd"; char **p = &s; printf("The value of s is: %p\n", s); printf("The direction of s is: %p\n", &s); printf("The value of p is: %p\n", p); printf("The direction of p is: %p\n", &p); printf("The direction of s[0] is: %p\n", &s[0]); printf("The direction of s[1] is: %p\n", &s[1]); printf("The direction of s[2] is: %p\n", &s[2]); return 0; } 

When compiling with gcc, I get the following warnings:

 $ gcc main.c -o main-bin -ansi -pedantic -Wall -lm main.c: In function 'main': main.c:6: warning: initialization from incompatible pointer type main.c:9: warning: format '%p' expects type 'void *', but argument 2 has type 'char (*)[4]' main.c:11: warning: format '%p' expects type 'void *', but argument 2 has type 'char **' main.c:12: warning: format '%p' expects type 'void *', but argument 2 has type 'char ***' 

(Flags for gcc is because I have to be C89)

Why incompatible pointer types? Is the name of the array a pointer to its first element? Therefore, if s is a pointer to 'a', &s must be char ** , no? And why am I getting other warnings? Do I have to specify pointers ( void * ) to print them?

And at startup, I get something like this:

 $ ./main-bin The value of s is: 0xbfb7c860 The direction of s is: 0xbfb7c860 The value of p is: 0xbfb7c860 The direction of p is: 0xbfb7c85c The direction of s[0] is: 0xbfb7c860 The direction of s[1] is: 0xbfb7c861 The direction of s[2] is: 0xbfb7c862 

How can the value of s and its direction (and, of course, the value of p ) be the same?

+33
c pointers
Oct 13 '08 at 14:25
source share
8 answers

"s" is not "char *", it is "char [4]". So, "& s" is not "char **", but actually a "pointer to an array of 4 characters." Your compiler can handle "& s" as if you wrote "& s [0]", which is about the same thing, but is "char *".

When you write "char ** p = & s;" you're trying to say, โ€œI want p to be set to the address of the object that currently points toโ€œ asd. โ€But currently there is nothing that points toโ€œ asd. โ€There is only an array that containsโ€œ asd โ€; / p>

 char s[] = "asd"; char *p = &s[0]; // alternately you could use the shorthand char*p = s; char **pp = &p; 
+24
Oct 13 '08 at 14:44
source share

Yes, your compiler is expecting void *. Just drop them on void *.

 /* for instance... */ printf("The value of s is: %p\n", (void *) s); printf("The direction of s is: %p\n", (void *) &s); 
+13
Oct. 13 '08 at 14:31
source share

If you pass an array name as an argument to a function, it is treated as if you passed the address of the array. So, & s and s are the same arguments. See K & R 5.3. & s [0] matches & s because it takes the address of the first element of the array, which matches the address of the array itself.

For everyone else, although all pointers are essentially memory cells, they are still printed, and the compiler will warn you about assigning one type of pointer to another.

  • void* p; says p is the memory address, but I don't know what in memory
  • char* s; says s is the memory address and the first byte contains the character
  • char** ps; says ps is a memory address and four bytes (for a 32-bit system) contain a char * pointer.

cf http://www.oberon2005.ru/paper/kr_c.pdf (K & R e-book)

+4
Oct 13 '08 at 14:37
source share

change line:

char s [] = "asd";

at

char * s = "asd";

and everything will become clearer

+1
Oct 13 '08 at 14:34
source share

You cannot change the value (i.e. address) of a static array. From a technical point of view, the lvalue of an array is the address of its first element. Therefore, s == &s . This is just a fad of language.

+1
Oct 13 '08 at 14:38
source share

He usually considered bad style as unnecessary hover pointers (void *). Here, however, you need casts to (void *) in printf arguments, since printf is a variable. The prototype does not tell the compiler what type to convert pointers to the call site.

+1
Oct 13 '08 at 17:20
source share

This is not a pointer to a char* character, but a pointer to an array of 4 characters: char* [4] . With g ++, it does not compile:

main.cpp: In the function 'int main (int, char **): main.cpp: 126: error: cannot convert' char (*) [4] to 'char ** on initialization

In addition, the linux man pages say :

R

The void * pointer argument is printed in hexadecimal (as if in% # x or% # Lx). This will be a pointer to the void.

You can change your code to:

 char* s = "asd"; char** p = &s; printf("The value of s is: %p\n", s); printf("The address of s is: %p\n", &s); printf("The value of p is: %p\n", p); printf("The address of p is: %p\n", &p); printf("The address of s[0] is: %p\n", &s[0]); printf("The address of s[1] is: %p\n", &s[1]); printf("The address of s[2] is: %p\n", &s[2]); 

result:

S value is: 0x403f00

Address s: 0x7fff2df9d588

P value is: 0x7fff2df9d588

Address p: 0x7fff2df9d580

Address s [0]: 0x403f00

Address s [1]: 0x403f01

Address s [2]: 0x403f02

+1
Mar 15 '13 at 1:42
source share

You used:

 char s[] = "asd"; 

Here s actually points to the asd bytes. Address s also points to this location.

If you used:

 char *s = "asd"; 

the value of s and & s will be different, since s will actually be a pointer to the "asd" bytes.

You used:

 char s[] = "asd"; char **p = &s; 

Here s points to the asd bytes. p is a pointer to a pointer to characters and has been set to the address of characters. In other words, you have too many directions per page. If you used char * s = "asd", you can use this extra indirectness.

0
Oct 13 '08 at 14:28
source share



All Articles