gpt4 book ai didi

header 可以使用源文件中定义的宏定义吗?

转载 作者:行者123 更新时间:2023-11-30 16:10:56 25 4
gpt4 key购买 nike

我正在尝试使用固定长度数组来实现堆栈。我想创建 Stack 的多个实例,因此我的堆栈实现位于 stack.h header 中。

stack.h


#ifndef STACK_H
#define STACK_H

typedef int Item;

typedef struct stack{
Item array[SIZE];
int current_size;
}Stack;

Stack *create_stack(void);
void push_stack(Stack *stack, Item value);
Item pop_stack(Stack *stack);

#endif

但是,我想将数组的 SIZE 保留为私有(private),因此我在 stack.c 中定义了它

stack.c

#include "stack.h"

#define SIZE 100

Stack *create_stack(void)
{
....
}

void push_stack(Stack *stack, Item value)
{
....
}

Item pop_stack(Stack *stack)
{
....
}

这可能吗?在源文件中定义了宏,但在头文件中使用了宏?谢谢

最佳答案

从技术上讲,您应该将#include预处理器指令视为“复制和粘贴”指令。

这基本上意味着最终结果是一个包含按指定顺序排列的所有文本的单个文件。

当然,在这种情况下,您的代码会出现错误,因为 SIZE 仅在使用之后才定义。

考虑一下,在stack.c中:

#define SIZE 100
#include "stack.h"

这将允许在 stack.h 中使用 SIZE

此外,如果不在 header 中定义 SIZE(至少作为后备值),如果不先手动定义 SIZE,您将无法在任何地方包含 header .

考虑在标题中添加:

#ifndef SIZE
#define SIZE 10
#endif

恕我直言,这种方法不是使用此功能的理想方式,但这应该可以回答您的问题。

恕我直言,最好的方法是使用不完整的类型或“灵活的数组”。

例如,您可以使用以下方式定义类型:

typedef struct stack{
int current_size;
Item array[];
} Stack;

然后使用(例如)分配足够的内存来管理堆栈大小:

Stack * s = malloc(sizeof(*s) + (SIZE*sizeof(Item)));

但是,我可能会选择使该类型成为不透明指针。

这意味着只能使用函数访问数据。

使用不透明指针将提供更强的划分。

它还允许您将来更新数据类型而不破坏 ABI/向后兼容性,这也很有帮助。

即,在标题中将自己限制为:

typedef struct stack Struct;

这些函数将使用指向不完整类型的指针。

Stack *create_stack(void);

这将保证使用 header 的任何人都无法访问数据(他们将收到有关访问不完整类型的错误)。

C 文件将仅定义其内部使用的结构:

struct stack{
Item array[SIZE];
int current_size;
};

或者,使用动态大小方法,如上所述:

struct stack{
int current_size;
Item array[];
};


Stack *create_stack(size_t size)
{
Stack * s = malloc(sizeof(*s) + (size * sizeof(*s->array)));
// ....
return s;
}
<小时/>

附注- 恕我直言

作为有关命名的注释...您似乎正在使用 CamelCase 命名约定。

在 C 语言中,您会发现大多数开发人员倾向于使用 Snake_case 而不是 CamelCase 来命名。

此外,typedef 通常有一个后缀,类似于 POSIX 和某些标准类型使用的(保留的)_t 后缀(即结构类型可能以 _s 结尾) .

这些只是我的个人意见,但作为一个长期的代码阅读者,我发现阅读与语言提供的标准库风格相匹配的代码更容易。显然,并不是每个人都同意我的观点。

使用这些命名约定,我将这些类型命名为:

typedef int item_i;

typedef struct stack{
int current_size;
item_i array[SIZE];
} stack_s;

关于 header 可以使用源文件中定义的宏定义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58776158/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com