【问题标题】:Error when passing struct to function in c将结构传递给c中的函数时出错
【发布时间】:2018-08-24 03:30:39
【问题描述】:

当我将结构传递给函数时,我收到错误:预期为“struct book”,但参数的类型为“struct book”。为什么会这样?

#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);
}

错误:

30:12:错误:“showBooks”的参数 1 的类型不兼容
showBooks(book1);

10:5:注意:预期为“struct book”,但参数的类型为“struct” book' int showBooks(struct book x);

31:12:错误:“showBooks”的参数 1 的类型不兼容
showBooks(book2);

10:5:注意:预期为“struct book”,但参数的类型为“struct” book' int showBooks(struct book x);

哪里出错了?

【问题讨论】:

  • 你用的是什么编译器?
  • gcc 版本 6.3.0
  • 为什么书有两种定义?删除main里面的那个。 ideone.com/RIgIYH
  • 与 book 的重新定义无关,showBooks() 函数应该返回 void。
  • 大声笑,我喜欢这样的错误消息,(不是真的)。编译器应该更清楚地表明名称可能相同,但类型记录不同。用户看到这样的错误,认为编译器的龙舌兰酒太多了:(

标签: c gcc struct parameter-passing


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您的两个不同的结构定义定义了两种不同的类型。尽管它们都称为struct book,但它们不是同一类型。

    您的变量 book1book2 具有局部结构的类型,但函数需要全局结构类型的结构,因此会出现错误。

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

    【讨论】:

    • 恭喜获得 100k!
    • @JonathanLeffler 并且仍在学习...在检查有关此答案的标准时,我发现一个 TU 中的本地结构可以与另一个 TU 中的全局结构兼容(因此,@ 987654328@ in另一个 TU 可以与此代码中的两个 struct books 兼容,即使这两个彼此不兼容!)。
    • 跨 TU 结构的兼容性规则很有趣,而且在您考虑时至关重要。是的;问题在于,“内部”struct 与“外部”不同,仅仅是因为它是一个新定义(尽管函数中的struct book; 也会隐藏“外部”定义)。
    • @JonathanLeffler 所以实际上可以将book1 传递给showBooks -- 如果我们通过另一个翻译单元中的函数
    • 我不认为你打算逃脱它,但你可能会在实践中。主要规则在 C11 中§6.2.7 Compatible type and composite type ¶1§6.7.2 Type specifiers,尤其是§6.7.2.1 Structure and union specifiers。你会在哪里声明外部函数原型?它将采取两种类型中的一种,而另一种则不一样。但是,我怀疑编译器几乎没有理由去寻找诡计。
    猜你喜欢
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2015-01-03
    相关资源
    最近更新 更多