转自:https://blog.csdn.net/u010757264/article/details/49932829

C++中变量、函数的属性包括数据类型和存储类别。存储类别分为静态存储和动态存储两类,指数据在内存中的存储方式(静态和动态),包含auto,static,register,extern四种。auto register是用来修饰变量的,static extern修饰变量函数都可以。

变量的生存周期

变量从建立到撤销的时间段成变量的生存周期。静态变量,从变量产生到整个程序执行结束。当函数使用变量结束后,变量的存储空间依然存在,变量的值也会随着函数的对其的使用而改变。如在函数内定义了一个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声明变量,会相互影响,可能执行一个文件时改变了该全局变量的值,影响其他文件的调用。如果我们希望该外部变量只能在本文件内使用,而不能被其他文件引用可以在外部变量定义时加static声明。防止别人写的模块误用。也就是说,一个文件中用了static int a;试图在另一个文件中用extern int a来扩展a的作用域是不行的,这个操作可以通过编译,但不能运行。将static去掉,程序可运行。

参考文献:

http://blog.csdn.net/firefly_2002/article/details/7940802

http://blog.csdn.net/hackbuteer1/article/details/7487694

(转)C/C++——auto,static,register,extern用法的更多相关文章

  1. 谈谈以下关键字的作用auto static register const volatile extern

    (1)auto 这个这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是 ...

  2. 存储类型auto,static,extern,register的区别 <转>

    变量和函数的属性包括数据类型和数据的存储类别,存储类别指数据在内存中存储方式(静态和动态),包含auto,static,register,extern四种. 内存中.具体点来说内存分为三块:静态区,堆 ...

  3. 《OOC》笔记(1)——C语言const、static和extern的用法

    <OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...

  4. static和extern的用法小结

    以前写程序是,基本不管static和extern,一个工程文件也只有一个c文件.今天尝试用多个文件来写,自然就涉及到这两个关键词的使用,自己查了些资料,并且做了些实验,总结如下. extern的用法 ...

  5. auto和register关键字

    关键字概述 很多朋友看到这儿可能会有疑问,往往其它讲C语言的书籍都是从HelloWorld,数据类型开始C语言学习的,为什么我们要从C语言的关键字开始呢?关于这点,我有两点需要说明: 本章节面向的读者 ...

  6. c++中static的全部用法

    要理解static,就必须要先理解另一个与之相对的关键字,很多人可能都还不知道有这个关键字,那就是auto,其实我们通常声明的不用static修饰的变量,都是auto的,因为它是默认的,就象short ...

  7. static 和extern关键字

    static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.extern "C"是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话 ...

  8. 16-static和extern关键字2-对变量的作用

    上一讲介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量也有 ...

  9. 15-static和extern关键字1-对函数的作用

    一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.ob ...

  10. 转:从编译链接过程解析static函数的用法

    关于static函数的用法 就像我们熟知的那样,变量可以分全局的和局部的,函数也可以分全局的和局部的. 比如说,在一个工程的common.h中定义了一个全局变量 int test;那么在整个工程的作用 ...

随机推荐

  1. 微信小程序实战 购物车功能

    代码地址如下:http://www.demodashi.com/demo/12400.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  2. Codeforces Hello2015第一题Cursed Query

    英文题面: De Prezer loves movies and series. He has watched the Troy for like 100 times and also he is a ...

  3. 深入理解Java 8 Lambda

    - 转载:blog1, blog2 以上两篇博客是对lambda表达式的深入理解,用于后续加深理解. 如下先从零开始理解lambda, 1. 接触lambda表达式是从python,javascrip ...

  4. Maven 编译

    pom.xml 添加插件 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins< ...

  5. 使用ZipArchive解压

    本文转载至 http://www.apkbus.com/forum.php?mod=viewthread&tid=131390&extra=page%3D1 qqpk360 该用户从未 ...

  6. python 基础 1.5 python数据类型(四)--字典

    一.python 数据类型--字典 1.用字符串存储信息,如:存储“姓名,身高,性别”: In [1]: info='Tom 170 M' //字符串存储信息 In [3]: info[0:3] // ...

  7. Unix环境高级编程—进程控制(二)

    一.函数wait和waitpid 今天我们继续通过昨天那个死爹死儿子的故事来讲(便于记忆),现在看看wait和waitpid函数. #include<sys/wait.h> pid_t w ...

  8. mysql insert返回主键

    使用mybatis的话,很方便. 使用useGeneratedKeys和keyProperty,keyProperty是插入的java对象的属性名,不是表的字段名. 这样,在插入该条记录之后,生成的主 ...

  9. c++标准库比较

    1 GNU standard c++ library debian发行版中使用的c++标准库是GNU standard c++标准库. 2 Boost debian发行版中也是用了boost库,但是不 ...

  10. mac上完整卸载删除.简单粗暴无脑:androidstudio删除方案

    如果你是mac  ,你删除as ,删不干净也正常,你会发现安装的时候,前面的东西也在.配置文件在,会导致你以前的错误不想要的东西都在. 废话不多说,复制粘贴就是干!!!!~~~~~~~~ 第一步: 复 ...