这篇文章将学会看懂和使用register关键字和extern关键字。
1、register关键字
翻译为“寄存器” 即用它所修饰的变量称之为寄存器变量 。作用是让编译器尽可能将变量存在CPU内部寄存器中。使用形式:register 类型 变量名;比如register int a;那么为什么要将量存在CPU内部寄存器中?不是有内存和外存吗?我们知道,计算机中CPU对寄存器、cache、内存、外存访问速度依次为寄存器>cache>内存>外存。当然了,对寄存器的访问速度最快,可不是说我们在编程的时候把每一个变量的修饰符都写为register。原因其一寄存器数量不多,不可能将所有变量都放到CPU内部的寄存器中。原因其二不可能每一个变量都需要CPU快速执行,也就是说事情总是有轻重缓急的,我们一般是把需要CPU快速处理或者频繁访问的变量加上register修饰符,从而缩短CPU从内存抓获取数据的时间,进而提高执行效率。但是加上register修饰符的变量未必都存放在寄存器中,因为寄存器的数量是有限的,修饰符会被编译器忽略,也不会报错。
使用register注意以下几点:
(1)不能用&访问register变量的地址:因为&获取的是内存地址,而register变量保存的是CPU中寄存器中的地址;
(2)只能修饰局部变量,不可修饰全局变量或函数:因为一个变量只能声明一种存储类型
(3)只修饰CPU所能接受的数据类型:因为CPU要直接访问寄存器
2、extern关键字
主要作用是可以在当前.c文件中引用别的.c文件中定义的全局变量和非static函数。通常都是在与要引用的.c文件相对应的.h文件中对这些全局变量和函数进行声明,在当前.c文件中直接用#include来包含声明全局变量和函数的头文件。这里有几点需要注意。
(1)为什么要在当前.c文件中引用别的.c文件中的内容?原因是:如果你要实现的功能非常简单,在一个.c文件中就可以完成,那么确实不用;如果功能比较复杂,你还要在一个.c中实现所用功能,那只能说太死板了,代码过程不利于阅读代码,也不便于后期维护,在公司实际做项目时经常是团队合作,分模块完成各自的任务,然后再将代码组合到一起。不仅便于阅读代码也便于后期维护。强调一点:模块化编程的思想非常重要 就是把一个大的任务按功能分成相应模块 ,然后对每一模块创建.c和.h文件 方便最后整合。
(2)可以引用别的.c文件中定义的全局变量和非static函数?注意一定是全局变量,而不是局部变量,因为局部变量的作用域是代码块,在栈上存储。代码块运行完之后局部变量就没有了。如果这个全局变量不想被修改,也可以加上const关键字进行修饰;这里的函数时全局函数,也就是说在这个函数的定义前没有static关键字进行修饰,在前面文章讲到static修饰函数时表明这个函数只能在本文件中被使用,不能再别的文件中使用。
下面用代码来演示extern修饰变量和函数:
1)演示修饰变量
有3个文件:main.c extern.c extern.h main.c文件要访问extern.c文件中定义的全局变量a(通过#include "extern.h"方式),在extern.h中对全局变量a用extern修饰。
main.c代码
运行结果:main.c可以访问extern.c中的全局变量a
如果extern.h中没有extern int a;main.c还要访问变量a,则会报错,提示a没有定义:
如果extern.h中没有extern int a;改为extern int a=10;也会出错,显示定义变量a多次:
如果要访问 extern.c中的局部变量b就会出错,因为变量b作用域与代码块即fun函数内部。
出错提示b没有定义如下图所示:
2)演示修饰函数
有3个文件:main.c extern.c extern.h main.c文件要访问extern.c文件中定义的函数fun(通过#include "extern.h"方式),在extern.h中对函数fun用extern修饰。
main.c代码
运行结果:main.c可以访问extern.c中的函数fun
如果extern.c中的函数fun前面有修饰符static,则会出错,提示fun没有定义。如下图所示:
以上就是register和extern关键字的用法,register在应用层用的不多,extern用的比较多。这些关键字都是必备知识,多敲代码,上机实战,理解才是王道。