【问题标题】:extern void pointer in C fileC文件中的extern void指针
【发布时间】:2015-10-21 12:22:34
【问题描述】:

我正在制作一个程序,我决定将其拆分为两个 .c 文件。第一个 program.c 文件包含所有包含文件和声明,另一个 unit.c 文件有十几个函数和一些在主程序中定义的全局变量的外部声明。c

到目前为止,一切工作正常(编译/链接),在 unit.c 中声明并在 program.c 中定义的外部变量是 int 或 float 等内置类型。当我尝试从包含在 program.c 但不在 unit.c 中的头文件中使用新类型的变量时,通常编译器会抱怨。

具体情况是这样的:

程序.c

#include "SDL.h"
int a;
SDL_Surface* sprite;
SDL_Surface* ghost;

单位.c

extern int a; //works fine
extern SDL_Surface* sprite; //compiler error
extern SDL_Surface* ghost; //compiler error
void funct1 (void)
{
    if (sprite == ghost)
    ....
}

如果我在 unit.c 的顶部包含 SDL.h,问题就解决了,但我不想在任何地方都包含所有内容,所以我想出了一个完整的解决方案。我仅在 unit.c 中声明 sprite 和 ghost 的类型为 void 指针,但 program.c 中的定义保持不变。像这样:

单位.c

extern void* sprite;
extern void* ghost;

编译器没有抱怨。我只需要那些外部指针来测试它们是否指向相同的地址。我对可执行文件进行了一些测试,它工作正常。

我正在使用免费的命令行 Borland 编译器版本 5.5.1

问题是,这在 ANSI C 中可以被认为是合法的,还是 Borland 编译器的一些怪癖? 在我的情况下,将 SDL.h 包含在 unit.c 中是唯一真正的(最佳实践)解决方案,还是请您指出其他一些合法的替代方案?

【问题讨论】:

  • 如果你不想在任何地方都包含 SDL,你应该封装 spriteghost 对象,例如,制作你自己的 Entity 结构,而不是依靠这个技巧.

标签: c


【解决方案1】:

不,这是合法的。您可以将任何数据指针转换void*,但不能假装现有指针是void*

解决方法是创建标题program.h,并将其包含到unit.c

#ifndef PROGRAM_H
#define PROGRAM_H
#include "SDL.h"
extern int a;
extern SDL_Surface* sprite;
extern SDL_Surface* ghost;
#endif

不要不惜一切代价避免在 .c 文件中包含标头;这是 C 语言的标准做法,也是避免问题的最佳方法。

【讨论】:

  • 如本文所述:
  • 如本文所述:link 最佳实践是使用关键字extern 在一个头文件中声明全局变量,因此它们仅被声明而不被定义,然后您可以包含它文件无处不在。您只需要在一个源文件中定义一个全局变量。 extern 关键字的很好解释:link 我什至不必声明:extern void* ghostextern ghost 就足够了
  • @b'stard 我认为省略类型不是一个好主意。据我所知,extern ghost 被解释为extern int ghost
【解决方案2】:

SDL_Surface 未在 unit.c 中定义。

添加

#include "SDL.h"

到unit.c

【讨论】:

  • 必须定义SDL_Surface。这是唯一的答案。
  • @AndrewHenle 没有。他只需要声明 SDL_Surface。此声明不必完整。
猜你喜欢
  • 2011-04-01
  • 2010-09-29
  • 2014-05-30
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多