C语言中的extern关键字是怎么用的?老师说还有个与它对应的关键字 , 是哪个啊?
谢邀 。在回答这个问题之前 , 题主应该明白 , 实际上程序员的工作就是把一个较复杂的需求 , 分解成若干个较独立的模块 , 然后继续把每个模块分解成若干更简单的工作 , 并编写C语言代码逐个实现 , 最后再合并完成需求 。在实际的C语言程序开发中 , 每一个独立模块单独占用一个文件是合适的 , extern 关键字正好可以方便程序员进行多文件编程 。
例如在某个项目中 , text.c 负责处理文本 , picture.c 负责处理图片 , video.c 负责处理视频 。整个项目的构成一目了然 , 维护很方便 。多文件编程我们从实例出发 , 建立 fun.c 文件 , 接下来自定义函数的C语言代码都在此文件编写 。再建立 main.c 文件 , main() 函数的代码编写在此文件中 , 文件布局如下图 , 请看:然后在 fun.c 文件里定义 add() 函数和全局变量 cnt , 相关C语言代码如下 , 请看:再在 main.c 文件里的 main() 函数中调用 add() 函数 , 相关C语言代码如下:编译并执行这段C语言代码 , 得到如下输出结果:虽然程序按照预期执行了 , 但是应该能在编译时发现警告信息:这是因为编译器在处理 add() 函数调用时没有找到 add() 函数的原型 , 只能根据 add(3, 4) 函数调用“推测”隐式声明:所幸编译器“推测”正确 , 因此C语言程序得以正常执行 。
C语言编译器为什么需要函数原型?这是因为编译器必须知道函数的参数类型和个数 , 以及返回值的类型 , 才能知道该生成什么样的指令 。那为什么不从函数调用的隐式声明中“推测”呢?这是因为并不是所有情况编译器都能“推测”正确的 , 一旦编译器“推测”错误 , 要么C语言程序无法编译通过 , 要么无法得到预期结果 。例如 , add() 函数的形参都是 int 型的 , 实际上我们也能传入 char 型实参 , 这时编译器就无法获得正确的参数类型了 。
对于 printf() 这种参数可变的函数 , 编译器就更不能确定它的参数类型了 。另外 , 函数的返回值类型 , 编译器也往往无法正确获得 。既然如此 , 为什么编译器不自己去搜索函数的定义呢?这是因为编译器不知道去哪里找 , 例如我们在 main.c 里调用的 add 函数在 fun.c 里 , 编译器又怎么会知道呢?extern 和 static 关键字extern 的字面意思是“外部的” , 它是C语言中的一个关键字 , 表示“外部符号” 。
你已经知道C语言编译器需要知道函数的原型 , 所以在 main.c 中 , 正确的做法应该是下面这样的 , 请看相关C语言代码:这样编译器就知道 add() 函数的原型了 , 也知道它来自于外部文件 。实际上 , 函数声明中的 extern 也可以不写 , 不过不写 extern 仍然表示 add 函数是外部符号 。应该注意到 fun.c 文件里有个全局变量 cnt , 我们能否在 main.c 中使用呢?答案是肯定的 , 使用 extern 引入定义就可以了 。
引入外部变量时 , extern 不能省略 。extern int cnt; 不是定义变量 , 因此不会为 cnt 分配空间 。另外 , 在 fun.c 中 , 我们可以把 cnt 初始化为 0 :而在 main.c 中 , 则不能再对 cnt 做初始化 , 下面这种做法是非法的 , 编译器会报错:如果不写 extern , 意思就变了 , int cnt;显然表示定义了一个变量 。
推荐阅读
- c语言学习心得,C语言学习零基础入门到..
- 华为的鸿蒙系统是是什么语言开发的?
- 汇编语言,面向机器的程序设计语言
- 第一个结构化程序设计语言是什么
- 冒泡排序代码,c冒泡排序
- 实时字幕,多语言版本
- 易语言开发手机软件 如何开发手机软件
- java语言的特点有哪些,Java语言特点
- 人类应该保护濒危语言吗,为什么要保护濒危语言
- 感谢cctv之类搞笑语言 搞笑留言感谢cctv