为什么C语言全局变量初始化元素必须是常量,而局部变量可以不是常量

news2025/1/17 2:57:50

前言

(1)今天看到一个有意思的问题,在交流群中,一位网友问,全局变量为什么不能给变量。会出现initializer element is not constant报错,代码如下

#include <stdio.h>

int a = 1;
int b = a+1; //这里会报错initializer element is not constant

int main(void)
{
	printf("a = %d\r\n",a);
	printf("b = %d\r\n",b);
	return 0;
}

(2)一般来说,全局变量我们都是默认给的一个常量数字,局部变量赋值给一个变量。关于上述问题,我也表示疑惑,于是我带着疑问,开始查找资料。

#include <stdio.h>

int a = 1;

int main(void)
{
	int b = a+1;
	printf("a = %d\r\n",a);
	printf("b = %d\r\n",b);
	return 0;
}

解释

全局变量和局部变量存储位置

(1)想要弄清楚这个问题,首先,我们需要知道全局变量和局部变量存储有什么区别?想了解具体信息,请看:RAM明明断电会丢失数据,为什么初始化的全局变量存储在RAM?详细分析程序的存储;
(2)因为上面的文章篇幅比较大,所以我浓缩一下。
<1>被赋值为非0的全局变量,最终会存储在.data段。他在编译时候,会变成RW-data,他的初始值是需要存储在ROM区域的。
<2>而局部变量,并不会被编译进入单片机,也就是说,他在单片机断电状态是不占空间的。
<3>当单片机上电之后,会给全局变量在RAM中分配出一个静态数据区。同时把初值赋值到这个静态数据区的.data段。
<4>单片机上电并且开始运行程序之后,调用到了局部变量所存在的那个函数时候。单片机才会给局部变量在栈中分配空间,然后赋初值是在运行过程中,执行代码实现的。
<5>因此,我们可以得出结论。被赋初值的全局变量,初始值是静态存储。而被赋初值的局部变量,初始值是动态存储。
(4)了解了上述之后,我们就能够明白为什么局部变量赋初始值可以被通过了,因为他是动态的,所以编译器不会管他。但是为什么全局变量又不可以呢?这就涉及,静态存储的数据与编译器之间的关系了。

编译器有关

(1)我们都知道,编译器能够将C语言变成机器所能够识别的01语言。而编译器的还有一些功能,常常被我们所忽视了。
(2)为了能够让程序更加小巧精炼,编译器会帮我们处理很多事情。这就引出了一个概念,用编译器的时间换运行态的时间
<1>编译时:您(开发人员)编译代码的时间段。
<2>运行时间:用户运行您的软件的时间段。
(3)例如下面这个简单的代码:
<1>我们能够发现int b = 2 + 3;转换称为汇编代码之后,他是直接将5传递给了b。这个就是编译器进行了运算处理,对代码进行了优化。这个叫做常量折叠
<2>sizeof这个运算同理,编译器会直接将int是4个字节这个信息传递给变量。

在这里插入图片描述

(4)上述两个例子都是用编译器的时间换运行态的时间。那么讲了这么多,和全局变量初始化元素必须是常量有什么关系呢?
(5)上面说了,编译器会进行常量折叠,但是请注意,这里是常量折叠!常量折叠会将常量表达式在编译器运行时期计算出来,整型字面量、sizeof()运算符(当参数不是VLA时),枚举常量,以及各种算术、关系/比较运算符在所有操作数都是整型常量时,整个表达式都会算是整型常量表达式。

在这里插入图片描述

(6)但是,我们发现了没有,编译器是不会进行变量的运算的!因此,全局变量int b = a+1;这样赋初值,编译器是不会进行运算的!

总结

(1)因此,我们可以得出结论:
<1>编译器无法在编译时求得一个非常量的值,它只能在运行时通过读取变量地址来间接得到变量的值,而全局变量在编译时就必须确定其值。
<2>局部变量的初始值是不由编译器管理,他是在运行时进行的分配,因此可以初值可以赋予变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/885017.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zabbix-6.4.4 邮箱告警SMS告警配置

