按关键词阅读: 关系 文件 作用
8、这也是我讲述一件事的一贯作风,我总是想把一个东西说明白,让那些刚刚接触C的人也一样明白.上面是.h文件的最基本的功能,那么.h文件还有什么别的功能呢? 让我来描述一下我手头的一个项目吧.这个项目已经做了有10年以上了 , 具体多少年我们部门的人谁都说不太准确,况且时间并不是最主要的 , 不再详查了 。
是一个通讯设备的前台软件, 源文件大小共 51.6M, 大小共1601个文件, 编译后大约10M, 其庞大可想而知,在这里充斥着错综复杂的调用关系,如在second.c中还有一个函数需要调用first.c文件中的play1函数, 如何实现呢? Sencond.h 文件play1();
sencond.c文件* 。
9、().Play();
.例程-5在second.h文件内声明play1函数 , 怎么能调用到first.c文件中的哪个play1函数中呢? 是不是搞错了 , 没有搞错, 这里涉及到c语言的另一个特性:存储类说明符.C语言的存储类说明符有以下几个, 我来列表说明一下说明符用 法Auto只在块内变量声明中被允许, 表示变量具有本地生存期.Extern出现在顶层或块的外部变量函数与变量声明中 , 表示声明的对象具有静态生存期, 连接程序知道其名字.Static可以放在函数与变量声明中,在函数定义时,只用于指定函数名,而不将函数导出到链接程序,在函数声明中,表示其后边会有定义声明的函数,存储类型static.在数据 。
10、声明中,总是表示定义的声明不导出到连接程序.无疑, 在例程-5中的second.h和first.h中,需要我们用extern标志符来修饰play1函数的声明,这样,play1()函数就可以被导出到连接程序, 也就是实现了无论在first.c文件中调用,还是在second.c文件中调用,连接程序都会很聪明的按照我们的意愿,把他连接到first.c文件中的play1函数的定义上去, 而不必我们在second.c文件中也要再写一个一样的play1函数.但随之有一个小问题, 在例程-5中,我们并没有用extern标志符来修饰play1啊, 这里涉及到另一个问题, C语言中有默认的存储类标志符. C99 。
11、中规定, 所有顶层的默认存储类标志符都是extern . 原来如此啊,哈哈.回想一下例程-4, 也是好险, 我们在无知的情况下, 竟然也误打误撞,用到了extern修饰符, 否则在first.h中声明的play1函数如果不被连接程序导出,那么我们在在play2()中调用他时, 是找不到其实际定义位置的 .那么我们如何来区分哪个头文件中的声明在其对应的.c文件中有定义,而哪个又没有呢?这也许不是必须的 , 因为无论在哪个文件中定义 , 聪明的连接程序都会义无返顾的帮我们找到 , 并导出到连接程序, 但我觉得他确实必要的. 因为我们需要知道这个函数的具体内容是什么,有什么功能, 有了新需求后我也许要修改他 , 我 。
12、需要在短时间内能找到这个函数的定义, 那么我来介绍一下在C语言中一个人为的规范:在.h文件中声明的函数,如果在其对应的.c文件中有定义,那么我们在声明这个函数时,不使用extern修饰符, 如果反之,则必须显示使用extern修饰符.这样,在C语言的.h文件中,我们会看到两种类型的函数声明. 带extern的,还不带extern的, 简单明了,一个是引用外部函数 , 一个是自己生命并定义的函数.最终如下:Sencond.h 文件Extern play1();
上面洋洋洒洒写了那么多都是针对函数的 , 而实际上.h文件却不是为函数所御用的. 打开我们项目的一个.h文件我们发现除了函数外,还有其他的东西,。
13、那就是全局变量.在大型项目中 , 对全局变量的使用不可避免, 比如,在first.c中需要使用一个全局变量G_test, 那么我们可以在first.h中,定义 TPYE G_test. 与对函数的使用类似, 在second.c中我们的开发人员发现他也需要使用这个全局变量, 而且要与first.c中一样的那个, 如何处理? 对,我们可以仿照函数中的处理方法, 在second.h中再次声明TPYE G_test, 根据extern的用法,以及c语言中默认的存储类型, 在两个头文件中声明的TPYE G_test,其实其存储类型都是extern, 也就是说不必我们操心, 连接程序会帮助我们处理一切. 但我 。
14、们又如何区分全局变量哪个是定义声明,哪个是引用声明呢?这个比函数要复杂一些, 一般在C语言中有如下几种模型来区分:1、初始化语句模型顶层声明中 , 存在初始化语句是 , 表示这个声明是定义声明 , 其他声明是引用声明 。
C语言的所有文件之中 , 只能有一个定义声明 。
按照这个模型 , 我们可以在first.h中定义如下TPYE G_test=1;那么就确定在first中的是定义声明 , 在其他的所有声明都是引用声明 。
2、省略存储类型说明在这个模型中 , 所有引用声明要显示的包括存储类extern , 而每个外部变量的唯一定义声明中省略存储类说明符 。
稿源:(未知)
【傻大方】网址:/a/2021/0902/0024073978.html
标题:文件|头文件的作用与作用域的关系( 二 )