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

本文详细介绍了C语言中变量的存储类别,包括auto(自动)、static(静态)、register(寄存器)和extern(外部)。重点讲解了static如何改变局部变量和全局变量的行为,以及extern在多文件开发中的作用。同时,提到了register关键字用于优化频繁使用的变量,但在现代编译系统中往往不再需要显式声明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- 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的作用是将变量的作用域限制在当前文件中,其他文件不能通过extern来引用该变量。


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


此外,多文件开发时,函数也可以添加extern或static声明。函数默认是相当于添加了extern声明的,此时函数可以被其他文件调用。如果为函数添加static声明,则该函数只能在其所定义的文件内使用,不能被其他文件调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值