C语言关键字register、extern、static、一些总结,及项目中使用的心得
首先介绍两个概念:
一、变量的生存周期:
变量从建立到撤销的时间段成变量的生存周期。静态变量,从变量产生到整个程序执行结束。当函数使用变量结束后,变量的存储空间依然存在,变量的值也会随着函数的对其的使用而改变。如在函数内定义了一个static变量,那第一次调用该函数后,该变量的值将会被保留,当第二次被调用时,该变量的值还是第一次调用结束时的值。动态变量,顾名思义,变量的存储空间是随着函数的调用动态产生和撤销的。如,在一个函数里定义了动态变量,变量的周期指从变量建立到函数结束,而不是这个程序结束。
二、变量的作用域:
变量的作用域指程序中可以引用该变量的区域,限定这个变量的可用性范围就是这个变量的作用域。变量的作用域和生存周期是不同的概念。
1. 自动变量(autovariable)
函数中的局部变量,如果不用static特别说明,则编译系统默认为自动变量,它在函数调用中分配内存空间,数据存储在动态存储区,在函数调用结束后,自动释放这些空间。
2. register
一般情况下,变量存放在内存中,当程序中用到哪个值时,将其从内存中取出送到CPU。对于频繁使用的变量,如for循环操作,为了提高效率,可以请求编译器将这个变量保存在CPU的寄存器中,即寄存器变量,从而加快程序的运行。不过现在的编译器,优化性较强,所以不必用register声明变量。
3. static
(1) static与变量
static与局部变量
在函数中的局部变量,加上关键字static,该变量就被定义成为一个静态局部变量。标识符如果被声明为static,就具有静态生命周期。它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。因此,函数执行结束后,变量的存储空间依然存在,不随函数执行结束撤销,但其他函数是不能使用它的,或者说其他函数“看不见”它。静态局部变量只在编译时赋一次初值,如果对变量没有赋初值,则在编译的时候自动赋为0,而且在函数下次调用时,变量的值保持为上次使用结束的值。
static与全局变量
在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。这时,只能在此文件中使用变量,别的文件不能使用。
对于全局变量,即使在定义前不加static,它也是按静态方式存储的,static只是影响变量的作用范围,这时可以在别的文件中使用变量。
(2) static与函数
对于函数前加static,表示此函数只能在此文件中调用,别的文件“看不见”它。这样就可以在两个文件中,使用相同的函数名称而互不影响。
(3) static与类
static与类的数据成员
1) 对于类的数据成员,在前面加上static关键字,为静态数据成员,表示这个数据成员不属于某个对象,而是所有对象都可以访问它。而且,即可以像普通数据成员那样通过对象(.操作符)访问,也可以用专有方式,通过类名(::操作符)访问静态数据成员。
2) 静态数据成员在内存中只占一份存储空间,因此,每个对象都可以改变它的值。它的存储空间不随建立的对象的撤销而撤销,而是在程序运行结束时撤销。
3) 不能用参数列表对静态数据成员初始化,如果未对其初始化,子编译系统将其初始化为0。
4) 而非静态数据成员,在产生每一个对象的时候都会对应产生这个数据的一个存储空间。
static与类的成员函数
1) 同静态数据成员类似,静态成员函数也是属于类,不属于对象,所以即可以通过对象(.操作符)访问,也可以通过类名(::操作符)访问静态成员函数。
2) 由于静态成员函数属于类,不属于特定的对象,而this指针是关于特定的对象的,所以静态成员函数没有this指针,静态成员函数一般是用来访问静态数据成员,不访问非静态数据成员(可以访问非静态数据成员,但不提倡这样做)。而非静态的共有(public)成员函数既可以访问静态数据成员也可以访问非静态数据成员。
4. extern
extern只能用来声明已定义的变量,不能用于变量的定义。
声明包括定义,但不是所有的声明都是定义。关于声明和定义的简单区分方法可以用:建立存储空间的声明称为定义性声明,把不建立存储空间的声明称引用性声明。
int a; //定义性声明,既是声明,又是定义。为变量a开辟存储空间
extern int a; //只是声明,不是定义,不为变量a开辟存储空间
(1) 在一个文件内使用extern
变量的作用域,一般是从变量的定义处开始的,如果想在定义变量之前使用这个变量,可以extern来声明外部变量来扩展它的作用域,即同一个文件内,extern声明之后就可以作用域扩大到声明处到文件结束。用extern对此变量进行声明,这里变量声明表示这个变量是已经在别的地方定义的,声明不会产生新的变量也不再给变量分配内存空间。
(2) 在多个文件内使用extern
相信很多程序小白会遇到在多个文件一起编译时,想要调用一个变量却出现各种报错的情况,这时只需要掌握extern的用法就能解决这个问题。
对于多个源文件,如果想在一个文件中使用另一个已定义的外部变量,可以在未定义该外部变量的文件内做extern声明即可以使用,编译时遇到extern,会先在文件内找是否定义了该外部变量。如果未找到则在链接时在其他文件中找。如果在两个文件中定义了一个同名变量,会出现重复定义的错误。但是需要注意在不同文件中extern声明变量,会相互影响,可能执行一个文件时改变了该全局变量的值,影响其他文件的调用。如果我们希望该外部变量只能在本文件内使用,而不能被其他文件引用可以在外部变量定义时加static声明。防止别人写的模块误用。也就是说,一个文件中用了static int a;试图在另一个文件中用extern int a来扩展a的作用域是不行的,这个操作可以通过编译,但不能运行。将static去掉,程序可运行。
心得:这些c语言中修饰变量的关键字,在写项目时的用处很大,虽然在很多时候,不使用它们不会影响的程序的操作,但是作为一个优秀的程序员,我们需要掌握更多有效的工具,写出好的项目,需要我们掌握这些基本功。只有掌握更多的技巧或者说是编程经验,这样才能写出更好,可移植性更高的程序,才能成为一个自我修养更好的程序员。总之,在实战中不断提高自己,遇到问题,要不断学习,并解决这些问题,水平才会的到更好的提升!
C语言关键字register、extern、static、一些总结,及项目中使用的心得的更多相关文章
- C语言关键字register、extern、static
C语言中: 一.register变量 关键字regiter请求编译器尽可能的将变量存在CPU的寄存器中.有以下几点注意的地方. register变量必须是能被CPU寄存器所接受的类型,这通常意味着re ...
- C语言中关键字auto、static、register、const、volatile、extern的作用
原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.exter ...
- 【转】C语言正确使用extern关键字
利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int f ...
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- FILE不是C语言关键字
FILE不是C语言关键字,只是标准C中的标准输入输出中定义的一个新的数据类型 stdio.htypedef struct _iobuf{ char* _ptr; int _cnt; char* _ba ...
- C语言关键字详解
相对于其他语言来说,C语言的关键字算是少的了.在C98中关键子总共只有32个,我们来分析一下每个关键字在C语言中它独特的作用. 1.关于数据类型的关键字 (1) char :声明字符型变量或函数 ( ...
- 李洪强漫谈iOS开发[C语言-009] - C语言关键字
// // main.m // 04 - C语言关键字 // // Created by vic fan on 16/7/12. // Copyright © 2016年 李洪强. All r ...
- c语言关键字总结
1.关键字变更历史 1999年12月16日,ISO推出了C99标准,该标准新增了5个C语言关键字: inline restrict _Bool _Complex _Imaginary(注意bool 从 ...
- 1.C语言关键字(auto break case char const swtich)
ANSI C标准C语言共有32个关键字,分别为: auto break case char const continue default do double else enum extern floa ...
随机推荐
- Spark:大数据的电花火石!
什么是Spark?可能你很多年前就使用过Spark,反正当年我四六级单词都是用的星火系列,没错,星火系列的洋名就是Spark. 当然这里说的Spark指的是Apache Spark,Apache Sp ...
- 发运模块中如何创建Debug 文件
版本11.5.9到12.x A. 针对发运事务处理或者快速发运产生Debug文件 注意:如果通过发运事务处理执行发放,请参考B部分,下面这部分销售订单发放是格外的设置和日志文件. 1. 每一 ...
- 【unix网络编程第三版】阅读笔记(四):TCP客户/服务器实例
本篇博客主要记录一个完整的TCP客户/服务器实例的编写,以及从这个实例中引发的对僵死进程的处理等问题. 1. TCP客户/服务器功能需求 本实例完成以下功能: (1) 客户从标准输入读入一行文本,并写 ...
- pig的udf编写
http://www.cnblogs.com/anny-1980/p/3673569.html http://blog.csdn.net/ruishenh/article/details/120480 ...
- pig中查询top k,返回每个hour和ad_network_id下最大两个记录(SUBSTRING,order,COUNT_STAR,limit)
pig里面是有TOP函数,不知道为什么用不了.有时间要去看看pig源码了. SET job.name 'top_k'; SET job.priority HIGH; --REGISTER piggyb ...
- jdbc连接mysql加载驱动程序com.mysql.jdbc.Driver
在开发环境如eclipse,中加载指定数据库的驱动程序.需要下载MySQL支持JDBC的驱动程序mysql-connector-java-5.1.25-bin.jar. 而具体在Java程序中加载驱动 ...
- golang:使用timingwheel进行大量ticker的优化
Ticker 最近的项目用go实现的服务器需要挂载大量的socket连接.如何判断连接是否还存活就是我们需要考虑的一个问题了. 通常情况下面,socket如果被客户端正常close,服务器是能检测到的 ...
- android官方技术文档翻译——设计时布局属性
本文译自androd官方技术文档<Designtime Layout Attributes>:http://tools.android.com/tips/layout-designtime ...
- Dynamics CRM 系统自定义部分的语言翻译
Dynamics CRM 自带语言切换功能,在官网下载所需语言包安装后,在设置语言中就能看到你所添加的语言,勾选要启用的语言应用即可,再打开系统设置--语言就能看到可更改用户界面语言的显示了. 但官方 ...
- 10_Android中通过HttpUrlConnection访问网络,Handler和多线程使用,读取网络html代码并显示在界面上,ScrollView组件的使用
编写如下项目: 2 编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <mani ...