嵌入式C程序中Const节省内存空间细节问题??

Frey_Liu 2016-10-09 11:41:34
如下例是一个网上找的说明const节省存储空间的例证:
#define M 3 //宏常量
const int N = 5; //此时并未将N放入内存中
int main()
  {
  int i = N; //此时为N分配内存 ,以后不再分配
  int I = M; //预编译期间进行宏替换,分配内存
int j = N; //没有内存分配
int J = M; //在进行宏替换,又一次分配内存
  }
const定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的只读变量在程序运行过编译阶段进行替换,而const修饰的只读变量是在编译的时候确定其值。#define宏没有类型,而const修饰的只读变量具有特定的类型。
问题:
1. 记得调试时看到用const修饰的只读变量都是和代码放置在一起的,对MCU来说也就是ROM。我想问的是如果程序运行中调用该只读变量,还会降该变量重新拷贝到RAM中吗??多次调用该只读常量就只有第一次调用时拷贝到RAM中??

2. 对于那些const 修饰的比较大的只读常量被运行中的程序调用时有时怎么处理的??如const修饰的1k 的只读数组,RAM只有1K或者RAM小于1K时,程序还会将const 修饰的只读常量拷贝到RAM中吗??显然是不可能的。

3.如果对于普通的嵌入式系统,节省的是MCU的RAM还是ROM啊,好像只是ROM吧!


突然想起这个问题,由于手头没有可调试的工具,只能在网上请求各位大神了!见笑!!!
...全文
1677 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hailee1985 2016-12-12
  • 打赏
  • 举报
回复
和芯片有很大关系吧,也就是和对应的编译器有关。普通单片机,const变量都是在flash里面,从这个意义上讲,根本就不占用内存空间呢
fuchouzhe 2016-10-10
  • 打赏
  • 举报
回复
问题1和2:不会,根本就不会复制到RAM中而是“就地”使用 问题3:你看到的只是51等早期单片机的编程思路,RAM资源少,当然要节约使用。
of123 2016-10-10
  • 打赏
  • 举报
回复
这与编译器以及你的使用需求相关。 比如,你在 Codewarrior 中,可以在 .lcf 文件中为一个变量或数组定义 Flash(ROM) 存储地址和内存链接地址。并用类似 Startup.c 中的例程将其内容从存储地址复制到链接地址。对于运行程序来说,它不知道初始数据固化存储在哪里。当然,你也可以将其置于唯一的 Flash(ROM)地址,或者理解为它的存储地址和链接地址相同。 对于 C51 编译器,加 code 关键词有初值的变量或数组,就是在 Flash(ROM)中。你对它直接访问,不一定要复制到 RAM 中。
maxwell11 2016-10-10
  • 打赏
  • 举报
回复
这个其实是要理解编译器工作的。 程序编译完后 分为 代码段,数据段。 数据段又分为,初始化段,非初始化段。 初始化段里分为,只读段,读写段。 程序在加载时分为:加载时域(loadtime),运行时域(runtime) 以一个ARM嵌入式系统为例:上电时,bootloader将flash中的程序加载到sdram中(sdram中的起始地址就是加载时域),加载完成cpu开始从reset的段执行startup,startup会将加载的程序按运行时域再分配到对应的地址(比如:代码放在0地址,只读数据紧接着代码放,读定段(全局变量)放在xxx地址,清0段放在yyy地址,bss(非初始化段)放在zzz地址)。 明白这些后可以发现,const主义的只读段跟代码段的权限是差不多的,会紧跟着代码存放。对于不需要加载到RAM中运行的系统,加载时域与运行时域由编译器来处理,在烧录到ROM中时已经确定了地址。程序运行时只有读写段的数据会被加载到RAM,代码段跟只读段在ROM中原来的位置。
老规矩,先看本节效果图我们实现这个支付功能完全是借助小程序云开发实现的,不用搭建自己的服务器,不用买域名,不用备案域名,不用支持https。只需要一个简单的云函数,就可以轻松的实现微信小程序支付功能。核心代码就下面这些一,创建一个云开发小程序关于如何创建云开发小程序,这里我就不再做具体讲解。不知道怎么创建云开发小程序的同学,可以去翻看我之前的文章,或者看下我录制的视频:https://edu.csdn.net/course/play/9604/204528创建云开发小程序有几点注意的1,一定不要忘记在app.js里初始化云开发环境。2,创建完云函数后,一定要记得上传二, 创建支付的云函数1,创建云函数pay三,引入三方依赖tenpay我们这里引入三方依赖的目的,是创建我们支付时需要的一些参数。我们安装依赖是使用里npm 而npm必须安装node,关于如何安装node,我这里不做讲解,百度一下,网上一大堆。1,首先右键pay,然后选择在终端打开2,我们使用npm来安装这个依赖。在命令行里执行 npm i tenpay安装完成后,我们的pay云函数会多出一个package.json 文件到这里我们的tenpay依赖就安装好了。四,编写云函数pay完整代码如下//云开发实现支付 const cloud = require('wx-server-sdk')cloud.init() //1,引入支付的三方依赖 const tenpay = require('tenpay'); //2,配置支付信息 const config = ;exports.main = async(event, context) => 一定要注意把appid,mchid,partnerKey换成你自己的。到这里我们获取小程序支付所需参数的云函数代码就编写完成了。不要忘记上传这个云函数。出现下图就代表上传成功五,写一个简单的页面,用来提交订单,调用pay云函数。这个页面很简单,1,自己随便编写一个订单号(这个订单号要大于6位)2,自己随便填写一个订单价(单位是分)3,点击按钮,调用pay云函数。获取支付所需参数。下图是官方支付api所需要的一些必须参数。下图是我们调用pay云函数获取的参数,和上图所需要的是不是一样。六,调用wx.requestPayment实现支付下图是官方的示例代码这里不在做具体讲解了,完整的可以看视频。实现效果1,调起支付键盘2,支付完成3,log日志,可以看出不同支付状态的回调上图是支付成功的回调,我们可以在支付成功回调时,改变订单支付状态。下图是支付失败的回调,下图是支付完成的状态。到这里我们就轻松的实现了微信小程序的支付功能了。是不是很简单啊,完整的讲解可以看视频。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