我可以将数组直接传递给 printf:
char text[1024] = "text";
printf("%s", text);
或者我应该明确地将其转换为 char 指针:
char text[1024] = "text";
printf("%s", (char*) text);
我问是因为我认为它可能将数组元素直接复制到 va_list 中,而不是只放置一个指向第一个元素的指针。
是的,您可以直接传递一个数组。确切地说,数组名代表数组的地址,与 . 没有区别char *
。
(char*)text
在这个例子中text
几乎没有任何区别!当作为函数参数传递时,数组的基地址衰减为指针。
事实上,即使text
不是char
数组,也几乎没有什么区别,printf
因为它是一个可变参数函数
int printf(const char *format, ...);
它只关心第一个论点。逻辑可能会出错,但printf
不在乎!
简短的回答,是的,C _are_a 中的数组指向它们的第一个元素。 (编辑:更长的答案,实际上,C 中的数组是标识符或标签,它们只是名称,但是当用作不以 & 或 sizeof 开头的表达式的一部分时,它们会被转换为指针或以其他方式评估为指针) .
更长的答案:你看,函数不能真正接收数组作为参数,但编译器必须向它们发送一些东西,所以它会向它们发送一个指针。因此,第一句话可能应该以“就功能printf()
而言......”开始
有些函数声称采用数组,但这只是一种错觉。这两个功能是一样的。
func(char *a);
func(char a[]);
下面的 C FAQ 条目更详细地介绍了数组和指针之间的细微差别:
char a[] = "this";
char *b = "that";
a[0] 生成的代码与 b[0] 完全不同,但它们大致相同,因为下标运算符 [] 为我们提供了预期的结果。
有趣的是,格式说明符 "%s\n" 也printf()
作为指针传递给。
除非它是sizeof
or 一元运算符的操作数&
,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of ”类型的表达式T
将被“pointer to T
”类型的表达式替换其值为数组第一个元素的地址。
当你写
printf("%s", text);
该表达式text
被一个新的类型的表达式替换,char *
其值为&text[0]
,而这个指针值就是传递给的值printf
。这意味着您不必强制转换参数。这也意味着您不能将数组表达式作为函数参数传递并让被调用函数将其作为数组类型接收。转换发生在调用函数之前。
指针和数组的名称是可交换的。(除了内存分配)
当你有
char *a = "abcdef";
char b[5];
你可以写
char z = a[2]; // 'c'
char x = *b;
char y = *(b+2);
但你做不到
b ++;
您可以将array b
其视为char * const b
不可修改的指针