存储类别、链接和内存管理(一)--面试中你遇到过static关键字吗?

简介: 主要介绍作用域,链接,存储期。

   halo大家好~今天我们来分享一下在有关C语言面试中我们最常被面试官问到的static关键字到底有什么用?相信学完本期内容你就会回答了~

一、存储类别

   首先我们来了解下存储类别。

   从硬件方面看,每个变量存储的值都占用一定的物理内存空间,C语言中把这样一块内存称为对象。    

   从软件方面看,程序需要访问对象,可以通过声明变量来完成:

int entity = 3;

   程序通过访问标识符entity去访问对象。

640.png

一般而言,那些指定对象的表达式称为左值,即entity即是标识符也是左值。如果可以使用左值改变对象中的值,该左值就是一个可修改的左值(modifiable value)。很简单吧,如果你理解不了,想象一下,我要将存储3的内存空间改成4怎么做?

entity = 4;

通过标识符entity(左值)去修改某一内存空间的值。

再看一个例子,声明:

const char *pc = “hello world!”;

640.png

字符串“hello world!”存放在一段连续的内存空间里,假设从地址0x56000000开始,那pc存放的值就是0x56000000,即pc的值存放了字符串的地址。

我们可以让pc重新指向其他字符串(改变pc里的值),所以标识符pc是个可修改的左值,const保证了被pc指向的字符串内容不被修改,但是无法保证pc不指向其他字符串。但是*pc不是可修改的左值,因为*pc指定了储存‘h’字符的数据对象。

可以用存储期描述对象,所谓存储期是指对象在内存中保留了多长时间。

标识符用于访问对象,使用作用域链接描述标识符。

1.1 作用域

   作用域描述程序中可访问标识符的区域。一个C变量的作用域可以是:

块作用域、函数作用域、函数原型作用域文件作用域

块就是一对用花括号{}括起来的代码区域,我们使用的局部变量、函数的形参都具有块作用域。C99把块的概念拓展到包括for循环、while循环,例如:

for(int i=0;i<5;i++);

变量i的作用域也是块作用域,一旦循环结束,就不能再访问i。

   函数作用域(function scope)仅用于goto语句的标签。这意味着即使一 个标签首次出现在函数的内层块中,它的作用域也延伸至整个函数。如果在 两个块中使用相同的标签会很混乱,标签的函数作用域防止了这样的事情发 生。

   函数原型作用域的范围是从形参定义处到原型声明结束。这意味着,编 译器在处理函数原型中的形参时只关心它的类型,而形参名(如果有的话) 通常无关紧要。而且,即使有形参名,也不必与函数定义中的形参名相匹 配。只有在变长数组中,形参名才有用。

   变量的定义在函数的外面,具有文件作用域(file scope)。具有文件作 用域的变量,从它的定义处到该定义所在文件的末尾均可见。定义在函数体外,这样的变量可用于多个函数,所以文件作用域变量也称为全局变量(global variable)。

所以,局部变量具有块作用域,全局变量具有文件作用域。

1.2 链接

   说到链接,首先我们要知道C变量具有3种链接属性:外部链接内部链接无链接

C预处理时,用包含的头文件内容替换#include指令,编译器源代码文件和所有的头文件都看成是一个包含信息的单独文件。这个文件被称为翻译单元 (translation unit)。

具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量

具有文件作用域的变量可以是外部链接或内部链接。

外部链接变量可以在多文件程序中使用,内部链接变量只能在一个翻译单元中使用(即一个源代码文件和它所包含的头文件)。

但是,对程序员而言这些术语太长了。一 些程序员把“内部链接的文件作用域”简称为“文件作用域”,把“外部链接的文件作用域”简称为“全局作用域”或“程序作用域”。

那么如何知道文件作用域是内部链接还是外部链接呢?就看外部定义中有没有static!举个例子:

int i = 6;            //文件作用域,外部链接
    static int k = 6;  //文件作用域,内部链接
    int main(void)
        ...

   该文件和同一程序的其他文件都可以使用变量i。而变量k属文件私有,该文件中的任意函数都可使用它。

总结:当你的Project里有多个C文件的时候,编译器编译它们的时候所有文件都能使用变量i,而加了static的全局变量k,则只有该文件可以使用,其他文件是看不到变量k的。

1.3 存储期

  C对象有4种存储期:静态存储期、线程存储期、自动存储期、动态分配存储期。

静态存储期:如果对象具有静态存储期,那么它在程序的执行期间一直存在。文件作用域变量具有静态存储期。注意:static仅仅是声明了它的链接属性,而无论是外部连接还是内部连接,所有的文件作用域都具有静态存储期

线程存储期用于并发程序设计,程序执行可被分为多个线程。具有线程 存储期的对象,从被声明时到线程结束一直存在。以关键字_Thread_local声 明一个对象时,每个线程都获得该变量的私有备份。

块作用域的变量通常都具有自动存储期。当程序进入定义这些变量的块时,为这些变量分配内存;当退出这个块时,释放刚才为变量分配的内存。我们到目前为止使用的局部变量都是自动类别

注意:块作用域变量也能具有静态存储期。为了创建这样的变量,要把变量声明在块中,且在声明前面加上关键字static

640.jpg

总的来说:static关键字的作用就是限制作用域和存储期。通常面试官还会跟全局变量和局部变量一起问的哦~    

号主:一枚机械专业本科生,经历了转行,从外包逆袭到芯片原厂的Linux驱动开发工程师,深入操作系统的世界,贯彻终身学习、终身成长的理念。平时喜欢折腾,寒冬之下,抱团取暖,期待你来一起探讨技术、搞自媒体副业,程序员接单和投资理财。【对了,不定期送闲置开发板、书籍、键盘等等】。

如果你想了解我的转行经验,欢迎找我交流~gongzhong号【哆哆jarvis】

一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~


相关文章
|
5天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
13 1
|
9天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
14天前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
21 3
|
14天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
19天前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
35 4
|
17天前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
36 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
24天前
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储
|
14天前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。
|
2月前
|
缓存 监控 NoSQL
阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
|
19天前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储