%s期望'char *',但参数是'char [100]'

时间:2014-09-20 16:39:44

标签: c printf

我有以下几点:

#include <stdio.h>
typedef struct {
char s[100];
} literal;

literal foo()
{
return (literal) {"foo"};
}

int main(int argc, char **argv) {
    printf("%s", foo().s);
    return 0;
}

编译时会出现此错误(使用gcc):

  

警告:格式'%s'需要类型为'char *'的参数,但参数为2   类型为'char [100]'[-Wformat =]

any1对如何修复它有任何想法?那个函数返回类型有什么问题?

修改 问题(如果在讨论中不清楚)是c标准gcc用来编译文件。如果你使用-std = c99或-std = c11就行了。

2 个答案:

答案 0 :(得分:5)

这不是错误,而是警告,而不是-Wall产生的所有警告都是明智的。

这里的编译器是&#34;种类&#34; right:在评估之前你的参数是一个数组而不是一个指针,并且获取一个临时对象的地址有点危险。我设法通过明确使用指针来消除警告

printf("%s\n", &foo().s[0]);

此外,您应该注意到您使用的是稀有动物,即临时生命的对象,返回值或您的函数。只有在C99之后,才有一个特殊的规则允许获取这样一个野兽的地址,但这是C语言的一个极端情况,你可能会通过使用一些更简单的结构更好。指针的生命周期以表达式的结尾结束。因此,如果您尝试将指针指定给变量,比如说,稍后在另一个表达式中使用它,则会出现未定义的行为。

编辑:正如mafso在评论中所说的,使用C99之前的C版本,不允许获取函数返回值的地址。正如Pascal Cuoq所说,即使对于C99,代码的行为也是未定义的,因为在参数的评估和函数的实际调用之间存在一个序列点。 C11通过产生我上面提到的临时生命对象来纠正这个问题。

答案 1 :(得分:-1)

我并不确切地知道为什么C语言比我更多的人可以解释它,但是以这种方式写main()

int main(int argc, char **argv) {
    literal b = foo();
    printf("%s", b.s);
    return 0;
}

代码打印&#34; foo&#34;正确地在GCC 4.5.4