When we talk about dereference, is it necessary that *
should be used in it? If we access the referent of the pointer in some other way, can it be considered as dereferencing a pointer or not, like:
char *ptr = "abc" ;
printf( "%c" , *ptr ); // Here pointer is dereferenced.
printf( "%s" , ptr ); // What about this one?
That is the first part of my question.
Now if printf( "%s" , ptr )
is an example of dereferencing then kindly answer the followi开发者_开发百科ng part of my question too.
K&R says
a "pointer to void" is used to hold any type of pointer but cannot be dereferenced itself
Hence,
char a = 'c' ;
char *p = &a ;
void *k = &a;
printf( "\n%c\n" , *p );
printf( "\n%c\n" , *k );
Does not compile, complier gives error
In function ‘main’: warning: dereferencing ‘void *’ pointer error: invalid use of void expression
But if we use
char *a = "c" ;
char *p = a ;
void *k = a;
printf( "\n%c\n" , *p );
printf( "\n%s\n" , k );
It compiles and works. Which means void pointer can be dereferenced - we have got the object pointer is referring to.
If that's the case then what does K&R above mentioned quote means in this context?Thanks for your time.
No. what you have is "undefined behaviour" - the C language standard does not say what should happen. In your case, it "works", but for another user/compiler/platform it might not. Your statement:
printf( "\n%s\n" , k );
is equivalent to:
int k = 42;
printf( "\n%s\n" , k );
and is equally undefined.
In the example given:
char *a = "c";
char *p = a;
void *k = a;
printf( "\n%c\n" , *p );
printf( "\n%s\n" , k );
What is happening, in the first printf, the value 'c' is passed in from dereferencing the char
pointer, printf
only knows you gave it a char
because of the %c
format tag.
Now, a void*
is just a raw pointer that has an unknown type, you can't dereference it because the compiler does not know what type to read from it unless you cast it to something else.
In the second printf, the void*
pointer is passed in. printf
just sees it as a plain number, and has no idea what it is until it reads the formatting tag given. By using %s
, you are telling the printf function that you actually passed in a char*
, so it casts it accordingly and reads it properly as a string, i.e. it dereferences a char*
pointer--not a void*
pointer.
It's valid code, as long as the void*
pointer points to a null-terminated char
array. If the void*
pointer is pointing to something different, the printf
function will still happily try to read it as a char*
pointer (if you specify %s
) and cause undefined behavior.
A different bad example:
char *a = "ce";
int b = (int)a;
printf( "\n%s\n" , b );
You can't dereference an integer either, but I told printf
that it's a char*
, so it works.
精彩评论