您的位置:首页 > 编程语言 > C语言/C++

黑马程序员——C语言中变量的存储类别

2015-08-12 15:58 357 查看
------- android培训、java培训、iOS培训、期待与您交流!
----------

关于变量的存储方式

变量的存储方式分为两种:静态存储方式动态存储方式

静态存储区中存放全局变量,在程序开始执行时给全局变量分配存储区,程序执行完毕后释放,在程序执行过程中他们占据固定的存储单元。

动态存储区中存放以下数据:

函数形参。在调用函数时为形参分配存储空间。
自动变量。未加static声明的局部变量。
函数调用时的返回地址等。
存储在动态存储区的数据在函数开始调用时分配存储空间,函数结束时释放这些空间。这种分配是动态的,所以在一个程序中两次调用同一函数,分配给此函数中局部变量的空间地址可能是不同的。

数据的四种存储类别:auto(自动)、stastic(静态)、register(寄存器)、extern(外部)。

一、auto

所有局部变量(包括函数中定义的变量以及复合语句代码块中定义的变量)和函数的形参都属于auto类变量。这种类型的数据都是在其作用域开始时系统为其进行存储空间的分配,在作用域结束时自动释放存储空间。

通常情况下可以省略关键字“auto”。

二、static

对函数的局部变量声明static

当希望函数的局部变量的值在函数调用结束后不消失而保留原值,就需要在变量前加“static”关键字进行声明。使用static声明过的变量在函数调用结束时内存单元不会释放,在下次调用该函数时,该变量的值就是上一次调用结束时的值。

例:

#include <stdio.h>
int add(){
    static int a =0;
    int b = 0;
    a = a+1;
    b = b+1;
    printf(“a = %d,b = %d”,a,b);
}
void main(){
    for(int i=0;i<3;i++){
        add();
        printf(“\n");
    }
}


输出结果为a = 1,b = 1

            a = 2,b = 1

            a = 3,b = 1

通过static声明,局部变量被作为静态变量存储在静态存储区,在整个程序运行期间都不会被释放。
静态局部变量是在编译时赋初值,相对的,自动变量不是在编译时而是在函数调用时赋初值,每调用一次函数就重新赋一次初值。
如果在定义局部变量时不赋初值,对于静态变量,编译时会自动赋初值(数值型变量为0,字符型变量为空字符)。而对于自动变量,则会是一个不确定的值。

static应用举例,输出1到5的阶乘:

int fac(int n){
    static int f = 1;
    f = f*n;
    return f;
}
int main(int argc, const char * argv[]) {
    for (int i=1; i<6; i++) {
        printf("%d! = %d\n",i,fac(i));
        
    }
}


输出结果为 1! = 1

             2! = 2

               3! = 6

             4! = 24

             5! = 120

在多文件开发中使用static

当希望某些外部变量只能被本文件引用而不能被其他文件引用,可以在定义外部变量时加static声明。

外部变量:在函数外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。

例如,在文件file.c中定义了外部变量static int A;在文件file2.c中声明extern int A;那么文件file2.c仍然不能使用file.c中的外部变量A,此变量A的作用域仅限于文件file.c。

三、extern

在一个文件内声明外部变量

外部变量的作用域范围在变量的定义处到文件结束,如果在定义之前想引用该外部变量,可以通过关键字extern的声明对该变量作外部变量声明,表示该变量是一个已经定义的外部变量。相当于变相的扩大了外部变量的作用域。

应用举例:

#include <stdio.h>
int main(int argc, const char * argv[]) {
    int sum(int x,int y);
    extern int a,b;
    printf("%d",sum(a, b));
    return 0;
}
int a = 3,b = 5;
int sum(int x,int y){
    return x+y;
}


在使用extern声明外部变量时可以省略类型名,例如extern int a;

在多文件开发中声明外部变量

在多文件开发时,如果要让一个变量可以在多个文件中引用,只需要在声明该变量时加上关键字extern,其他文件就可以引用这个变量,同时其他文件中也不能再定义同名变量。

或者,先在当前文件中定义该变量(不在.h文件中声明),在其他需要使用该变量的文件中通过extern声明该变量,也可以实现相同的效果。

四、register

一般情况下,静态变量和动态变量的值都是存在内存中的。当某个变量需要频繁被使用时,可以通过register关键字声明,将该变量存储在CPU的寄存器中以提高运行效率。但是由于现在的编译系统能够识别频繁使用的变量并自动将这些变量放在寄存器中,所以通常不需要特别使用register关键字声明。

总结

关于变量的存储类别,主要需要区分和掌握的就是static和extern。所有局部变量都是auto类型,不需要特别声明,而register类型在现代编译系统下会由系统自动完成。

对于局部变量,static的作用是将原本存储在动态存储区的数据存储到静态存储区中从而实现函数调用结束时保留变量的作用。对于全局变量,static的作用是将变量的作用域限制在当前文件中,其
4000
他文件不能通过extern来引用该变量。

extern可以实现变量声明和定义的分离。当编译器遇到extern声明的变量时,会先在当前文件的下文中寻找该变量的定义,如果当前文件中没有定义该变量的话则去其他文件中寻找。

此外,多文件开发时,函数也可以添加extern或static声明。函数默认是相当于添加了extern声明的,此时函数可以被其他文件调用。如果为函数添加static声明,则该函数只能在其所定义的文件内使用,不能被其他文件调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息