scanf和p转换说明符

时间:2014-12-29 09:58:39

标签: c c11 format-specifiers

在C11规范中,%p的参数类型在void **函数的情况下必须为scanf(),但我无法确定如何输入地址并存储它进入void **。 事实上,如果我试图做:

void **p;
scanf("%p", p);

我遇到了分段错误。

P.S。 C11规范:

  

相应的参数应该是指向void

的指针

4 个答案:

答案 0 :(得分:6)

void **p;
scanf("%p", p);

相同的原因不起作用
int *i;
scanf("%i", i);

不起作用 - 你正在写一个未初始化的指针(或告诉scanf写一个,至少)。

这有效:

int i;
scanf("%i", &i);

这样做:

void *p;
scanf("%p", &p);

答案 1 :(得分:1)

您没有初始化p。尝试:

void *p;
scanf("%p", &p);

这将使用p的地址,该地址有效。

答案 2 :(得分:1)

注意:原始帖子没有提及c11标准。

好吧,根据c99规范文件,第7.19.6章。 1 2,段落 8 12,

  

p

     

匹配实现定义的序列集,应该是   与可能由%p转换产生的序列集相同   fprintf功能。相应的参数应该是指向a的指针   指向void的指针。输入项将转换为指针值   实现定义的方式。如果输入项是先前转换的值   在同一程序执行期间,结果的指针应进行比较   等于该值;否则%p转换的行为是未定义的。

因此,它不是void **,而是void *

接下来,您出现分段错误的原因是在p中使用了未初始化的指针scanf()。在使用[传递给p作为参数]之前,您没有为scanf()分配内存。

正如其他人的建议,你可以很好地使用像

这样的东西
void *p;
scanf("%p", &p);

此处,&p值实际为pointer to a pointer to void并且具有已定义的地址。

答案 3 :(得分:0)

标准说%p应该有void *类型参数。您需要将p声明为void *然后

scanf("%p", &p);    

您遇到段错误的原因是因为在void **p中,p并未指向任何位置。