如何使用头文件包含来自不同文件的函数和变量
How to use header files to include functions and variables from different files
我有一个包含三个文件的程序 01.h
、main.c
、01.c
.
01.h
是:
int b;
void jumbo();
01.c
是:
#include "01.h"
int main()
{
//some code
b = 7;
//some code
}
// some code
void jumbo()
{
//some code
}
main.c
是:
#include "01.h"
int main()
{
// some code
printf(" %d", b);
jumbo();
}
我遇到两个问题:
b
的打印值是 main.c
中的 0
而不是 7
.
在 main.c
中调用 jumbo()
时,编译器显示以下错误:
- main.c:|| undefined reference to `jumbo'|
- ||error: ld returned 1 exit status|
我哪里做错了,如何使用头文件来包含来自不同文件的函数和变量?
参见 this C reference website. Then read some C11 standard like n1570, and enable all warnings and debug info when compiling. If you use the GCC compiler, invoke it as gcc -Wall -Wextra -g
. You could use later the GDB 调试器。
您可能想要:
- 在头文件中声明
extern int b;
01.h
- 在一个实现文件中定义
int b;
,例如在 main.c
当然,你应该只有一个main
函数。
从一些现有的 C 开源软件的源代码中获取灵感,例如GNU make or GNU bash.
不要忘记阅读 C 编译器和源代码编辑器(例如 GNU emacs)和调试器的文档。
对于现实生活中的程序,做文档(用铅笔和纸,或使用 LaTeX) the software architecture, and some coding conventions. See the GTK 项目作为示例。
您可能希望使用 doxygen 从以指定方式格式化的评论中生成 一些 文档。
您可能想要使用 Clang static analyzer。
对 jumbo
的未定义引用很可能是因为您没有在编译中包含 01.c
。
当您包含 header 01.h
时,您只包含函数原型,您是 向编译器承诺 存在具有该名称的函数,参数和 return 类型。当代码被编译时,编译器会寻找这样的实现,如果没有找到,它就不能编译程序,因为它不知道这样的函数应该做什么。
要真正包括你需要编译的函数实现和link实现函数的文件,在本例中01.c
.
现在,如果您这样做,您将遇到一个新的错误,类似于 multiple definitions of main
。
您需要做的是从 01.c
中删除 main
实现并将此文件包含在您的编译过程中,它看起来像这样:
01.h:
int b = 7; // normally you wouldn't do this, in headers is usual to define constants only
// b is indeed a global variable and these should only
// be used if you absolutely have to
void jumbo();
main.c:
#include "01.h"
#include <stdio.h>
int main()
{
// some code
printf(" %d", b);
jumbo();
}
01.c:
// here you don't need to include 01.h
void jumbo()
{
//some code
}
这是一个可能的编译命令 gcc
:
gcc main.c 01.c -o program_name
^^^^
您可以添加一些常规警告标志来检测代码中的潜在问题:
gcc main.c 01.c -o program_name -Wall -Wextra -pedantic
^^^^^^^^^^^^^^^^^^^^^^^
我有一个包含三个文件的程序 01.h
、main.c
、01.c
.
01.h
是:
int b;
void jumbo();
01.c
是:
#include "01.h"
int main()
{
//some code
b = 7;
//some code
}
// some code
void jumbo()
{
//some code
}
main.c
是:
#include "01.h"
int main()
{
// some code
printf(" %d", b);
jumbo();
}
我遇到两个问题:
b
的打印值是main.c
中的0
而不是7
.在
main.c
中调用jumbo()
时,编译器显示以下错误:
- main.c:|| undefined reference to `jumbo'|
- ||error: ld returned 1 exit status|
我哪里做错了,如何使用头文件来包含来自不同文件的函数和变量?
参见 this C reference website. Then read some C11 standard like n1570, and enable all warnings and debug info when compiling. If you use the GCC compiler, invoke it as gcc -Wall -Wextra -g
. You could use later the GDB 调试器。
您可能想要:
- 在头文件中声明
extern int b;
01.h
- 在一个实现文件中定义
int b;
,例如在main.c
当然,你应该只有一个main
函数。
从一些现有的 C 开源软件的源代码中获取灵感,例如GNU make or GNU bash.
不要忘记阅读 C 编译器和源代码编辑器(例如 GNU emacs)和调试器的文档。
对于现实生活中的程序,做文档(用铅笔和纸,或使用 LaTeX) the software architecture, and some coding conventions. See the GTK 项目作为示例。
您可能希望使用 doxygen 从以指定方式格式化的评论中生成 一些 文档。
您可能想要使用 Clang static analyzer。
对 jumbo
的未定义引用很可能是因为您没有在编译中包含 01.c
。
当您包含 header 01.h
时,您只包含函数原型,您是 向编译器承诺 存在具有该名称的函数,参数和 return 类型。当代码被编译时,编译器会寻找这样的实现,如果没有找到,它就不能编译程序,因为它不知道这样的函数应该做什么。
要真正包括你需要编译的函数实现和link实现函数的文件,在本例中01.c
.
现在,如果您这样做,您将遇到一个新的错误,类似于 multiple definitions of main
。
您需要做的是从 01.c
中删除 main
实现并将此文件包含在您的编译过程中,它看起来像这样:
01.h:
int b = 7; // normally you wouldn't do this, in headers is usual to define constants only
// b is indeed a global variable and these should only
// be used if you absolutely have to
void jumbo();
main.c:
#include "01.h"
#include <stdio.h>
int main()
{
// some code
printf(" %d", b);
jumbo();
}
01.c:
// here you don't need to include 01.h
void jumbo()
{
//some code
}
这是一个可能的编译命令 gcc
:
gcc main.c 01.c -o program_name
^^^^
您可以添加一些常规警告标志来检测代码中的潜在问题:
gcc main.c 01.c -o program_name -Wall -Wextra -pedantic
^^^^^^^^^^^^^^^^^^^^^^^