在C中创建自己的头文件


Answers:


298

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;
}

main.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

2
@Anu:我看不懂这种格式。您可以编辑原始问题以包含此代码。
奥利弗·查尔斯沃思

3
值得注意的是,如果您仅尝试通过按钮进行构建(例如在Code :: Blocks中为“ build and run”),该代码将无法正常工作。对于您来说,这似乎很明显,但是对我而言,这是第一次发生,我花了相当长的时间才找出问题所在。
Jeyekomon 2014年

5
@Jeyekomon:嗯,这里什么问题?
奥利弗·查尔斯沃思

2
没有人告诉我,“构建并运行”按钮不足以容纳所有内容。:-)这对我来说是一个惊喜(我是新手)。现在,我想我必须先学习使用命令行或makefile。
Jeyekomon 2014年

1
我想知道您是否可以详细说明如何编译所有必需的文件,而不必将foo.c包含在gcc程序参数中。这种技术叫什么技术,或者什么程序可以在IDE之外实现此功能-我想起了Make
2014年

26
#ifndef MY_HEADER_H
# define MY_HEADER_H

//put your function headers here

#endif

MY_HEADER_H 充当双重包容护卫。

对于函数声明,您只需要定义签名,即没有参数名称,如下所示:

int foo(char*);

如果确实需要,还可以包括参数的标识符,但这不是必需的,因为标识符只能在函数的主体(实现)中使用,而在标头(参数签名)的情况下,它将丢失。

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

在源文件中,您将具有:

#include "my_header.h"

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

它们被称为函数声明或函数原型,而不是“函数标头”。标头是您包括的文件,而不是其中的声明。
乔纳森·韦基利

@JonathanWakely这些是头文件。名称说明了一切:头文件包含头。但是,感谢您的反馈,这让我想了一秒钟。
Flavius

不,标头是文件本身,而不是它们包含的声明。您可以找到一个信誉良好的参考来备份对“标头”的使用吗?例如,它与K&R,C标准,UNIX编程环境Wikipedia相矛盾。
乔纳森·韦克利

@JonathanWakely您真的读过K&R吗?TOC的“ 4.5头文件”部分和“头文件”用斜体字表示,表示术语。在本书的其余部分中,作者有时为了简洁起见只写了“标题”,但是通过格式化和TOC可以清楚地知道什么是正确的术语。因此,请成为一名专业人士,并在错误时识别自己。
Flavius

是的,“标头”是指文件,而不是其中的声明。在第二版中,有关标准标头的讨论,请参见第241页;有关定义声明(您误称为“函数标头”)的第33页,并明确定义了标头:“通常的做法是收集extern变量的声明和函数在一个单独的文件中,该文件在历史上称为标头,包含#include在每个源文件的开头。例如,标准库的功能在标头中声明,例如<stdio.h>
乔纳森·韦基利

8

myfile.h

#ifndef _myfile_h
#define _myfile_h

void function();

#endif

myfile.c

#include "myfile.h"

void function() {

}

void function();作为声明不会阻止像这样的调用function(42);。用void声明一样void function(void);
chux -恢复莫妮卡

5

头文件包含您在.c或.cpp / .cxx文件中定义的函数的原型(取决于您使用的是c还是c ++)。您希望在.h代码周围放置#ifndef /#defines,以便在程序的不同部分中两次包含相同的.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,如下所示:

客户端

#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,则原型仅包含一次。” 这是误导。他们避免从相同的源文件中两次包含相同的头文件(可以在两个不同的源文件中两次包含一个头文件,并且通常是必需的!),并且重新声明函数原型不是问题,重新定义类型和全局变量是必须警惕的。
乔纳森·韦克利
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.