C语言的作用域和生存期到底是什么?
📅 2026/7/27 4:44:41
👁️ 次浏览
在嵌入式C语言开发中我们会经常遇到下面这两个概念其实对于这两个C语言的基本概念应该很多网友都能多多少少说出一些相关的内容也是嵌入式岗位面试的时候会经常涉及到的笔试题目主要用来描述变量只是角度不同。今天就抽空给大家简单总结一下这两个概念的一些基本内容并通过实例进一步说明一下加深我们的印象毕竟把这些基本知识掌握透彻才能进一步领悟C语言的灵魂。一、我们先来看看作用域作用域————“在哪儿能被看见”空间维度所谓作用域其实是很多程序设计语言中非常重要的一个概念主要用于减少命名冲突并提高程序逻辑的局部性以此来提高程序的可靠性和健壮性。通俗一点来讲就是在程序里面的哪些地方可以访问这个变量而在C语言代码中作用域主要是由花括号{ }来决定也就是说如果错误使用不在作用域范围内的变量则可能会出现程序编译错误和程序运行错误等问题。接下来就通过下面几个方向来举例说明这样更好理解。1、块作用域变量被定义在一对花括号内部即正常情况下只能在花括号内部代码块里面使用这个变量。我们先来看看下面的代码你觉得编译会成功通过吗int main{intx 1;if(x 1){inty 2;printf(x %d\r\n, x);printf(y %d\r\n, y);}printf(x %d\r\n, x);printf(y %d\r\n, y);return0;}认真想一想如果没看帖子内容之前你也能判断正常吗如果可以那你很棒我们来编译一下果然编译失败编译失败的原因是最后一个通过printf打印变量y的值的时候提示变量y为没有声明的标识符没有定义。原因其实很简单因为变量y是被声明在if所包含的花括号里面的其作用域仅限此花括号内部下面这个是对每条语句的解释int main{intx 1; //x的作用域从这行开始到main函数结束if(x 1) // y的作用域与if条件的真假没有关系{inty 2; //y的作用域仅限if语句块内部printf(x %d\r\n, x); //没有问题x在外层定义则内层可用printf(y %d\r\n, y); //没有问题y在块内定义块内可用}printf(x %d\r\n, x); //没有问题x在外层定义则外层可用printf(y %d\r\n, y); //有问题y不在其作用域内则外层不可用return0;} // x的作用域到此结束通过以上的详细注释应该理解了为什么会出现这种编译错误了吧。2、文件作用域所谓的文件作用域是指定义在所有函数外部的变量的作用域也就是我们常见的全局变量其作用域一般就是从其定义的位置开始到整个文件一般是C源文件结束都有效。这个相对来说比较好理解也不容易出错不过我们也来看代码理解一下int g_test 666; //全部变量作用域为整个源文件voidfunc(void){printf(g_test %d\r\n, g_test); //没有问题文件里面的函数的内部可以访问}intmain{func;printf(g_test %d\r\n, g_test); //没有问题main函数也可以访问return0;}以上这段代码肯定可以编译通过这个没有异议吧~~我也在代码后面加了注释毕竟还有初入职场和初识C语言的兄弟们。3、同名变量的屏蔽规则所谓的同名变量的屏蔽规则也就是在一段程序里面当内层变量和外层变量出现同一个名称的时候内层变量会自动生效外层变量会自动失效这就是内层变量屏蔽外层变量。用文字来说可能会比较抽象我们还是用代码来解释看下面代码intx 66;int main{intx 88;printf(x %d\r\n, x);{intx 99;printf(x %d\r\n, x);}printf(x %d\r\n, x);return0;}大家认为这里会打印出什么……再想想……打印结果如下为什么是这个打印这个呢结合代码增加注释如下就明白了原因intx 66; //全局变量xint main{intx 88; //局部变量x屏蔽了全局xprintf(x %d\r\n, x); //输出局部变量x的值{intx 99; //更内层的局部变量x屏蔽了外层的局部变量xprintf(x %d\r\n, x); //输出内层局部变量x的值}printf(x %d\r\n, x); //退出内层到外层外层局部变量x可见了return0;}二、我们再来看看生存期生存期————“活了多久”时间维度其实生存期的概念类似于作用域只是通过另一种角度来描述变量而已指的是变量在内存中真实存在的时间也就是从分配内存到回收内存的过程。接下来也是通过下面几个方向来举例说明便于理解。1、静态生存期所谓静态生存期也就是变量在程序开始运行时就已经被分配内存直到程序结束后才被释放这种主要包括全局变量和静态局部变量。全局变量定义在函数外面默认就是静态生存期静态局部变量static关键词修饰不能省略虽然定义在函数内部但它的值会在函数调用期间一直保留具有静态生存期看下面的代码voidcounter(void){staticint count 0;count;printf(counter被调用了 %d 次\n, count);}intmain{counter;counter;counter;return0;}程序执行结果从以上执行结果也可以看出静态局部变量count的值确实只是初始化一次其值是保留的每次运行是在上一次值的基础上加1的。静态局部变量的这种特性也使其得到广泛应用可以**上一次值且不影响代码可读性还能增加代码可维护性。2、自动生存期所谓自动生存期就是变量在进入代码块的时候自动分配内存离开代码块的时候自动释放内存比较典型的就是函数内部的局部变量都是自动生存期如下代码注释和执行结果所示voidfunc(void){int x 0; // x在这里“出生”x;printf(x %d\n, x); // 总是输出 1} // x在这里“死亡”内存被回收intmain{func;return0;}所以每次调用函数 func局部变量x 都会重新出生、初始化然后死亡所以输出***是 1虽然看似简单但这种原因引起的Bug有时候还真不容易排查因为你根本不会想到是这种操作出了问题。这里要想实现程序功能将局部变量x改成静态局部变量就可以了。3、动态生存期所谓动态生存期一般是由攻城狮自己手动控制生存期对于C语言而已即通过malloc动态申请内存通过free释放内存。如果不手动释放就会一直存在。如下代码和注释所示voidfunc(void){int *p (int *)malloc(sizeof(int)); // 申请内存p本身是局部变量指针*p 100;printf(*p %d\r\n, *p);free(p); //释放内存}intmain{func;return0;}如果没有free(p);这行内存就会一直存在造成内存泄漏; 函数结束指针变量p死亡了但它指向的那块内存依然存在且无法再被访问。以上通过实例详细介绍了C语言里面的作用域和生存期两个用于描述变量的基本概念两者其实是从不同角度描述了变量的行为和作用即作用域问的是“我能在哪用它”生存期问的是“它在内存里面待多久”最后用下面这张简图汇总一下吧现在是不是都非常明白了
更多请点击:
https://intelliparadigm.com
第一章:AI视频赋能教育的真相与数据悖论 AI视频技术正以惊人的速度渗透教育场景——从自适应微课生成、虚拟教师驱动,到课堂行为实时分析,表象繁荣之下却潜藏着一组尖锐的“数据悖论”&…
📅 2026/7/27 4:43:40
更多请点击:
https://kaifayun.com
第一章:AI全链路电商运营的核心逻辑与演进范式 AI全链路电商运营并非简单地将模型嵌入现有流程,而是以数据为血液、算法为神经、业务目标为中枢,重构“人-货-场”三要素的动态耦合关系。其核心…
📅 2026/7/27 4:43:40
1. 项目概述在嵌入式视觉和多媒体处理领域,图像缩放是一个绕不开的基础操作。无论是将高清视频流适配到不同分辨率的显示屏,还是在计算机视觉算法中对输入图像进行预处理,都需要一个高效、稳定的缩放引擎。十年前,当我第一次接触德…
📅 2026/7/27 4:43:40
1. 项目概述:从一份数据手册开始的热设计实战做嵌入式硬件设计,尤其是用到TI这类高性能处理器的项目,最怕的不是代码调不通,而是板子跑着跑着莫名其妙重启,或者性能突然下降。很多时候,问题的根源不在软件&…
📅 2026/7/27 5:57:57
1. 项目概述:为什么DDR3布局布线是高速设计的“硬骨头”干了这么多年硬件设计,每次项目评审会上,只要提到DDR3的PCB设计,会议室里的气氛总会凝重几分。这玩意儿不像电源,纹波差点还能凑合用;也不像低速接口…
📅 2026/7/27 5:57:57
从 Docker 到 runC:揭开容器运行时神秘面纱
大家好,我是你们的资深技术博主。今天我们来聊一个有趣又硬核的话题——从 Docker 到 runC。很多同学可能用过 Docker,知道它能“打包应用、随处运行”。但你有没有想过,Docker 是怎么在…
📅 2026/7/27 5:57:57
专栏:Spring Cloud 个人主页:手握风云 目录
一、负载均衡
1.1. 问题
1.2. 定义
1.3. 分类
二、Spring Cloud LoadBalancer
2.1. 快速上手
2.2. 负载均衡策略
2.3. 底层原理
三、多机部署
3.1. 前置准备
3.2. Maven 项目打包
3.3. 服务器 Jar…
📅 2026/7/27 5:57:57
1. Docker 搭建 Jenkins 服务
Jenkins 是一种持续集成的工具,提供了一个开放易用的软件平台,用于监控持续重复的工作。
1. Jenkins 镜像
查找 Jenkins 镜像:
# 查找 Jenkins 镜像
docker search jenkins
在线拉取 Jenkins 镜像ÿ…
📅 2026/7/27 5:57:57
最近马斯克在一次公开访谈中再次抛出惊人观点:"未来工作将成为可选项"。这句话在社交媒体上迅速发酵,有人欢呼"躺平时代即将到来",也有人质疑"这不过是科技富豪的乌托邦幻想"。但作为一名技术从业者࿰…
📅 2026/7/27 5:56:57
现象在 WezTerm 终端中,包含中文路径的文本(如标签页标题、Shell 提示符、路径补全)中,某些汉字时而渲染为日文字形,时而显示为简体中文(中国大陆)字形。以「径」字为例,日文写法右侧…
📅 2026/7/27 0:00:07
这个问题看似在寻找一个答案,实际上是在寻找一种“值得继续投入的方向感”。很多人在问:
“人生有什么意义?”
深层可能是在问:
我现在做的事情值得吗?我的努力有没有价值?我的存在是不是重要?未…
📅 2026/7/27 0:00:07
1. 为什么MoE架构让大模型参数量翻倍却不增加推理成本?去年我在部署一个千亿参数大语言模型时,首次接触到混合专家模型(Mixture of Experts,简称MoE)架构。当时最让我震惊的是,这种架构的模型参数量可以达到…
📅 2026/7/27 0:00:07
更多请点击:
https://codechina.net
第一章:AI帮助理解数学概念 人工智能正以前所未有的方式重塑数学学习的路径。通过自然语言处理与符号计算的深度融合,AI不仅能解析抽象定义,还能将定理、证明和几何直觉转化为可交互、可验证的…
📅 2026/7/27 1:11:21
1. 项目背景与核心价值去年参与的一个短剧项目让我深刻体会到传统创作流程的痛点:编剧团队花了三周打磨剧本,角色设计反复修改了七版,最后成片时又因为演员档期问题不得不临时调整分镜。这种低效的创作模式在快节奏的内容行业越来越难以为继。…
📅 2026/7/27 1:11:21
remix-i18next TypeScript类型安全实践:确保翻译键与类型定义同步 【免费下载链接】remix-i18next The easiest way to translate your React Router framework mode apps 项目地址: https://gitcode.com/gh_mirrors/re/remix-i18next
在开发多语言应用时&am…
📅 2026/7/27 1:11:21
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/26 7:10:22
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/26 17:10:53
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/27 5:11:32