我正在try 以这种方式编写一个C头文件:

// header.h
#ifndef HEADER_H
#define HEADER_H

extern int add(int a, int b);

#endif
// header.c
#include "header.h"

int add(int a, int b)
{
    return (a+b);
}

现在假设我有一个main.c文件,如下所示:

// main.c
#include <stdio.h>
#include "header.h"

int main(void)
{
    print("%d", add(2,3));
    return 0;
}

编译main.c时出错,GCC说"未定义对‘Add’的引用".你能解释一下我哪里出错了吗?

EDIT:
I think I didn't make myself very clear previously. What I am actually trying to say is that, I've seen that most C programmers follow the above mentioned style of writing the header files, and I've also heard that this reduces the size of the final binary that's generated. I'm trying to do something similar but I get an error every time I try to compile my code. I added that extern keyword so that the compiler understands that the function is defined somewhere externally, but it still failed to compile.

如何在实现上述编程风格的情况下成功编译上述代码?

推荐答案

有两个问题:

header.h

// header.h
#ifndef HEADER_H
#define HEADER_H

int add(int a, int b);

#endif
  • 你不需要"外部"
  • 你不应该有拖尾"/"
  • 在最后的"#endif"之后应该有一个换行符

Example gcc command:

gcc -g -Wall -pedantic main.c header.c -o myprog

您需要编译both个"main.c"和"header.c",并在构建中包含这两个".o"文件.

听起来"未定义的引用"是一个链接器错误:您可能没有包括"header.o".

C++相关问答推荐

C中的整字母后缀i是什么

Pure Win32 C(++)-除了替换控件的窗口程序之外,还有其他方法可以在输入时禁用按钮吗?

strftime函数中%s的历史意义是什么?为什么没有记录?

*p[num]和(*p)num的区别

为什么C语言允许你使用var =(struct NAME){

如何将字符**传递给需要常量字符指针的常量数组的函数

在Rust和C之间使用ffi时如何通过 struct 中的[U8;1]成员传递指针

在WSL关闭/重新启动后,是什么原因导致共享对象依赖关系发生更改?

从uint8_t*转换为char*可接受

一旦运行长度超过2,编译器是否会优化";strnlen(mystring,32)>;2";以停止循环?

I2C外设在单次交易后出现故障

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

Cairo STM32MP1 cairo_Surface_WRITE_TO_PNG始终返回CAROLIO_STATUS_WRITE_ERROR

如何将C中的两个字符串与从文件接收的字符串中的字符数进行比较

GETS()在C++中重复它前面的行

在C中使用无符号整数模拟有符号整数

为什么我在我的代码中得到错误和退出代码-1073741819(0xC0000005),但如果我添加了一个不相关的打印语句,它仍然有效?

macos/arm64 上地址空间不使用第一位吗?

memcmp 是否保证按顺序比较字节?

多行表达式:C 编译器如何处理换行符?