嵌入式软件-为什么查找表中需要“const”?

嵌入式软件-为什么查找表中需要“const”?,c,memory,embedded,lookup,lookup-tables,C,Memory,Embedded,Lookup,Lookup Tables,我刚刚在LinkedIn上看了这段视频 查找表,它提到,如果没有“const”限定符,数组将在RAM中分配,初始分配将在启动期间发生,整个表将存储两次—在RAM和ROM中 有人能更详细地给我解释一下吗?为什么要存储两次?这是否意味着所有不带“const”的变量/数组都会被存储两次?切换情况是否比没有常量的查找表更好 提前感谢。微控制器通常都有比RAM更多的闪存,除了无闪存的。将常量数据放在RAM中是一种浪费 当您使用const关键字时,大多数工具链将数据放在位于只读存储器-闪存中的.rodata

我刚刚在LinkedIn上看了这段视频 查找表,它提到,如果没有“const”限定符,数组将在RAM中分配,初始分配将在启动期间发生,整个表将存储两次—在RAM和ROM中

有人能更详细地给我解释一下吗?为什么要存储两次?这是否意味着所有不带“const”的变量/数组都会被存储两次?切换情况是否比没有常量的查找表更好


提前感谢。

微控制器通常都有比RAM更多的闪存,除了无闪存的。将常量数据放在RAM中是一种浪费

当您使用const关键字时,大多数工具链将数据放在位于只读存储器-闪存中的.rodata部分。例如,一些uC类型的AVR需要使用特殊的机制来访问这些数据,对于大多数现代的AVR,快速uC需要使用等待状态来减慢读写操作几乎没有区别,因为闪存比SRAM慢

您还可以使用属性和pragmas强制将静态常量自动变量放置在ROM中

gcc静态常量字符_属性_节.rodata x;节可能有不同的名称-检查您的工具链文档

但它只适用于全局变量——大多数实现将自动常量变量放在位于RAM中的堆栈上

编辑 静态常数也可以仅存储在ROM中。但几年前,我在uC gcc的一个分支机构有一次糟糕的经历。确保-检查您的工具链对这些变量所做的操作


因此,const对于查找表来说不是必需的,但是保存通常非常有限的资源(SRAM)是合乎逻辑的。

由于C,const不是必需的。它取决于编译器和处理器。你使用的是什么处理器和编译器?关于常量限定符,你在教科书中找不到什么不清楚的地方?从晦涩难懂的在线教程或YT视频中学习C是个坏主意。可能的答案是,如果您声明了一个查找表或任何不带常量的数据结构,并为其提供初始数据,那么系统必须同时具有初始数据的副本和用于查找表的单独空间。这是因为,由于表不是常量,编译器必须考虑到这样一个事实,即某些东西可能会改变它,除非它可以通过检查所有代码来证明不是这样。因此,为了创建请求的表,编译器必须安排程序为表留出空间,并且必须用初始数据填充该空间。为此,……初始数据必须可用。所以一定有它的副本。相反,如果表是用const定义的,那么初始数据本身就可以充当表。包含初始数据的表只有一个副本,并且它只被读取,从不被修改,因此初始数据不需要单独的副本。@EricPostphil谢谢。太清楚了!全局变量是永久的。在自动变量的情况下,堆栈内存在函数退出时被回收,因此它们在SRAM上不那么贪婪。谢谢@P_uuj_uu_uu1我仍然困惑的是,当不使用const时,为什么数组同时存储在RAM和ROM中?你能解释一下吗?关于全局变量部分-如果是局部变量,它可能会溢出堆栈,因为每次调用都需要分配它,对吗?我想使用静态限定符可以解决这个问题。除非是别的问题。@ShantanuMhapankar SRAM中的一个初始化变量也必须存在于ROM中,因为它的数据必须从某处复制。至于对自动变量使用静态限定符,这与使其成为全局变量的内存使用相同,是的,初始化的自动变量在每次函数调用时都需要从ROM复制数据。静态局部变量的效果是,它与全局变量保持在相同的内存空间中,但对函数是私有的。@WeatherVane不那么贪婪,但如果您有1k SRAM堆栈,它也非常有限。是我写错了什么,还是有人只是感到沮丧