当我们谈论解引用时,是否有必要使用*
?如果我们以其他方式访问指针的所指对象,是否可以将其视为取消引用指针,例如:
char *ptr = "abc" ;
printf( "%c" , *ptr ); // Here pointer is dereferenced.
printf( "%s" , ptr ); // What about this one?
这是我问题的第一部分。
现在 if printf( "%s" , ptr )
是取消引用的示例,请也回答我的问题的以下部分。
K&R 说
“指向 void 的指针”用于保存
任何类型的指针,但不能是
取消引用自身
因此,
char a = 'c' ;
char *p = &a ;
void *k = &a;
printf( "\n%c\n" , *p );
printf( "\n%c\n" , *k );
无法编译,编译器给出错误
在函数“main”中:警告:
取消引用“void *”指针错误:
void 表达式的使用无效
但是如果我们使用
char *a = "c" ;
char *p = a ;
void *k = a;
printf( "\n%c\n" , *p );
printf( "\n%s\n" , k );
它可以编译并工作。这意味着 void 指针可以被取消引用 - 我们已经得到了所引用的对象指针。
如果是这样的话,那么上面提到的 K&R 在这种情况下意味着什么?
感谢您抽出时间。
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 following 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.
发布评论
评论(2)
不,你所拥有的是“未定义的行为”——C 语言标准没有说明应该发生什么。在您的情况下,它“有效”,但对于另一个用户/编译器/平台来说可能不行。您的陈述:
相当于:
并且同样未定义。
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:
is equivalent to:
and is equally undefined.
在给出的示例中:
发生了什么,在第一个 printf 中,值“c”是通过取消引用
char
指针传入的,printf
只知道您给了它一个 < code>char 因为%c
格式标记。现在,
void*
只是一个具有未知类型的原始指针,您无法取消引用它,因为编译器不知道从中读取什么类型,除非您将其转换为其他类型。在第二个 printf 中,传入了
void*
指针。printf
只是将其视为一个普通数字,并且不知道它是什么,直到它读取给定的格式标记。通过使用%s
,您可以告诉 printf 函数您实际上传入了char*
,因此它会相应地对其进行强制转换并将其正确读取为字符串,即取消引用char*
指针——而不是void*
指针。只要
void*
指针指向以 null 结尾的char
数组,它就是有效的代码。如果void*
指针指向不同的东西,printf
函数仍然会愉快地尝试将其读取为char*
指针(如果您指定%s
)并导致未定义的行为。另一个不好的例子:
你也不能取消引用一个整数,但我告诉
printf
它是一个char*
,所以它可以工作。In the example given:
What is happening, in the first printf, the value 'c' is passed in from dereferencing the
char
pointer,printf
only knows you gave it achar
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 achar*
, so it casts it accordingly and reads it properly as a string, i.e. it dereferences achar*
pointer--not avoid*
pointer.It's valid code, as long as the
void*
pointer points to a null-terminatedchar
array. If thevoid*
pointer is pointing to something different, theprintf
function will still happily try to read it as achar*
pointer (if you specify%s
) and cause undefined behavior.A different bad example:
You can't dereference an integer either, but I told
printf
that it's achar*
, so it works.