2010-07-28 31 views
7

当我们谈论解除引用时,是否有必要使用*呢?如果我们访问指针所指的一些其他的方式,可以将其视为解引用指针或没有,如:为什么printf(“%s”,ptr)能够解引用void *?

char *ptr = "abc" ; 
printf("%c" , *ptr); // Here pointer is dereferenced. 
printf("%s" , ptr); // What about this one? 

这是我的问题的第一部分。

现在如果printf("%s" , ptr)是解引用的示例,那么也请回答我的问题的以下部分。

ķ& [R说

a "pointer to void" is used to hold any type of pointer but cannot be dereferenced itself

因此,

char a = 'c' ; 
char *p = &a ; 
void *k = &a; 
printf("\n%c\n" , *p); 
printf("\n%c\n" , *k); 

不能编译,编译器给出错误

In function ‘main’: warning: dereferencing ‘void *’ pointer error: invalid use of void expression

但是如果我们用

char *a = "c" ; 
char *p = a ; 
void *k = a; 
printf("\n%c\n" , *p); 
printf("\n%s\n" , k); 

它编译和工作。这意味着无效指针可以被解除引用 - 我们已经得到了对象指针指向的内容。
如果是这种情况,那么上面提到的K & R是什么意思?

谢谢你的时间。

+1

我没有看到你在哪里解除引用'void *'成功。请重新阅读您的代码。 – leppie 2010-07-28 10:53:27

回答

9

不,你有什么是“未定义的行为” - C语言标准没有说明会发生什么。在你的情况下,它“工作”,但对于另一个用户/编译器/平台,它可能不是。您的发言:

printf("\n%s\n" , k); 

等同于:

int k = 42; 
printf("\n%s\n" , k); 

和同样是不确定的。

+0

我明白了你的观点。谢谢。问题的第一部分呢? 'printf(“%s”,ptr)'也被视为指针的解引用? – 2010-07-28 10:59:18

+1

@andrew printf()肯定需要对指针进行取消引用,以完成对“%s”格式化程序的操作。 OTOH,如果您在同一个指针上使用“%p”格式化程序,则不需要遵守。 – 2010-07-28 11:01:24

+0

我不知道这个标准是如何定义'printf'的,或者我错过了某些东西,但可以设想'void *'被转换为'char *',因为'printf'可以推断它是一个字符串由'%s'完成。然后再次,这个问题可能是一个可变参数问题。我不想挖掘它。 – 2011-10-25 01:02:11

0

在给出的例子:

char *a = "c"; 
char *p = a; 
void *k = a; 
printf("\n%c\n" , *p); 
printf("\n%s\n" , k); 

发生了什么,在第一个printf,值“C”是从提领该char指针传递,printf只知道你给它一个char因为%c格式标记。

现在,void*只是一个未知类型的原始指针,不能对其进行解引用,因为除非将其转换为其他类型,否则编译器不知道要从中读取哪种类型。

在第二个printf中,void*指针被传入。printf只是将其看作一个普通数字,并且不知道它是什么,直到它读取给定的格式标记。通过使用%s,你告诉printf函数,你实际上通过了一个char*,所以它会相应地转换它,并以字符串的形式正确读取它,即取消引用char*指针 - 而不是void*指针。

它是有效的代码,只要void*指针指向以空值终止的char数组。如果void*指针指向不同的东西,printf函数仍然乐意尝试将其读取为char*指针(如果指定了%s)并导致未定义的行为。

不同的坏榜样:

char *a = "ce"; 
int b = (int)a; 
printf("\n%s\n" , b); 

无法提领的整数下去,但我告诉printf,这是一个char*,所以它的工作原理。

相关问题