【问题标题】:C Header file being included in another header file and both included in a c fileC 头文件被包含在另一个头文件中,并且都包含在一个 c 文件中
【发布时间】:2019-11-16 09:15:46
【问题描述】:

我有一个关于 C 中的头文件的问题。假设我有一个头文件,其中包含一个名为 cars.h 的结构汽车,如下所示:

typedef struct car_s {
    string plate;
    string model;
} car;

现在,我有另一个包含上述头文件的头文件,名为drivers.h,如下:

#include "cars.h"

typedef struct driver_h
{
    string id;
    string name;
    car own_car;
} driver;

现在,假设我有另一个文件,但这次是一个 C 文件,名为 main.c,如下:

#include "cars.h"
#include "drivers.h"

int main() {
    car c;
    driver bob;
    bob.own_car = c;
    return 0;
}

您能解释一下为什么这是错误的吗?我可以做些什么来防止任何错误?

谢谢!

【问题讨论】:

  • 首先,c 头文件中没有 string 数据类型
  • @VJAYSLN 我的坏哈哈我已经学习 C# 6 年了,这是我第一次学习 C,但有时我仍然会犯这个错误,我的意思是 char plate[10];..等等
  • person bob; 应该是 driver bob;。我没有更正它,因为它可能是问题的一部分。
  • @DavidNagy 是的,我也注意到了这一点,但这只是我此时创建的用于提问的代码。我没有使用实际的代码。感谢您指出这一点!

标签: c header main


【解决方案1】:

问题是同一个头文件可能会被包含多次。你能做些什么来防止在你的代码中多次包含相同的头文件?你可以在你的头文件中添加这个:

对于cars.h:

#ifndef CARS_H
#define CARS_H

typedef struct car_s{
    stringplate;
    string model;
}car;

#endif

这将检查这个头文件是否已经被包含,如果是则不会再次包含它,如果不是那么它将现在被包含。

你也为drivers.h做同样的事情:

#ifndef DRIVERS_H
#define DRIVERS_H

#include "cars.h"
typedef struct driver_h
{
    string id;
    string name;
    car own_car;
} 

#endif

【讨论】:

    【解决方案2】:

    包含的结果是为编译器生成了一个大文件。由于您已经在drivers.h 中包含了cars.h,但是在您的.c 文件中您再次包含了汽车,您最终会得到两次包含的文件。这将导致编译器看到双重定义,尽管相同,但可能会抱怨这种双重定义。

    一种解决方案是在您的包含文件中设置所谓的“包含保护”,如果之前包含该内容,则不会使内容可见。只需在谷歌或本网站上查找“包括警卫”即可。

    更好的解决方案是了解模块的包含结构并正确包含文件,在这种情况下只有驱动程序.h。

    【讨论】:

    • 尽管答案是正确的,但我不同意你最后的说法。确保您没有在层次结构中多次包含某个头文件并不总是容易/可能。除此之外,我不会依赖一件事还包括另一件事(如果实现发生变化怎么办?)。当然,在这个简单的例子中,我们可以确保没有多重包含,很明显drivers.h 也包含cars.h,但我不会依赖它。只需使用包含警卫并包含您打算使用的所有内容。你失去了什么?
    猜你喜欢
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    相关资源
    最近更新 更多