我有一个程序,由三个文件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:||对"jumbo"的未定义引用|
- ||错误:ld返回1退出状态|
我做错了什么?如何使用头文件包含不同文件中的函数和变量?
对jumbo
的未定义引用很可能是因为您的编译中没有包含01.c
。
当您包含头01.h
时,您只是包含函数原型,您向编译器承诺存在具有该名称、参数和返回类型的函数。当代码被编译时,编译器会寻找这样的实现,如果没有找到,它就无法编译程序,因为它不知道这种函数应该做什么。
要真正包含函数实现,您需要编译并链接实现函数的文件,在本例中为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
^^^^^^^^^^^^^^^^^^^^^^^
这里有一个活样本
请参阅此C参考网站。然后阅读一些C11标准,如n1570,并在编译时启用所有警告和调试信息。如果使用GCC编译器,请将其作为gcc -Wall -Wextra -g
调用。您可以稍后使用GDB调试器。
您可能想要:
- 在头文件
01.h
中声明extern int b;
- 在一个实现文件中定义
int b;
,例如在main.c
中
当然,您应该只有一个main
函数。
从一些现有的C开源软件的源代码中获得灵感,例如GNUmake或GNUbash。
不要忘记阅读C编译器、源代码编辑器(例如GNUemacs(和调试器的文档。
对于现实生活中的程序,记录(用铅笔和纸,或使用LaTeX(软件架构和一些编码约定。有关示例,请参阅GTK项目。
您可以使用doxygen从以指定方式格式化的注释中生成一些文档。
您可以使用Clang静态分析器。