码迷,mamicode.com
首页 > 编程语言 > 详细

C、C++变量auto,static,register,extern类型

时间:2014-07-22 23:12:12      阅读:531      评论:0      收藏:0      [点我收藏+]

标签:http   使用   os   strong   文件   数据   

auto:

推导类型变量:/Zc:auto[-] compiler option tells the compiler how to use the auto keyword to declare variables.‘ data-guid="0be6182f1ca27bd1ea991f3f06584d3b">编译器选项指示编译器如何使用 auto 关键字来声明变量。 如果指定默认选项 /Zc:auto,编译器从其初始化表达式中推导声明的变量的类型。 如果指定 /Zc:auto-,编译器将该变量分配给自动存储类。

使用示例:

auto root = new TreeNode(*pre_first);  这里root为 TreeNode *
auto inRootPos = find(in_first,in_last,*pre_first); 这里inRootPos 为 int
auto leftSize = distance(in_first,inRootPos); 这里leftsize 为 int

static
它是C,C++中都存在的关键字,它主要有三种使用方式,其中前两种只指在C语言中使用,第三种在C++中使用。
(1)局部静态变量 
(2)外部静态变量/函数 
(3)静态数据成员/成员函数 
局部静态变量 
与auto类型(普通)局部变量相比, static局部变量有三点不同: 
1. 存储空间分配不同,auto类型分配在栈上,属于动态存储类别,占动态存储区空间,函数调用结束后自动释放;而static分配在静态存储区,在程序整个运行期间都不释放。两者之间的作用域相同,但生存期不同。
2. static局部变量在所处模块的初次运行时进行初始化工作,且只初始化一次。
3. 对于局部静态变量,如果不赋初值,编译期会自动赋初值0或空字符;而auto类型的初值是不确定的。(对于C++中的class对象例外,class的对象实例如果不初始化,则会自动调用默认构造函数,不管是否是static类型) 
二、外部静态变量/函数 
在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。为了限制全局变量/函数的作用域,函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函 数)。注意此时,对于外部(全局)变量,不论是否有static限制,它的存储区域都是在静态存储区,生存期都是全局的。此时的static只是起作用域限制作用,限定作用域在本模块(文件)内部。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 
三、静态数据成员/成员函数(C++特有) 
C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数。这是与普通成员函数的最大区别,也是其应用所在。比如在对某一个类的对象进行计数时,计数生成多少个类的实例,就可以用到静态数据成员。在这里面,static既不是限定作用域的,也不是扩展生存期的作用,而是指示变量/函数在此类中的唯一性。这也是“属于一个类而不是属于此类的任何特定对象的变量和函数”的含义。因为它是对整个类来说是唯一的,因此不可能属于某一个实例对象的。(针对静态数据成员而言,成员函数不管是否是static,在内存中只有一个副本,普通成员函数调用时,需要传入this指针,static成员函数调用时,没有this指针) 
注意:
不能将union成员声明为static的,然而,对于全局的匿名union,必须显式的声明为static。

register关键字
只有函数参数和局部变量可被声明为register。意思是,在可能的情况下,该变量被存储在CPU寄存器中。register变量和auto变量一样,它的生命周期只维持在它所声明的块中。编译器并不赞成程序员指定register变量。实际的情况是,编译器会根据全局优化的需要自动决定是否采用register类型。

extern关键字
extern用在声明语句中表示该对象或变量是在其它编译单元中(不能说是其它文件,因为有些文件,如头文件不是编译单元)定义的;如果用在定义语句中,表示该变量对外部可见。
注意extern与#include作用的区别:
例1,使用extern:
//out.h
int a = 10;

//out.cpp
#include "out.h"

//example.cpp
#include <iostream>
using namespace std;

extern int a;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"a="<<a<<endl;

system("pause"); 
return 0;
}
编译链接流程:
由于out.cpp文件引用了out.h文件,所以out.cpp文件的内容变成了int a = 10;,编译时生成编译单元out.obj(out.o),其中定义了变量a。example.cpp文件中出现了对a的引用cout<<"a="<<a<<endl;,但该文件中没有a的定义(extern int a;只是一个声明),而且包含的头文件中也没有,但是由于有声明extern int a;,表明a是在其它编译单元中定义的,编译不出错。最后链接器在编译单元out.obj(out.o)中找到a的定义,建立连接关系,生成最后的exe文件。该工程中有两个编译单元,最后链接成一个exe文件。

例2,使用#include:
//out.h
int a = 20;

//example.cpp
#include "out.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
cout<<"a="<<a<<endl;

system("pause"); 
return 0;
}
编译链接流程:
example.cpp文件中出现了对a的引用cout<<"a="<<a<<endl;,但该文件中没有a的定义,但是包含的头文件out.h中有,这样在编译之前,头文件out.h展开到example.cpp文件中,相当于example.cpp文件中定义了a(int a = 20;),编译成功。最后链接器链接编译单元生成最后的exe文件。该工程中只有一个编译单元,最后链接成一个exe文件。



C、C++变量auto,static,register,extern类型,码迷,mamicode.com

C、C++变量auto,static,register,extern类型

标签:http   使用   os   strong   文件   数据   

原文地址:http://www.cnblogs.com/qingcheng/p/3700154.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!