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修饰符
C语言 extern学习2 分析的更多相关文章
- C语言 extern学习1
没有头文件时,通过本文件内的函数声明来确定定义域,实现功能: //单文件测试 #include <stdio.h> /* 经测试,C语言环境下子函数默认是void型:所以可省略不写 为严谨 ...
- [转]C语言指针学习经验总结浅谈
指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...
- 个人作业-2 英语学习APP分析
产品: 必应词典 PC版 第一部分:调研,评测 1.对于这款产品的第一感觉是界面做的有点生硬粗糙,而且界面有种很空的感觉,界面美化做的不是很好,第一印象不是很喜欢.不过一点,就是把单词的近义词反义词放 ...
- R语言︱词典型情感分析文本操作技巧汇总(打标签、词典与数据匹配等)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:情感分析中对文本处理的数据的小技巧要 ...
- C语言课程学习的总结
C语言课程学习的总结 学习C程序这门课一年了,这是我们学的第一门专业课.在大学里,C语言不但是计算机专业的必修课程而且也是非计算机专业学习计算机基础的一门必修课程.所以作为我这个计算机专业的学生来说当 ...
- C语言(函数)学习之strstr strcasestr
C语言(函数)学习之[strstr]&[strcasestr]一.strstr函数使用[1]函数原型char*strstr(constchar*haystack,constchar*needl ...
- 【Go语言】学习资料
这段时间一直在看Go语言,6月3日Apple发布了swift发现里面竟然也有许多Go语言的影子,截至现在每天都在感觉到Go语言的强大.确实值得一学 今天在这里给园友们推荐一些Go语言的学习资料 网站 ...
- 远离go path,弃用go get,使用go mod 进行go语言的学习
标题说的是go语言的学习,因为我也没做过开发 文章要解决的仅仅是一个问题 当你使用go get 无论如何get不到所需的包的问题 第一步就是下载goland 新手极其推荐goland,因为直接使用gl ...
- Dart语言快速学习上手(新手上路)
Dart语言快速学习上手(新手上路) // 声明返回值 int add(int a, int b) { return a + b; } // 不声明返回值 add2(int a, int b) { r ...
随机推荐
- Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件!
源:Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件! 2014年02月06日发布控件的重要更新版本: Victor 串口控件 1.5.0.2 版本 (包 ...
- 基于FPGA的OLED真彩色动态图像显示的实现
源:基于FPGA的OLED真彩色动态图像显示的实现 作为第3代显示器,有机电致发光器件(Organic Light Emitting Diode,OLED)由于其主动发光.响应快.高亮度.全视角.直流 ...
- springmvc的jdbcTemplate 插入 返回主键
public int insertCustomer(final Customer customer) { //TODO. final String sql = " ...
- C++中string中的erase函数怎么使用
erase函数的原型如下:(1)string& erase ( size_t pos = 0, size_t n = npos );(2)iterator erase ( iterator p ...
- 步进控件——UIStepper
步进控件,可用于替换传统用于输入值的文本框.步进控件提供了“+”和“-”两个按钮,用来改变stepper内部value的增加或减少,调用的事件是UIControlEventValueChanged.由 ...
- 如何让搜索引擎抓取AJAX内容? 转
越来越多的网站,开始采用"单页面结构"(Single-page application). 整个网站只有一张网页,采用 Ajax 技术,根据用户的输入,加载不同的内容. 这种做法的 ...
- 如何用 Git 合并两个库,并保留提交历史
转载自 https://segmentfault.com/a/1190000000678808 背景 一个中型规模项目,开始规划时就打算采用 C/S 架构,后端是单纯的 API 服务,前端在 Web ...
- osgEarth基础入门(转载)
osgEarth基础入门 osgEarth是基于三维引擎osg开发的三维数字地球引擎库,在osg基础上实现了瓦片调度插件,可选的四叉树调度插件,更多的地理数据加载插件(包括GDAL,ogr,WMS,T ...
- 初学杂文 String类
String: 两个字符床 String stra 和String strb stra = "hello " ; strb = "hello " 在对象池中开 ...
- Angular - - angular.Module
angular.Module Angular模块配置接口. 方法: provider(name,providerType); name:服务名称. providerType:创建一个服务的实例的构造函 ...