存储类别、链接和内存管理(一)--面试中你遇到过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】

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


相关文章
|
1月前
|
Java 程序员
面试官的加分题:super关键字全解析,轻松应对!
小米,29岁程序员,通过一个关于Animal和Dog类的故事,详细解析了Java中super关键字的多种用法,包括调用父类构造方法、访问父类成员变量及调用父类方法,帮助读者更好地理解和应用super,应对面试挑战。
41 3
|
5月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
76 0
|
4月前
|
缓存 安全 Java
【Java面试题汇总】Java基础篇——基础、修饰符和关键字(2023版)
Java的特点和优点,、Java 8的新特性、面向对象、基本数据类型和引用类型、自动拆装箱与自动装箱、==与equals()的区别、为什么重写equals()就要重写hashcode()、抽象类和接口的区别、重载和重写的区别、四种引用方式、wt()和sleep()的区别、java方法是值传递还是引用传递?访问修饰符、static、final、this和super、volatile的用法及原理
|
4月前
|
缓存 监控 NoSQL
阿里面试让聊一聊Redis 的内存淘汰(驱逐)策略
大家好,我是 V 哥。粉丝小 A 面试阿里时被问到 Redis 的内存淘汰策略问题,特此整理了一份详细笔记供参考。Redis 的内存淘汰策略决定了在内存达到上限时如何移除数据。希望这份笔记对你有所帮助!欢迎关注“威哥爱编程”,一起学习与成长。
|
3月前
|
存储 Kubernetes 架构师
阿里面试:JVM 锁内存 是怎么变化的? JVM 锁的膨胀过程 ?
尼恩,一位经验丰富的40岁老架构师,通过其读者交流群分享了一系列关于JVM锁的深度解析,包括偏向锁、轻量级锁、自旋锁和重量级锁的概念、内存结构变化及锁膨胀流程。这些内容不仅帮助群内的小伙伴们顺利通过了多家一线互联网企业的面试,还整理成了《尼恩Java面试宝典》等技术资料,助力更多开发者提升技术水平,实现职业逆袭。尼恩强调,掌握这些核心知识点不仅能提高面试成功率,还能在实际工作中更好地应对高并发场景下的性能优化问题。
|
3月前
|
缓存 Java 编译器
【多线程-从零开始-伍】volatile关键字和内存可见性问题
【多线程-从零开始-伍】volatile关键字和内存可见性问题
49 0
|
5月前
|
存储 安全 Java
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程是什么,JDK、JRE、JVM的联系与区别;什么是程序计数器,堆,虚拟机栈,栈内存溢出,堆栈的区别是什么,方法区,直接内存
JVM常见面试题(二):JVM是什么、由哪些部分组成、运行流程,JDK、JRE、JVM关系;程序计数器,堆,虚拟机栈,堆栈的区别是什么,方法区,直接内存
|
5月前
|
Java
【Java基础面试四十一】、说一说你对static关键字的理解
这篇文章主要介绍了Java中static关键字的概念和使用规则,强调了类成员与实例成员的区别及其作用域的限制。
|
6月前
|
SQL 安全 Java
Android经典面试题之Kotlin中object关键字实现的是什么类型的单例模式?原理是什么?怎么实现双重检验锁单例模式?
Kotlin 单例模式概览 在 Kotlin 中,`object` 关键字轻松实现单例,提供线程安全的“饿汉式”单例。例如: 要延迟初始化,可使用 `companion object` 和 `lazy` 委托: 对于参数化的线程安全单例,结合 `@Volatile` 和 `synchronized`
73 6
|
5月前
|
缓存 Java
【多线程面试题二十三】、 说说你对读写锁的了解volatile关键字有什么用?
这篇文章讨论了Java中的`volatile`关键字,解释了它如何保证变量的可见性和禁止指令重排,以及它不能保证复合操作的原子性。

热门文章

最新文章