首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ANSI C接口/实现

ANSI C接口/实现
EN

Stack Overflow用户
提问于 2014-10-05 17:34:47
回答 3查看 9.9K关注 0票数 9

我正在用C编写一个大型项目,我想使用接口(.h)和实现(.c)文件来组织它,类似于许多面向对象的语言,比如object或Java。我熟悉用C创建静态库,但我认为为我的项目创建静态库是不必要的复杂。如何在ANSI C中实现接口/实现范例?我主要使用GCC编译,但我的目标是严格遵守ANSI C和交叉编译器兼容性。谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-05 18:25:13

听起来你已经在做正确的事情了:好的C代码还在.h-文件中组织接口,在.c-文件中组织实现。

示例a.h文件:

代码语言:javascript
复制
void f(int a);

示例a.c文件:

代码语言:javascript
复制
#include "a.h"
static void helper(void) {...}
void f(int a) {... use helper()...}

示例main.c文件:

代码语言:javascript
复制
#include "a.h"
int main(void) { f(123); return 0; }

您获得了模块化,因为助手函数没有在头中声明,因此其他模块不知道它们(如果需要,可以在.c文件的顶部声明它们)。具有这种模块化减少了所需的重新编译的数量,并减少了需要重新编译的数量。(不过,每次都要进行链接)。请注意,如果您没有在头中声明帮助函数,那么您已经相当安全了,但是前面的static也会在链接期间对其他模块隐藏它们,所以如果多个模块使用相同的助手函数名称,就不会发生冲突。

如果您只使用原始类型,那么这就是您需要知道的全部内容,您可以停止在这里阅读。但是,如果您的模块需要使用一个结构,那么它就会变得更加复杂。

有问题的示例头b.h:

代码语言:javascript
复制
typedef struct Obj {
    int data;
}*Obj;
Obj make(void);
void work(Obj o);

您的模块希望将对象传入或输出。这里的问题是,内部信息泄露给了其他依赖于这个头的模块。如果表示改为float data,那么所有使用模块的都必须重新编译。解决这一问题的一种方法是只使用void*。这就是有多少程序在做这件事。但是,这很麻烦,因为每个将void*作为参数的函数都必须将其转换为Obj。另一种方法是这样做:

标题c.h:

代码语言:javascript
复制
typedef struct Obj*Obj;
Obj make(void);
void work(Obj);

执行c.c:

代码语言:javascript
复制
#include "c.h"
typedef struct Obj {
    int data;
}*Obj;

这样做的原因是,Obj是一个指针(而不是值/拷贝的结构)。其他依赖于该模块的模块只需要知道指针是否被传入或传递出去,而不需要知道指针指向什么。

票数 11
EN

Stack Overflow用户

发布于 2014-10-05 17:50:59

您必须阅读一些关于使用非OOL的OOP的内容,如http://www.cs.rit.edu/~ats/books/ooc.pdf。但是,这样做,您将永远不会有强大的OOP类型。

票数 1
EN

Stack Overflow用户

发布于 2016-11-18 00:13:50

请帮你自己一个忙,看看C接口和实现:创建可重用软件的技术

下面是我的一个仓库,它保存了一些使用C语言编写的库,使用了本书中描述的接口和实现模式。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26205329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档