#undef在我的C程序中没有按预期工作

时间:2018-03-13 08:54:32

标签: c header-files

我正在编写线性列表ADT作为我在DS课程中的练习。我使用一个头文件,一个函数源代码和一个驱动程序作为整个项目。我在头文件中定义了宏“ELEMENT_TYPE”和“MAXSIZE”。我的设计是我可以#undef并立即#define驱动程序中的这两个宏将“ELEMENT_TYPE”更改为驱动程序所需的任何类型。 如果我把这些代码:

#undef ELEMENT_TYPE
#define ELEMENT_TYPE char
#undef MAXSIZE
#define MAXSIZE 50

在#define之后的头文件中,然后在驱动程序中,可以正确识别函数(例如,insert()的第二个扩充是“ELEMENT_TYPE”,使用上面的代码,IDE显示插入( )在驱动程序中接收char扩充。)但是,如果我将这些代码放入#include“foo.h”下面的驱动程序中,那么IDE无法识别功能应该接收的扩充,并使用“ELEMENT_TYPE”的初始定义,这种情况,int。谁知道我的程序出了什么问题,以致预处理指令无法正常工作?

以下是原始代码: driver.c https://paste.ubuntu.com/p/6B76vmk6nN/

linear_list.c https://paste.ubuntu.com/p/SHq4W5zkGM/

linear_list.h https://paste.ubuntu.com/p/VY8vcgFD89/

PS:我不是以英语为母语的人,所以也许有些地方我没有明确表达。指出它们,如果需要我会添加更多细节。

2 个答案:

答案 0 :(得分:1)

听起来似乎正在发生的事情是你在驱动程序中尝试#define这些值,希望它们能够在linear_list.c中保持定义。

问题是这些文件是单独编译然后链接的。放在driver.c中的#define不能更改在linear_list.c中找到的那些。

为了获得我认为您想要的效果,您需要在linear_list.h中更改这些值。这是执行此操作的最佳方法,因为该标头包含在两个源文件中,并且可能在任何使用linear_list.c中定义的函数的文件中为#include d。请记住,为了查看程序行为的变化,您需要在更改为linear_list.h之后重新编译driver.c,而不是linear_list.c。

作为旁注,在#include全局标头(如stdio.h和stdlib.h)之后,通常应该#include本地标头,如linear_list.h。在linear_list.c中,如果使用这些标识符,这些标题中的任何一个都可以覆盖您在linear_list.h中使用的值。它们看起来很常见,某些标题可能会使用它们并不难以置信,因此将来使用更独特的标识符可能是值得的。这引出了我的最后一点:在这些标识符上使用#undef而不检查它们是否会在其他地方使用可能会导致一些问题,因此您通常应该使用#ifndef进行检查。

希望有所帮助。如果我误解了请纠正我。

编辑:澄清,附加信息,信用other answer,提醒我一些重要的做法。

答案 1 :(得分:0)

源代码中的宏将替换为在源代码中使用宏时生效的宏定义。因此,使用ELEMENT_TYPE的函数声明使用最近在声明之前的宏定义。稍后更改宏不会更改函数定义。

另一种方法是仅在标题中定义ELEMENT_TYPE时才定义:

#if ! defined ELEMENT_TYPE
    #define ELEMENT_TYPE char
#endif

然后源文件可以执行以下任一操作:

  • 不要自己定义ELEMENT_TYPE。如果包含标题,则会使用默认类型char

  • 定义ELEMENT_TYPE,然后包含标题。如果需要,之后#undef ELEMENT_TYPE。将使用ELEMENT_TYPE中源文件提供的类型。

驱动程序和使用它的程序必须使用相同的类型。您无法使用一种类型编译驱动程序,而使用另一种类型编译程序。使用不同类型编译程序不会更改驱动程序。