目录 ​------------------------- # 邮箱告警 ---------------------------------- 1.安装mailx与postfix软件包 2.修改mailx配置文件 3. 创建文件夹 4. 编写mail-send.sh脚本 5. 将该脚本赋予执行权限 6. 进入web界面进行设置—> Alerts —> Media Types 7. 添…

C++11并发与多线程笔记(3)线程传参详解,detach()大坑,成员函数做线程函数

C11并发与多线程笔记&#xff08;3&#xff09;线程传参详解&#xff0c;detach 大坑&#xff0c;成员函数做线程函数 1、传递临时对象作为线程参数1.1 要避免的陷阱11.2 要避免的陷阱21.3 总结 2、临时对象作为线程参数2.1 线程id概念2.2 临时对象构造时机抓捕 3、传递类对象…

数据结构算法--3快速排序

快速排序比冒泡排序&#xff0c;选择排序&#xff0c;插入排序速度都快 快速排序思路&#xff1a; ^取一个元素P&#xff0c;(第一个元素)&#xff0c;使元素P归位。 ^列表被P分成了两部分&#xff0c;左边都比P小&#xff0c;右边都比P大。 ^递归完成排序。 过程: 把5拿出…

FreeRTOS中断优先级测试

目录 资源配置 测试方案 易出 bug 测试代码 资源配置 1、定时器3中断优先级为3 2、定时器4中断优先级为4 3、FreeRTOS中断配置 OS系统管理不高于中断优先级4的中断。 #ifdef __NVIC_PRIO_BITS /* __NVIC_PRIO_BITS 已经在stm32f1xx.h里面定义为4 */#define configPRIO_B…

poetry add scipy || Poetry安装scipy失败

这里出现了一个使用poetry安装scipy失败的报错 poetry add scipy 大致意思是说&#xff0c;找不到需要的库和目前的python在版本上的交集&#xff0c;所以安装不了。 这可能与自己在poetry环境中已经安装的库有关。 但不管怎么说&#xff0c;我的这个3.10版本会装不了都是一…

【STM32RT-Thread零基础入门】 4. 线程介绍(理论)

文章目录 前言一、线程的概念二、线程的调度三、上下文切换四、线程的重要属性1. 线程栈2. 线程的状态3. 线程优先级4. 线程时间片5. 线程的入口函数 五、RT-Thread命令查看系统线程信息总结 前言 前文中的最后一个任务发现&#xff0c;一个main()函数很难同时实现按键功能和闪…

基于浏览器的插件sider,使用chatgpt3.5生成的连接Redis的代码

一.安装 首先在浏览器安装Sider插件&#xff0c;具体安装步骤https://www.423xz.com/gaoxiao/3949.html 收费情况&#xff1a;每天有几次的免费使用chatgpt3.5的次数&#xff0c;chatgpt4需要付费了。 二.使用步骤&#xff1a; 安装后使用&#xff0c;具体步骤&#xff1a;…

20 张图,透析HTTPs五大知识点

本文详细介绍了 HTTPS 相较于 HTTP 更安全的原因&#xff0c;包括对称加密、非对称加密、完整性摘要、数字证书以及 SSL/TLS 握手等内容&#xff0c;图文并茂、理论与实战结合、建议收藏&#xff01; 1. 不安全的 HTTP 近些年来&#xff0c;越来越多的网站使用 HTTPS 协议进行…

OpenCV-Python中的图像处理-霍夫变换

OpenCV-Python中的图像处理-霍夫变换 霍夫变换霍夫直线变换霍夫圆环变换 霍夫变换 霍夫(Hough)变换在检测各种形状的技术中非常流行&#xff0c;如果要检测的形状可以用数学表达式描述&#xff0c;就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使…

【产品设计】用设计讲好故事 – JOOX 2020听歌年榜总结

JOOX是腾讯面向东南亚市场战略性的音乐App&#xff0c;作为一个国家化品牌&#xff0c;它面临着一些困难&#xff0c;但同时它通过创意的方式将自己的产品价值观传递给用户。我们在设计产品中&#xff0c;做好一个设计项目&#xff0c;就好比讲一个故事&#xff0c;但这只是一种…

