创作内容不易,学习的朋友麻烦关注下博主,后面学习不迷路。有不会的问题也可以论坛咨询博主,博主也会及时回复~~
目录
1.作用域
作用域描述程序中可访问标识符的区域。一个c++变量的作用域可以是
块作用域,函数作用域,函数原型作用域,文件作用域
块作用域:我们日常用的基本都是块作用域,而块是用一对花括号括起来的代码区域。
范围:左花括号~右花括号
函数原型作用域:用于函数原型的形参名。
范围:形参定义处~函数右花括号
int add(int i)
{
int x,y;
….
}
这里的I,x,y都属于add函数私有的变量(i更准确的来说属于函数原型作用域,),这些变量都具有add的块作用域,进入函数,给这些变量分配空间,函数结束,自动清除这些变量所使用的空间。
int add(int i)
{
int x,y;
….
if(int j = 0;j < i;i++)
…
}
变量j只能在if这段块才能使用,而且在这个块中I,x,y均可以正常使用,因为if这段块也在这个add这个大段块空间里。
函数作用域:这个一般只用于goto语句。一个标签首次出现在内层块中,它的作用域延伸至整个函数。
范围:标签开始处~函数结束
int add(int i)
{
int x,y;
….
label:
if(int j = 0;j < i;i++)
…
}
label标签从if开始一直到函数结尾结束。
文件作用域:变量定义在函数外面,就是文件作用域。具有文件作用域的变量,从它定义处到该定义所在文件的末尾可见
范围:文件开始~文件结束
int z;
int add(int i)
{
int x,y;
….
if(int j = 0;j < i;i++)
…
}
int print(int num)
{
…
}
变量拥有文件作用域,它可以在add和Print函数当中使用
2.链接
C变量由三种链接属性:外部链接,内部链接,无链接
具有块作用域,函数作用域或函数原型作用域的变量都是无链接变量。
具有文件作用域的变量可以是外部链接或内部链接。
外部链接变量可以在多个文件程序中使用,内部链接变量只能在一个翻译单元中使用,无链接就只能在当前块中使用
3.存储期
作用域和链接描述了标识符的可见性。存储期描述了通过这些标识符访问的对象的生存期。C++有4种存储期:静态存储期,线程存储期,自动存储期,动态分配存储期
静态存储期:如果对象具有静态存储期,那么它在程序的执行期间一直存在。文件作用域具有静态存储器期。拥有静态存储期的变量会自动初始化为0。静态存储器必须使用常量初始化,不能使用变量初始化。自动变量可以使用变量也可以是常量
int x; //静态外部链接变量
static int y
int main()
{
…
}
这里需要注意下,对于文件作用域变量,关键字static表明了其链接属性,而非存储期。x,y从声名处开始到程序结束一直存在。
线程存储期:用于并发程序开发,程序执行可被分为多个线程。具有线程存储期的对象,从被声明时到线程结束一直存在。,以关键字thread_local声名一个对象时,每个线程都能获得该变量的私有备份。这里了解下就好了
自动存储期:块作用域的变量通常都是自动存储期(这一般也是我们编程当中用的最多的)。当程序进入定义这些变量的块时,为这些变量分配内存。而当退出这个块时,就会释放刚才为变量分配的内存空间。
这里需要注意,块作用域变量也能具有静态存储期。为了创建这样的变量,要把变量声明在块中,且在声明前面加上关键字static。这种在块中使用static的块作用域的静态变量
void more(int number){
int index;
static int ct = 0; //因为加了关键字static具有静态内部链接
}
这里,变量ct存储在静态内存中,它从程序被载入到程序结束期间都存在。但是,它的作用域定义在more()函数块中。只有在执行该函数时,程序才能使用ct访问它所指定的对象。但是,该函数可以给其他函数提供该存储区的地址以便间接访问该对象。
4.5种存储类别变量
说完了作用域,链接和存储期的概念后。朋友你已经大概了解了一个标识符和其对应的对象在整个程序的特点。而根据这些作用域,链接和存储期。我们就要讲解5个C语言的存储类别变量
存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
自动变量 | 自动存储期 | 块作用域 | 无链接 | 在代码块中 |
寄存器变量 | 自动存储期 | 块作用域 | 无链接 | 块内使用register存储类型说明符 |
静态外部链接变量 | 静态存储期 | 文件作用域 | 外部链接 | 所有函数外,直接声名 |
静态内部链接变量 | 静态存储期 | 文件作用域 | 内部链接 | 所有函数外,使用static存储类型说明符 |
块作用域静态变量 | 静态存储期 | 块作用域 | 无链接 | 块内使用static存储类型说明符 |
下面我们来一个一个讲解
1.自动变量
属于自动存储类别的变量具有自动存储期,块作用域且无链接。默认情况下,声明在块或函数头种的任何变量都属于自动存储类别。
int I; //静态外部链接变量
int main()
{
int I; //在main函数中声名了一个完全独立的I
…
}
块作用域和无链接意味着只要在变量定义所在的块中才能通过变量名访问该变量(当然,参数用于传递变量的值和地址给另一个函数,这属于间接的方法)
int loop(int n){
int m; //m的作用域
scanf("%d",&m);{
int i; //m和i的作用域
for(i =m; i < n;i++) puts("i is local to a sub-block\n");
}
return m; //m的作用域,i已经没有了
}
2.寄存器变量
变量通常寄存在计算机内存种,而寄存器变量则存储在CPU的寄存器种。与普通变量相比,寄存器变量访问和处理的速度会更快。但由于寄存器变量存储在寄存器而非内存种,所以无法获取到寄存器的地址。使用register声明寄存器变量
Int main(void){
register int quick;
}
这里需要知道,编译器必须根据寄存器得数量来衡量请求,如果寄存器无法分配,则直接忽略请求。这个时候寄存器变量就会变成普通的自动变量(但此时还是无法使用地址运算符)
在C++11之前register还是这样,不过到了C++11后,register就用来显式的指出变量是自动变量。在表面有意覆盖一个外部变量定义,或者强调不要把该变量改为其他存储类别时,使用register。
3.内部链接的静态变量
静态的意思是该变量在内存中原地不动,但值可变。具有文件作用域的变量自动具有静态存储期。这些变量和自动变量一样,具有相同的作用域,但是程序离开它们所在的函数后,这些变量不会消失
内部链接的静态变量,声名在所有函数外面,使用static类型说明符。如果static用于文件作用域声明,作用域受限于该文件。
static int I; //内部链接的静态变量
int main()
{
…
}
4.外部链接的静态变量
外部链接的静态变量具有文件作用域,外部链接和静态存储期。该类别有时称为外部存储类别,属于该类别的变量称为外部变量。如果一个源代码文件使用的外部变量定义在另一个源代码文件种,则必须使用关键字extern在该文件中声明该变量
int errupt; //外部定义的变量
double up[10]; //外部定义的数组
extern char coal; //此时从其他文件引入coal变量
int main(){
extern int errupt;
extern double up[10]; //如果去掉extern,将会重新创建一个同名的自动变量
}
Int errupt;第一次声明称为定义式声明
extern int errupt; 第二次声明称为引用式声明
extern表面该声明不是定义,而是指示编译器到别处查询定义。这里变量只能有一个定义式声明,但可以有多次引用式声名。而且只能在定义式声明的时候进行初始化。
6.块作用域静态变量
定义在块中,但使用static存储类别说明符
int I; //静态外部链接变量
int add()
{
auto int I; //在main函数中声名了一个完全独立的
static int y;
…
}
这个例子中,即使aadd函数结束,给i分配的存储空间会收回,但变量y的存储空间不会收回但此时如果想要访问这块存储空间,必须在之前留下这块空间的地址。
6.单定义规则
对于使用外部变量。C++踢狗两种变量声明。一种是定义声明(定义),它给变量分配存储空间;另一种是引用声明(声明)
引用声明使用关键字extern,且不进行初始化;否则,声明为定义,导致分配存储空间。
记住可以由多个声明,但只能有一个定义。
我们今天的内容到这就结束了,今天的内容到这里就结束了,如果有啥不会的朋友记得论坛里面提问哈~
如果朋友你感觉文章的内容对你有帮助,可以点赞,关注文章和专栏以及关注我哈,嘿嘿嘿我会定期更新文章的,谢谢朋友你的支持哈