这取决于是在函数范围内char txt[19]
声明还是在全局(或命名空间)范围内声明。
如果在函数范围内,则将在堆栈上分配并在运行时从驻留在(只读)数据段中的字符串文字txt
的副本初始化。
如果在全局范围内,那么它将在构建时在数据段中分配。
奖励:如果它被分配在某个子范围内,比如循环体,那么你应该假设它会在每次循环迭代期间被初始化(优化器可能会做一些技巧,但不要指望它)。
示例 1:
int len = 18;
char txt[19] = "The cake is a lie.";
int main() {
write(len,txt);
}
这里len
(an int
) 和txt
(19 字节 + 对齐填充) 将在构建时分配到程序的数据段中。
示例 2:
int main() {
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt);
}
在这里,字符串文字"The cake is a lie."
将在构建时分配到程序的数据段中。此外,len
和txt
(19 字节 + 填充)可能会在运行时在堆栈上分配。优化器可能会忽略len
分配,甚至可能会忽略txt
,但不要指望它,因为它取决于许多因素,例如write
body 是否可用、它到底做了什么、优化器的质量等。如果有疑问,查看生成的代码(godbolt现在支持 AVR 目标)。
示例 3:
int main() {
write(18,"The cake is a lie.");
}
在这里,字符串文字"The cake is a lie."
将在构建时分配到程序的数据段中。将18
嵌入程序代码中。
由于您在 AVR 上进行开发,因此还有一些额外的细节值得一提,即应用程序的可执行文件最初存储在Flash中,一旦您“运行”它,它就会被复制到 RAM 中。可以避免复制到 RAM 并使用PROGMEM
关键字将数据保留在 Flash 中(尽管要对数据做任何有意义的事情,您需要将其复制到 RAM 中)。