【问题标题】:Creating your own header file in C在 C 中创建自己的头文件
【发布时间】:2011-10-29 21:53:44
【问题描述】:

谁能用一个简单的例子从头到尾解释如何用C创建头文件。

【问题讨论】:

标签: c header include include-guards c-header


【解决方案1】:

foo.h

#ifndef FOO_H_   /* Include guard */
#define FOO_H_

int foo(int x);  /* An example function declaration */

#endif // FOO_H_

foo.c

#include "foo.h"  /* Include the header (not strictly necessary here) */

int foo(int x)    /* Function definition */
{
    return x + 5;
}

ma​​in.c

#include <stdio.h>
#include "foo.h"  /* Include the header here, to obtain the function declaration */

int main(void)
{
    int y = foo(3);  /* Use the function here */
    printf("%d\n", y);
    return 0;
}

使用 GCC 编译

gcc -o my_app main.c foo.c

【讨论】:

  • @Anu:我无法以这种格式阅读。您可以编辑原始问题以包含此代码。
  • 值得注意的是,如果您尝试仅通过按钮构建它(例如 Code::Blocks 中的“构建并运行”),则此代码不起作用。这对你来说似乎很明显,但对我来说这是第一次发生,我花了很长时间才弄清楚问题出在哪里。
  • @Jeyekomon:嗯,在哪里有问题?
  • 没有人告诉我“构建并运行”按钮不足以满足所有需求。 :-) 这对我来说是一个惊喜(我是新手)。现在我想我必须先学会使用命令行或makefile。
  • 我想知道您是否可以详细说明如何使用所有必需的文件进行编译,而不必将 foo.c 包含到 gcc 程序参数中。这种技术叫什么或者什么程序可以在 IDE 之外完成这个任务 - Make 出现在我的脑海中
【解决方案2】:
#ifndef MY_HEADER_H
# define MY_HEADER_H

//put your function headers here

#endif

MY_HEADER_H 用作双重包含保护。

对于函数声明,只需要定义签名,即不带参数名,像这样:

int foo(char*);

如果你真的想要,你也可以包含参数的标识符,但这不是必需的,因为标识符只会在函数的主体(实现)中使用,如果是标头(参数签名),它会丢失。

声明函数foo接受char*并返回int

在您的源文件中,您将拥有:

#include "my_header.h"

int foo(char* name) {
   //do stuff
   return 0;
}

【讨论】:

  • 它们被称为函数 declarations 或函数 prototypes,而不是“函数头”。标头是您包含的文件,而不是其中的声明。
  • @JonathanWakely 这些是头文件。这个名字说明了一切:头文件包含头文件。但是感谢您的反馈,这让我想了一会儿。
  • 不,标题是文件本身,而不是它们包含的声明。你能找到一个有信誉的参考来支持你对“标题”的使用吗?例如,它与 K&R、C 标准、UNIX 编程环境Wikipedia 相矛盾。
  • @JonathanWakely 你真的读过 K&R 吗? TOC 有一节“4.5 头文件”,“头文件”用斜体书写,表示术语。在本书的其余部分中,作者有时只写“标题”以求简洁,但通过格式化和 TOC,可以清楚地知道什么是正确的术语。所以,请成为专业人士,并认清自己的错误。
  • 是的,“header”指的是文件,而不是其中的声明。在第 2 版中,参见第 241 页讨论标准头文件,第 33 页讨论 definitionsdeclarations(您错误地将其称为“函数头文件”)并明确定义a header:“通常的做法是将变量和函数的 extern 声明收集在一个单独的文件中,历史上称为 header,包含在 #include 中每个源文件的前面。例如,标准库的函数在像&lt;stdio.h&gt;这样的头文件中声明。"
【解决方案3】:

我的文件.h

#ifndef _myfile_h
#define _myfile_h

void function();

#endif

我的文件.c

#include "myfile.h"

void function() {

}

【讨论】:

  • void function(); 作为 声明 不会阻止像 function(42); 这样的调用。在声明中使用void,如void function(void);
【解决方案4】:

头文件包含您在 .c 或 .cpp/.cxx 文件中定义的函数的原型(取决于您使用的是 c 还是 c++)。您想在 .h 代码周围放置 #ifndef/#defines,这样如果您在程序的不同部分包含两次相同的 .h,则原型仅包含一次。

client.h

#ifndef CLIENT_H
#define CLIENT_H

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);


#endif /** CLIENT_H */

然后您将在 .c 文件中实现 .h,如下所示:

client.c

#include "client.h"

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
 short ret = -1;
 //some implementation here
 return ret;
}

【讨论】:

  • “这样,如果您在程序的不同部分包含两次相同的 .h,则原型仅包含一次。” 这是误导性的。他们防止两次包含相同的头文件来自同一个源文件(在两个不同的源文件中包含两次头文件是可以的,而且通常是必需的!)并且重新声明函数原型不是问题,必须谨防重新定义类型和全局变量。
  • 这对我来说并不完全直观——也许它与我需要了解的预处理器的具体实现有关。为什么#ifndef#define 指令不在库文件的源代码中使用(即上面示例中的foo.c),而不是在该库的头文件中?是因为编译器知道它只有一个foo.c 的实际定义吗?
猜你喜欢
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 2010-10-12
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多