我必须使用C中的全局const字符串(我们使用C17作为标准),因为我们在嵌入式目标上运行这个应用程序,所以我希望我的字符串不是复制到每个翻译单元中
我知道三种方法,但我不知道该用哪种方法。
选项1
header.h
#pragma once
extern const char* pString;source.c
#include "header.h"
const char* pString = "Foo";选项2
(但这并不适用于所有编译器)
header.h
#pragma once
extern const char string[];source.c
#include "header.h"
const char string[] = "Foo"选项3
(仅在标头中定义字符串)
header.h
#pragma once
const char string[] = "Foo";如何在C中声明全局const字符串?
发布于 2022-10-04 09:28:32
首先,#pragma once是不可移植的.除非您喜欢只为它编写不可移植的代码,否则您应该用标准的标头保护来替换它。#ifndef HEADER_H ... #define HEADER_H ... #endif。如果你只需使用非标准的功能,否则你会打喷嚏,然后保持#pragma once.
此外,通过使用全局变量在多个文件之间共享字符串文本也是错误的做法。不像共享读/写全局变量那样糟糕,但仍然是糟糕的,表明设计考虑得很差。
备选方案1
如果您希望在RAM中分配指针,那么如果您想要在闪存中分配指针,就错了。在闪存分配情况下,您需要:
const char* const pString = "Foo";备选方案2
(但这并不适用于所有编译器)
它确实适用于所有符合标准的C编译器。它可能在某些C++编译器上不起作用,因为string是一个非常糟糕的名称选择。和str一起去。
请注意,选项2版本不分配单独的指针,而是直接引用字符串文本(它依次位于.rodata或`.text中)。
(一些半外来的微控制器可能无法直接访问此类内存中的字符串,因为它们具有一定的哈佛体系结构风格,或者因为它们可能使用页面/银行内存等,但这与标准C无关。)
备选方案3
不要这样做,这只会导致链接器问题,如果多个翻译单位试图声明的变量相互独立。它的设计也很差。
备选案文4
#define str "string literal"
这意味着字符串不一定会得到一个固定/已知的内存位置,但是编译器会将它存储在它喜欢的地方。在字符串池和类似的方面,它的效率可能会略高一些,但由于前面提到的全局变量的原因,它的设计也是有问题的。
备选方案5
// foo.h
const char* get_str (void);
// foo.c
const char* get_str (void)
{
return "foo";
}这是一个很好的设计与设置/getter和信息封装。不利的一面是,这不一定是在多个翻译单位内联,所以可能会有一个轻微的开销。
(您可以使它静态内联并放置在一个标题中,但之后它又回到了全局意大利面的正方形位置。)
选项1、2、4和5都是可行的,使用哪一种取决于上下文。
https://stackoverflow.com/questions/73945414
复制相似问题