C语言存储类别、存储区

目录

一,作用域

二,翻译单元

三,链接属性

四,可见性分类

五,存储期(生命周期)

六,变量存储类别

1,自动变量

2,寄存器变量

3,静态局部变量

4,非静态全局变量

5,静态全局变量

七,函数存储类别

八,存储区


一,作用域

作用域指的是,可以通过标识符的名称来访问它的一个范围。

有两种常见的作用域:块作用域、文件作用域

复合语句是块,一个函数也是一个块,函数内定义的是块作用域,范围是从定义处到块结束处

函数外定义的是文件作用域,范围是从定义处到文件结束处

局部变量是块作用域,全局变量是文件作用域

还有两种不常见的作用域:函数作用域、函数原型作用域

函数作用域仅用于goto语句的标签,范围是整个函数。

函数原型作用域仅用于函数原型,几乎也只有可变长数组用于函数参数时涉及:

void useAvla(int n, int num[n]);

二,翻译单元

在编译时,每个源文件(.c或者.cpp)都称为一个翻译单元,在预处理时会把include的头文件依次全部加入到源文件中。

文件作用域,指的是整个翻译单元,而不仅仅是原文件本身。

三,链接属性

变量有三种链接属性:外部链接,内部链接,无链接

块作用域、函数作用域、函数原型作用域都是无链接的,文件作用域都是外部链接或内部链接的。

静态的(static)全局变量是内部链接的,非静态的全局变量是外部链接的

也就是说,全局变量加了static就只能在本文件访问,不加static就可以在所有文件中访问。

四,可见性分类

描述一个变量的可见性,有两个属性,作用域和链接属性。

所以可见性分为三种,局部变量,静态全局变量,非静态全局变量

而函数作用域、函数原型作用域描述的标识符在编译之后并不会生成符号,不用关心。

五,存储期(生命周期)

存储期分为四种:自动存储期,静态存储期,动态分配存储期,线程存储期

局部变量一般都是自动存储期,即程序进入块时给变量分配内存,程序退出块时释放分配的内存。

自动存储期变量中,只有变长数组特殊一点,它的存储期是从声明处开始,而不是从进入块时开始。

局部变量也可以是静态存储期,局部变量如果加上static,那就是静态的,静态存储期是指程序执行期间一直存在。

全局变量无论是静态的还是非静态的,都是静态存储期。

PS:static用于局部变量和全局变量时,含义完全不同,但是我们还是可以把最常见的四种变量归纳如下:(仅供参考,很多情况不全)

 如果用malloc分配内存,那么就是动态存储期,需要free才能释放内存。

PS:malloc一段内存返回的指针是正常的局部变量,指针指向的地址才是动态存储期,虽然它本身没有标识符,但是可以理解为匿名变量。

PS:正常的局部变量,指的是这个指针变量像其他局部变量一样,可能是自动存储期,可能是静态存储期,也可能是动态存储期。

用thread_local修饰的是线程存储期,即线程局部变量,只在本线程可见,不用thread_local修饰的是所有线程可见。局部变量加thread_local修饰就会自动变成静态线程变量。

再给出一个相对完整的分类表:

六,变量存储类别

按照上面作用域、链接、存储期的分类,有四种类型的变量:静态全局变量、非静态全局变量、静态局部变量、自动变量(非静态局部变量、函数原型形参)。

自动变量又分为内存存储和寄存器存储,一共是五种存储类别

PS:只有自动变量可以放寄存器。

PS:没有算上线程局部变量的存储类别。

1,自动变量

非静态局部变量、函数原型形参都是自动变量,可以加auto修饰,也可以不加,没有语义区别,换句话说只是语法糖。

PS:C++中的auto是有语义的,用法完全不同。

自动变量不会初始化,除非显式给它初始化。

2,寄存器变量

为了提高效率,C 语言允许将局部变量得值放在 CPU 中的寄存器中,这种变量叫“寄存器变量”,用关键字 register 作声明。

注意:只有自动变量可以作为寄存器变量。

3,静态局部变量

用static修饰的局部变量。

4,非静态全局变量

非静态全局变量也叫外部链接的静态变量、外部变量。

没有加extern的是变量定义,如果要在该文件中定义之前使用该全局变量,或者在其他文件中使用,就必须在使用处用extern作引用声明。

引用声明是不进行初始化的,否则就会被视为变量定义。

总之,没有extern的、有extern但是有初始化的都是变量定义,没有extern也没有初始化的是变量引用。

5,静态全局变量

静态全局变量也叫内部链接的静态变量、外部静态变量。

静态全局变量不能在其他文件使用。

七,函数存储类别

函数的存储类别,分为外部函数、静态函数、内联函数。

用static修饰的是静态函数,只有本文件内可以调用。

没有static修饰的是外部函数,所有文件都可用。

八,存储区

内存中,用户存储空间可以分为三个部分:
1) 程序区;
2) 静态存储区;
3) 动态存储区;

变量的存储位置分为三种:

1) 寄存器
2) 内存——静态存储区;
3) 内存——动态存储区;

其中动态存储区分为堆heap 和 栈stack

所以变量的存储位置也可以分为四种:寄存器、内存静态存储区、堆、栈

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值