我试图在我的代码中打印出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);
}
那么你为什么不施展呢?
printf("argv = %p\n", (void *)argv);`
指定了%p
指针(POSIX printf()
; C11 §7.21.6.1 The fprintf
function):
p
- 参数应该是指向void
的指针。指针的值以实现定义的方式转换为打印字符序列。
由于char **
不是void *
,您需要进行显式转换。标准不允许编译器为你转换为void *
- printf()
声明中的省略号表示法意味着默认参数促销发生,但这只影响float
类型和小于int
的整数类型(short
,char
)等)。
在这些天的大多数机器上,这是一个无操作。在我学会用C语言编程的(长期过时)机器上,还没有void *
(对于标准来说太旧了),但等效的是char *
,并且给定内存位置的char *
地址的值不同于任何其他类型的指针值 - 强制转换不是可选的。
请注意,我假设您打算打印地址的值。如果您打算打印内容,那么还有更多工作要做。
好吧,不是任何指针(类型)。
根据C11
,章节§7.21.6.1,对于%p
转换说明符,
p
参数应该是指向
void
的指针。指针的值以实现定义的方式转换为打印字符序列。
因此,参数必须是void *
类型(或者,char*
,因为它们具有相同的对齐要求)。任何其他类型的指针必须通过显式转换转换,因为指针没有默认参数提升。
就像是
printf("%s%p", "argv = ", (void *)argv);
应该做。
要打印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;
}