首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C17如何声明和定义全局const字符串

C17如何声明和定义全局const字符串
EN

Stack Overflow用户
提问于 2022-10-04 08:59:20
回答 1查看 75关注 0票数 0

我必须使用C中的全局const字符串(我们使用C17作为标准),因为我们在嵌入式目标上运行这个应用程序,所以我希望我的字符串不是复制到每个翻译单元中

我知道三种方法,但我不知道该用哪种方法。

选项1

header.h

代码语言:javascript
复制
#pragma once
extern const char* pString;

source.c

代码语言:javascript
复制
#include "header.h"
const char* pString = "Foo";

选项2

(但这并不适用于所有编译器)

header.h

代码语言:javascript
复制
#pragma once
extern const char string[];

source.c

代码语言:javascript
复制
#include "header.h"
const char string[] = "Foo"

选项3

(仅在标头中定义字符串)

header.h

代码语言:javascript
复制
#pragma once
const char string[] = "Foo";

如何在C中声明全局const字符串?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-04 09:28:32

首先,#pragma once是不可移植的.除非您喜欢只为它编写不可移植的代码,否则您应该用标准的标头保护来替换它。#ifndef HEADER_H ... #define HEADER_H ... #endif。如果你只需使用非标准的功能,否则你会打喷嚏,然后保持#pragma once.

此外,通过使用全局变量在多个文件之间共享字符串文本也是错误的做法。不像共享读/写全局变量那样糟糕,但仍然是糟糕的,表明设计考虑得很差。

备选方案1

如果您希望在RAM中分配指针,那么如果您想要在闪存中分配指针,就错了。在闪存分配情况下,您需要:

代码语言:javascript
复制
const char* const pString = "Foo";

备选方案2

(但这并不适用于所有编译器)

它确实适用于所有符合标准的C编译器。它可能在某些C++编译器上不起作用,因为string是一个非常糟糕的名称选择。和str一起去。

请注意,选项2版本不分配单独的指针,而是直接引用字符串文本(它依次位于.rodata或`.text中)。

(一些半外来的微控制器可能无法直接访问此类内存中的字符串,因为它们具有一定的哈佛体系结构风格,或者因为它们可能使用页面/银行内存等,但这与标准C无关。)

备选方案3

不要这样做,这只会导致链接器问题,如果多个翻译单位试图声明的变量相互独立。它的设计也很差。

备选案文4

#define str "string literal"

这意味着字符串不一定会得到一个固定/已知的内存位置,但是编译器会将它存储在它喜欢的地方。在字符串池和类似的方面,它的效率可能会略高一些,但由于前面提到的全局变量的原因,它的设计也是有问题的。

备选方案5

代码语言:javascript
复制
// foo.h
const char* get_str (void);

// foo.c
const char* get_str (void)
{
  return "foo";
}

这是一个很好的设计与设置/getter和信息封装。不利的一面是,这不一定是在多个翻译单位内联,所以可能会有一个轻微的开销。

(您可以使它静态内联并放置在一个标题中,但之后它又回到了全局意大利面的正方形位置。)

选项1、2、4和5都是可行的,使用哪一种取决于上下文。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73945414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档