警告:格式为'%p'的参数应为类型'void *',但参数3的类型为'char **'

时间:2018-09-07 06:18:07

标签: c pointers

我现在试图在代码中打印出argv的值,但是当我尝试对其进行编译时,我得到了 warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘char **。我不确定这个警告是什么意思。即使%p是指针,也不打算用于argv吗?

int main(int argc, char* argv[])
{
    printf("%s%p", "argv = ", argv);
}

3 个答案:

答案 0 :(得分:9)

那你为什么不投它呢?

printf("argv = %p\n", (void *)argv);`

指定了%p指针(POSIX printf(); C11 §7.21.6.1 The fprintf function):

  

p —参数应为指向void的指针。指针的值以实现定义的方式转换为一系列打印字符。

由于char **不是void *,因此您需要进行显式转换。标准不允许编译器为您转换为void *-printf()声明中的省略号表示发生默认参数提升,但仅影响{{1} }类型和小于floatintshort等)的整数类型。

这些天在大多数计算机上,这是无人操作的。在我学会用C语言编程的(已经过时的)机器上,还没有char(对于标准而言太旧了),但是等效的是void *和{{ 1}}中给定内存位置的地址与其他任何类型的指针值都不一样-强制转换不是可选的。

请注意,我假设您打算打印地址的值。如果您打算打印内容,那么还有更多工作要做。

答案 1 :(得分:2)

好吧,不是任何指针(类型)。

对于C11转换说明符,根据%p第§7.21.6.1章,

  

p

     

自变量应为指向void的指针。指针的值是   在实现定义中转换为打印字符序列   方式。

因此,参数必须为void *类型(或char*,因为它们具有相同的对齐要求)。任何其他类型的指针,都必须通过显式转换进行转换,因为没有默认的指针提升参数。

类似

printf("%s%p", "argv = ", (void *)argv);

应该做。

答案 2 :(得分:1)

要打印argv及其地址,您需要做

int main(int argc, char* argv[])
{
    int i;
    printf("address of argv = %p\n", (void *)argv);
    for (i = 0; i < argc; ++i)
    {
        printf("%s\n", argv[i]);
    }
    return 0;
}