书接上回,咱们继续探讨函数的相关知识
一.函数的声明和定义
(1)单个文件的声明
我们一般在使用函数的时候,直接将函数写出来使用即可,如:
在上方,我已经将“ 函数调用 ”和“ 函数定义 ”部分给诸君注释出来了
以上场景是函数的定义在函数调用之前,没毛病昂
我们再看接下来的这种情况:
这种情景就是函数的调用在定义之前,在下方我们可以看到,没有任何问题;可事实真的是这样么?当然不是,当我们运行这段代码时,就会报错:
可见,这段代码是有问题的,我们可以想一个逻辑昂,我们程序的运行时,C语言编译器对源代码进行编译,一个从上到下依次顺序扫描的过程,当我们调用函数时,在我们的调用的上方却并没有找到这个函数,所以程序就会报错了,诸君都是聪明人,我相信这一点应该可以很轻松get到
这个时候有小伙伴就要说了,我有强迫症,我就想先调用再定义。这个么,当然也是可以滴,咱们兵来将挡,水来土掩,前辈们早已为我们想好了解决方案,那就是——函数声明
我们只需要事先在main函数前对我们需要调用的函数进行声明,就可以完美解决这个问题了,怎么声明呢?我们的声明函数需要交代清楚:函数名,函数的返回类型,函数的参数
像这样,程序就会进行正常编译,就不会有任何问题啦
(1)函数的调用一定要满足,先声明后使用
(2)函数的定义也是一种特殊的声明,所以如果函数定义放在调用之前也是可行的
(当然啦,我个人认为诸君最好还是将定义放在调用之前嘛,养成良好的写代码习惯这也是很重要的一点)
(1)多个文件的声明
现阶段我们还处于一个学习的阶段,还是初期,我们写的代码都很简单,简洁。若是以后我们出身社会了,工作了,一般在企业中我们当码农的时候,那时候需要我们写的代码就比较繁杂了。因此,当我们需要编写一个较大的程序时,我们不会将所有代码都放在一个文件中,而是往往会根据这个程序中的各个不同的功能,将代码分类拆分放在多个文件中
一般情况下,我们会将函数的声明、类型的声明放在头文件(.h)中,将函数的实现部分放在源文件(.c)
如图:我将声明单独放在头文件中,将函数的实现放在一个源文件中,将函数的调用放在一个源文件中,诸如此类,相信这点诸君不难理解
二. static 和 extern 关键字
在讲解static 和 extern 之前,我先来带大家了解了解作用域和生命周期
(1)作用域(scope)
作用域是一个程序设计概念,咱们通俗地来讲,一段程序代码中所用到的名字并不是总是有效的,而限定这个名字的可用性的代码范围就是这个名字的作用域
1 . 局部变量的作用域是变量所在的局部范围
2 . 全局变量的作用域是整个工程(项目)
(2)生命周期
1 . 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域生命周期结束
2 . 全局变量的生命周期是:整个程序的生命周期
(3)static 和 extern
static 和 extern 都是C语言中的关键字,那它们有什么区别,分别用来干什么呢?诸君莫急,我来为大家一 一 道来
1 . static
static 是“ 静态的 ”的意思,它可以被用来修饰局部变量,修饰全局变量,修饰函数
总结:static 修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本来一个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。但是作用域不变的
2 . extern 和 static 修饰全局变量
extern 是用来声明外部符号的,一般用于我们在一个文件中去引用另一个文件的全局变量
如图,如果一个全局的符号在A文件中定义的,在B文件中想使用,就可以使用 extern 进行声明,然后使用
这个代码,当我们使用 static 对全局变量进行修饰时,我们就不能在另一个文件引用该变量,即使是使用 extern 声明也不行
如图,该代码在编译的时候会出现链接性错误
总结:一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。本质原因是全局变量默认是具有外部链接属性的,在外部的文件中想使用,只要适当的声明就可以使用;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在自己所在的源文件内部使用,其他源文件,即使声明了,也是无法正常使用的
3 . static 修饰函数
这一点不难理解,咱们直接上图昂
这个时候我们的程序是可以正常运行的
如图,当我们使用 static 修饰了另一个文件的函数时,我们在源文件就不能引用该函数,这一点跟我们 static 修饰全局变量是一样的
总结:一个函数在被 static 修饰之后,就只能在本文件内部使用,其他文件无法正常的链接使用。这一问题的本质是:函数默认是具有外部链接性的,正是因为这一性质,使得函数在整个工程中只要有声明就可以被使用;但当我们使用 static 修饰该函数后,这一外部链接属性变成了内部链接属性,就使得函数只能在自己所在的源文件内部使用
OKK,有关函数的板块咱们就总结完了,这部分,相当相当相当重要!!!这是我们写大型程序的必要基础,所以诸君一定要重视,最好就是自己去不断的动手练习,纸上得来终觉浅,绝知此事要躬行嘛,这是亘古不变的道理,踏踏实实打好基础。好了,也没啥多说的,咱们下期再见吧!与诸君共勉!!!