第一次作业(4.C语言)

1.static

static是让该关键字标识的函数或变量只在本地文件可见,同一个程序的其它文件是不可见该函数的,也就是文件作用域的。

2.extern

外部存储类型,extern 对于非函数的对象是有用的,因为对象声明时会带来内存的分配,而用 extern就表示该对象已经声明过了,不用再分配内存.带extern的对象说明是对象的声明,不是对象的定义。

3.inline

用来声明内联函数,编译器看到inline就为该函数创建一段代码,以便在后面每次碰到该函数的调用都用相应的一段代码来替换。内联函数可以在一开始仅声明一次。内联函数必须在被调用之前声明或定义。内联函数中不能有复杂的结构控制语句,如:switch,while.如果有这些语句,则编译时将该函数视为普通函数那样产生函数来调用,递归函数不能被用来做内联函数。

另外,使用inline会增加二进制映像的大小,而这会降低访问CPU高速缓存的速度,所以不能在所有的函数定义中使用它。

4.static inline

static inline的内联函数,一般情况下不会产生函数本身的代码,而是全部被嵌入在被调用的地方。如果不加static,则表示该函数有可能会被其他编译单元所调用,所以一定会产生函数本身的代码。所以加了static,一般可令可执行文件变小。内核里一般见不到只用inline的情况,而都是使用static inline。

5.extern inline

 GNU89:不会生成一个非内联的版本,但是可以调用一个非内联版本(因此你必须在其它编译单元中定义它)。只能有一个定义的规则当然也适用,非内联版本和内联版本的代码必须是一样的。

C99 (or GNU99):和 GNU89 的 "inline" 一样, 会生成外部可见的代码,最多一个编译单元可以使用它。


GNU89:

"inline": 函数可能会被内联掉,非内联的版本总是会生成,而且外部可见,因此内联的定义在本编译单元中只能有一次,其它地方看到的是非内联版本。

"static inline":不会生成外部可见的非内联版本,可能会生成一个 static 的非内联版本。它当然可以被定义多次,因为外部看不到它。

"extern inline":不会生成一个非内联的版本,但是可以调用一个非内联版本(因此你必须在其它编译单元中定义它)。只能有一个定义的规则当然也适用,非内联版本和内联版本的代码必须是一样的。

C99 (or GNU99):

"inline":和 GNU89 的 "extern inline" 一样,没有外部可见的函数生成,但是外部可见的函数必须存在,因为有可能会用到它。

"extern inline":和 GNU89 的 "inline" 一样, 会生成外部可见的代码,最多一个编译单元可以使用它。

"static inline":和 GNU89 的 "static inline" 一样,这是唯一一个在 GNU89 和 C99之间可移植的。

最后,我们可以看大神 Linus Torvalds 如何描述 extern inline:

"static inline" means "we have to have this function, if you use it, but don't inline it, then make a static version of it in this compilation unit". "extern inline" means "I actually _have_ an extern for this function, but if you want to inline it, here's the inline-version".

6.多文件开发的好处

1.避免一而再,再而三地重复编译函数,因为编译器总是以文件为单位工作的。如果一个文件中包含的函数太多,则由于被修改的函数总是少数的几个,所以大多数正确的函数都得重新编译一次。
2. 使程序更加容易管理。可以将程序按逻辑功能划分,分解成各个源文件,便于程序员的任务安排,以及程序调试
3.把相关函数放到一特定源文件中。

7.  .h和.c文件

在很久以前,编译器只认识.c(.cpp))文件,而不知道.h是何物。 那时的人们写了很多的.c(.cpp)文件,渐渐地,人们发现在很多.c(.cpp)文件中的声明语句就是相同的,但他们却不得不一个字一个字地重复地将这些内容敲入每个.c(.cpp)文件。但更为恐怖的是,当其中一个声明有变更时,就需要检查所有的.c(.cpp)文件,并修改其中的声明,啊~简直是世界末日降临! 终于,有人(或许是一些人)再不能忍受这样的折磨,他(们)将重复的部分提取出来,放在一个新文件里,然后在需要的.c(.cpp)文件中敲入#include   XXXX这样的语句。这样即使某个声明发生了变更,也再不需要到处寻找与修改了---世界还是那么美好! 因为这个新文件,经常被放在.c(.cpp)文件的头部,所以就给它起名叫做“头文件”,扩展名是.h. 从此,编译器(其实是预处理器)就知道世上除了.c(.cpp)文件,还有个.h的文件,以及一个叫做#include命令。

虽然后来又发生很多的变化,但是这样的用法一直延续至今,只是时日久远了,人们便淡忘了当年的缘由罢了。 提到了头文件,就说说它的作用: (1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。 (2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。

预处理是编译器的前驱,作用是把存储在不同文件里的程序模块集成为一个完整的源程序. #include本身是一个简单的文件包含预处理命令,即为把include的后面文件放到这条命令这里。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值