将结构传递给c中的函数时出错

将结构传递给c中的函数时出错,c,gcc,struct,parameter-passing,C,Gcc,Struct,Parameter Passing,当我将一个结构传递给一个函数时,我得到了一个错误:应该是“structbook”,但参数的类型是“structbook”。为什么会这样 #include <stdio.h> #include <string.h> struct book { int id; char title[50]; }; int showBooks(struct book x); int main() { struct book { int id

当我将一个结构传递给一个函数时,我得到了一个错误:应该是“structbook”,但参数的类型是“structbook”。为什么会这样

#include <stdio.h>
#include <string.h>

struct book
{
    int id;
    char title[50];
};

int showBooks(struct book x);

int main()
{
    struct book
    {
        int id;
        char title[50];
    };

    struct book book1,book2;

    book1.id = 2;
    book2.id = 3;

    strcpy(book1.title, "c programming");
    strcpy(book2.title, "libc refrence");

    printf("Book\t\tID\n");

    showBooks(book1);
    showBooks(book2);
}

int showBooks(struct book x)
{
    printf("%s\t%d\n", x.title, x.id);
}
#包括
#包括
结构体的构造
{
int-id;
字符标题[50];
};
int展示册(结构书x);
int main()
{
结构体的构造
{
int-id;
字符标题[50];
};
结构书第1册、第2册;
book1.id=2;
book2.id=3;
strcpy(书名为“c编程”);
strcpy(书名为“libc参考”);
printf(“Book\t\tID\n”);
展览书(第一册);
展览书(第二册);
}
int展示册(结构书x)
{
printf(“%s\t%d\n”,x.title,x.id);
}
错误:

30:12:错误:“showBooks”的参数1的类型不兼容
展览书(第一册)

10:5:注意:应为“struct book”,但参数的类型为“struct” 图书展(结构图书x)

31:12:错误:“showBooks”的参数1的类型不兼容
展览书(第二册)

10:5:注意:应为“struct book”,但参数的类型为“struct” 图书展(结构图书x)


错误在哪里?

两个不同的结构定义定义了两种不同的类型。尽管它们都被称为
structbook
,但它们的类型不同

变量
book1
book2
具有本地结构类型,但函数需要全局结构类型的结构,因此出现错误


您可以通过删除本地结构定义来解决此问题;然后,
book1
将具有全局结构的类型等。

隐藏同名全局变量的局部变量或参数。这可能令人困惑。main()中的“struct book”隐藏了“struct book”的全局定义。 变量book1和book2是“struct book”类型,局部引用main()。 showBooks()使用参数作为book1或book2的形式参数。 实际参数使用“struct book”的全局定义,这导致类型不兼容。
注释本地定义并找出差异。

您使用的编译器是什么?gcc版本6.3.0为什么您对本书有两种定义?删除main中的一个。与书籍的重新定义无关,showBooks()函数应该返回void.lol,我喜欢这样的错误消息(不是真的)。编译器应该更清楚地表明名称可能相同,但类型记录不同。用户看到这样的错误,认为编译器已经喝了太多龙舌兰酒了:(祝贺你有100k!@JonathanLeffler,而且还在学习……在检查关于这个答案的标准时,我发现一个TU中的本地结构可以与另一个TU中的全局结构兼容(因此,另一个TU中的
struct book
可以与此代码中的
struct book
s兼容,即使这两者互不兼容!)。跨TU结构的兼容性规则很有趣,当你考虑它时,它是至关重要的。是的;问题是“内部”结构与“外部”结构不同,只是因为它是一个新的定义(尽管函数中的
struct book;
也会隐藏“外部”定义)@JonathanLeffler所以实际上可以将
book1
传递给
showBooks
——如果我们在另一个翻译单元中通过一个函数,我不认为你打算侥幸逃脱,但实际上你可能会。主要规则在C11中,尤其是。你会在哪里声明外部函数原型?它将采用这两种类型中的一种,而另一种则不一样。然而,我怀疑编译器没有什么理由去寻找借口。