为什么可以将双指针(地址的地址)传递给scanf?
这个简单的代码是我所期望的:
#include <stdio.h>
int main()
{
char input[20];
printf("enter a string: ");
scanf("%[^n]s", input);
printf("input: %sn", input);
}
哪里input是(char*)[20]。但是为什么我可以通过这个:
#include <stdio.h>
int main()
{
char input[20];
printf("enter a string: ");
scanf("%[^n]s", &input);
printf("input: %sn", input);
}
它仍然编译和运行?&input传递的参数应该是(char**)[20]哪个不正确,但它运行。为什么?
回答
在您的代码中,表达式input(当用作 的参数时scanf)将计算(即衰减)为 20 个字符数组的第一个元素的地址,并且表达式&input将计算为数组本身的地址 - 这将是同样,在这种情况下。这可以通过在代码中添加如下一行来证明:
printf("%p %pn", (void*)(input), (void*)(&input)); // Print the two addresses - SAME!
因此,您对 的调用scanf实际上将传递正确的值(输入缓冲区的地址)。
然而,一个好的编译器会警告你不兼容的指针类型;例如,clang-cl 生成这个:
警告:格式指定类型“char *”,但参数具有类型 'char (*)[20]' [-Wformat]
当然,是否要解决警告或忽略它取决于您;但是,在更复杂的代码中,此类“错误”可能会导致很难追踪的运行时错误。