C语言 extern学习2 分析

时间:2023-03-10 02:58:02
C语言 extern学习2 分析

上一篇文章中,通过头文件声明,而调用有一个特别大的漏洞:

为什么编译器可以链接过来呢,因为默认是extern修饰的,这种类似全局作用域的功能使其可以被调用

继续加强学习:

这一次有两对C文件:

        first.c  first.h

        second.c  second.h

first.c 代码:

//多文件测试
#include "head.h"
#include <stdio.h>
void printStr() { printf("Hello world!\n"); }

first.h代码:

void printStr();   //函数定义域:从声明点延伸到源程序文本结束

相应的,second.c 代码:

#include "second.h"
#include <stdio.h>
void main() { printStr(); }

second.h代码:(重点)

extern void printStr();   //函数定义域:从声明点延伸到源程序文本结束

分析:

无疑, 在上面的second.h和first.h中,需要我们用extern标志符来修饰printStr函数的声明,这样,printStr函数就可以被导出到连接程序, 也就是实现了无论在first.c文件中调用,还是在second.c文件中调用,连接程序都会很聪明的按照我们的意愿,把他连接到first.c文件中的printStr函数的定义上去, 而不必我们在second.c文件中也要再写一个一样的printStr函数.

但是,问题随之而来:

那么我们如何来区分哪个头文件中的声明在其对应的.c文件中有定义,而哪个又没有呢?这也许不是必须的,因为无论在哪个文件中定义,聪明的连接程序都会义无返顾的帮我们找到,并导出到连接程序, 但我觉得他确实必要的. 因为我们需要知道这个函数的具体内容是什么,有什么功能, 有了新需求后我也许要修改他,我需要在短时间内能找到这个函数的定义, 那么我来介绍一下在C语言中一个人为的规范:

在.h文件中声明的函数,如果在其对应的.c文件中有定义,那么我们在声明这个函数时,不使用extern修饰符, 如果反之,则必须显示使用extern修饰符.

这样,在C语言的.h文件中,我们会看到两种类型的函数声明. 带extern的,还不带extern的, 简单明了,一个是引用外部函数,一个是自己生命并定义的函数.

所以,在first.h 中 不使用extern修饰符(因为对应的.c文件有该子函数printStr的定义)

在second.h 使用extern修饰符