• C语言-入门-extern和头文件(十六)


    extern

    尽管大多数人可能理解变量或函数的“声明”与“定义”之间的区别,但是为了完整起见,我想对其进行澄清。

    声明变量或函数仅声明变量或函数存在于程序中的某个位置,但未为它们分配内存。变量或函数的声明起着重要的作用-告诉程序其类型将是什么。如果是函数声明,它还会告诉程序参数,其数据类型,这些参数的顺序以及函数的返回类型。这就是声明。

    关于定义,当我们定义一个变量或函数时,除了声明所做的一切外,它还为该变量或函数分配内存。因此,我们可以将定义视为声明的超集(或声明作为定义的子集)。

    变量或函数可以声明多次,但只能定义一次。(请记住基本原则,即不能有两个位置具有相同的变量或函数)。

    由于extern关键字将功能的可见性扩展到整个程序,因此该功能可以在整个程序的任何文件中的任何位置使用(调用),只要这些文件包含该功能的声明即可。(在适当的位置声明了函数,编译器知道该函数的定义存在于其他地方,并且可以继续编译文件)。这就是extern功能。

    我们经常会遇到这样的问题,我们的函数在调用之后定义的,那么我们程序是不知道这个函数的存在的,也就导致这函数无法使用比如:
    在这里插入图片描述
    解决办法我们可以在文件开头对函数进行声明
    在这里插入图片描述
    extern还可以配合头文件将文件内需要的变量或函数结构体等声明出来提供给其它功能使用

    .h头文件

    • 在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,前面我们已经看过 stdio.h 头文件,它是编译器自带的头文件,引用头文件相当于复制头文件的内容。

    • 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。

    • 有两种类型的头文件:程序员编写的头文件和C标准库自带的头文件 ,在程序中要使用头文件,需要使用 C预处理指令 #include来引用它

    • #include 的处理过程很简单,就是将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。但是我们不会直接在源文件中复制头文件的内容,因为这么做很容易出错,特别在程序是由多个源文件组成的时候。

    • 建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件

    • 源文件的名字 可以不和头文件一样,但是为了好管理,一般头文件名和源文件名一样.

    • 一个 #include 命令只能包含一个头文件,多个头文件需要多个 #include 命令

    • 不管是标准头文件,还是自定义头文件,都只能包含变量和函数的声明,不 能包含定义,否则在多次引入时会引起重复定义错误(!!!)

    定义头文件

    如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误。为了防止这种情况,标准的做法是把文件的整个内容放在条件编译语句中,如下:

    #ifndef 头文件名 	//头文件名的格式为"_头文件名_",注意要大写
    #define 头文件名
    
    头文件内容
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    示例代码:头文件test.h

    #ifndef _MAIN_H_    //如果没有定义头文件main.h,则执行下面的代码。这是防止重复定义
    #define _MAIN_H_	//定义头文件
    
    //下面的代码是头文件的内容
    #include//头文件
    #define ADD 1 //宏定义
    extern int x; //全局变量
    void swap(int a, int b);//函数声明
    
    #endif	//表示头文件结束
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意事项: 在头文件中声明变量必须需要加extern因为extern声明告诉编译器这个变量的定义在其他文件中,我在这里只是声明不使用,所以并不会为它分配内存。 而函数默认就有extern所以无须手动声明

    引用方式

    引用头文件的语法它的形式有以下两种:

    #include 这种形式用于引用系统头文件。它在系统目录的标准列表中搜索名为 file 的文件。
    #include "file" 这种形式用于引用用户头文件。它在包含当前文件的目录中搜索名为 file 的文件。

    在这里插入图片描述

    头文件规范

    1. 头文件中适合放置接口的声明,不适合放置实现
    2. 头文件应当职责单一,切忌依赖复杂
    3. 头文件应向稳定的方向包含
    4. 每一个 .c 文件应有一个同名 .h 文件,用于声明需要对外公开的接口
    5. 禁止头文件循环依赖
    6. c/.h禁止包含用不到的头文件
    7. 头文件应当自包含 (自包含就是任意一个头文件均可独立编译。如果一个文件包含某个头文件,还要包含另外一个头文件才能工作的话, 就会增加交流障碍,给这个头文件的用户增添不必要的负担。)
    8. 禁止在头文件中定义变量,注意定义和声明式不一样的
    9. 使用前置声明(forward declarations)可尽量减少头文件中#include的数量,也就是能依赖声明的就不要要依赖定义。
    10. 只能通过包含头文件的方式使用其它.c提供的接口,禁止在.c中通过extern 的方式使用外部函数接口
    11. 总是编写内部 #include 保护符( #define 保护)
    12. 禁止在头文件中定义变量
    13. 只能通过包含头文件的方式使用其他 .c 提供的接口,禁止在.c 中通过 extern 的方式使用外部函数接口、变量

    extern+头文件案例

    在这里插入图片描述
    在这里插入图片描述

    结构体+头文件案例

    如果一个结构体或共用体等, 会在多个文件中使用那么我们会将他定义在头文件中,这样就可以通用了
    在这里插入图片描述

    在这里插入图片描述

    点赞 -收藏-关注-便于以后复习和收到最新内容
    有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
    在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考
    免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。
    感谢,配合,希望我的努力对你有帮助^_^
  • 相关阅读:
    基于FPGA的一维卷积神经网络CNN的实现(八)激活层实现
    将时间序列转成图像——希尔伯特-黄变换方法 Matlab实现
    二叉树中序遍历--递归和迭代,妙啊
    Grafana,Loki,Tempo,Prometheus,Agent搭建日志链路监控平台
    基于微信小程序的教学教务管理系统(后台Java+SSM+MySQL)
    R语言比较两个样本的均值是否相同:使用t.test函数执行t检验通过比较来自两个总体的样本数据判断总体均值是否相同
    跨域自适应语义分割新技术
    Spring的重试机制-SpringRetry
    【Godot4自学手册】第十八节主人公的血量显示
    软件测试面试题:请你回答一下性能测试有哪些指标,对一个登录功能做性能测试,有哪些指标,怎么测出可同时处理的最大请求数量?
  • 原文地址:https://blog.csdn.net/weixin_45203607/article/details/126302278