基于php驾校驾驶理论考试模拟系统

驾校驾驶理论考试模拟系统&#xff0c;是基于php编程语言&#xff0c;mysql数据库进行开发&#xff0c;本系统分为用户和管理员两个角色&#xff0c;其中用户可以注册登陆系统&#xff0c;查看考试规则&#xff0c;进行驾照考试&#xff0c;查看考试得分&#xff0c;考试错题&a…

docker安装国产开源数据库tidb 单机版

docker pull pingcap/tidb 创建目录&#xff0c;然后安装tidb mkdir -p /data/tidb/data 创建容器 docker run --name tidb -d -v /data/tidb/data:/tmp/tidb --privilegedtrue -p 4000:4000 -p 10080:10080 pingcap/tidb:latest TiDB 简介 | PingCAP 文档中心

将您的 Ins 形象提升到新的水平

在当今这个社交媒体盛行的时代&#xff0c;Ins已成为人们展示个性、吸引关注的重要平台。你是否曾经想过&#xff0c;如果能够在同一个 Ins账户上展示不同的形象&#xff0c;让你的粉丝感受到更多的惊喜和乐趣呢&#xff1f;多账户登录功能正是满足这一需求的利器&#xff0c;它…

【我们常说这个pycharm里有陷阱,第三方库导入失败,看这里!】

最近有小伙伴遇到了明明安装了 python 第三方库,但是在 pycharm 当中却导入不成功的问题。 前言 一直以来,也有不少初学 python 的小伙伴,一不小心就跳进了虚拟环境和系统环境的【陷阱】中。 本文就基于此问题,来说说在 pycharm 当中如何使用系统环境、虚拟环境。 pych…

机器学习理论笔记(一):初识机器学习

文章目录 1 前言&#xff1a;蓝色是天的机器学习笔记专栏1.1 专栏初衷与定位1.2 本文主要内容 2 机器学习的定义2.1 机器学习的本质2.2 机器学习的分类 3 机器学习的基本术语4 探索"没有免费的午餐"定理&#xff08;NFL&#xff09;5 结语 1 前言&#xff1a;蓝色是天…

基于php动漫周边电商购物网站系统

动漫周边电商网站系统&#xff0c;是基于php毕业设计&#xff0c;mysql数据库进行开发&#xff0c;本系统分为用户和管理员两个角色&#xff0c;其中用户可以注册登陆系统&#xff0c;用户查看商品分类&#xff0c;商品列表&#xff0c;查看动漫周边商品详情&#xff0c;加入购…

【Java】BF算法(串模式匹配算法)

☀️ 什么是BF算法 BF算法&#xff0c;即暴力算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个与模式串T的第一个字符串进行匹配&#xff0c;若相等&#xff0c;则继续比较S的第二个字符和T的第二个字符&#xff1b;若不相等&#xff0c;则…

股票配资app是什么?是怎么一回事?

股票配资App是一种通过手机应用程序进行股票配资的工具。随着移动互联网的发展&#xff0c;越来越多的投资者选择使用手机进行股票交易&#xff0c;股票配资App应运而生。本文将对股票配资App进行详细解释。 股票配资App是一种便捷的投资工具&#xff0c;可以让投资者通过手机…

酷开系统 | 酷开科技大数据,更好的与目标消费人群建立联系

众所周知&#xff0c;OTT的一大优势在于强曝光&#xff0c;能够给消费者带来强烈的视觉冲击&#xff0c;强化品牌认知。但是&#xff0c;要想达到提升品牌认知&#xff0c;首先要保证OTT的流量规模&#xff0c;实现对目标人群的有效覆盖。得年轻消费者得“天下”&#xff0c;年…

防雷检测行业应用完整解决方案

防雷检测是指对雷电防护装置的性能、质量和安全进行检测的活动&#xff0c;是保障人民生命财产和公共安全的重要措施。防雷检测的作用和意义主要有以下几点&#xff1a; 防止或减少雷电灾害事故的发生。雷电是一种自然现象&#xff0c;具有不可预测、不可控制和高能量等特点&a…