【问题标题】:How to reuse a literal in a char and a one-character string constant?如何在 char 和单字符字符串常量中重用文字?
【发布时间】:2015-04-25 17:13:36
【问题描述】:

我需要在 c 代码中指定一个参数短选项(例如 -F)作为 charchar[] 常量。为了最大限度地重用代码,我想声明一个变量,它允许我在一个地方更改值(“文字” - 不是字符串或char 文字,而是抽象概念的意义)。我更喜欢一个专门在预处理器常量和函数/宏中或专门在 c 代码中解决这个问题的解决方案,以很好地解释为什么必须在两者的混合中解决这个问题。

我试过/检查了

  • #define FOREGROUND_OPTION_VALUE 'F',这导致我无法将其转换为char[](作为预处理器常量)(编写一个使用# 进行字符串化的宏会导致' 引号也被字符串化
  • 省略 ' 引号,这让我无法创建 ' 引号或以其他方式创建 char
  • @PedroWitzel 的答案是声明 char[] 并将第 0 个 char 用于另一个常量。这很好,但我更喜欢从char 创建char[] 的方法,因为这会强制两者相等(否则我必须添加一个编译时断言char[] 不长于@ 987654337@)。

对我来说唯一重要的是代码维护,没有其他事情(比如处理代码的成本(在编译或运行时 - 如果可能有的话,没有深入反映)。

【问题讨论】:

  • 只有在代码处理过程中(字面上)没有成本的情况下,才值得保存一个字符的数据。

标签: c string


【解决方案1】:

除了commentsPedro Witzelanswer 中的讨论之外,还有另一种选择:

#define FOREGROUND_OPTION_VALUE 'F'

static const char fg_opt_str[] = { FOREGROUND_OPTION_VALUE, '\0' };

这不是初始化字符串的常用方法,但它是一种有效的方法,似乎适合您的场景。现在您可以在需要常量char(或int)值的地方使用 FOREGROUND_OPTION_VALUE,在需要单字符字符串的地方使用fg_opt_str。如果您更改定义的值(例如更改为f),那么您只需更改一处代码即可继续工作,假设您之前没有使用f,这符合您的可维护性要求。

【讨论】:

  • 谢谢。正如我的问题中提到的,关于预处理器定义和 c 源代码的这种混合是否是必要(除了它绝对有效的事实)的声明将不胜感激。
  • 这取决于你想做什么。如果您的代码仅处理字符串或仅处理字符常量,则可能没有必要。但是,如果您需要两者并且它们需要自动保持同步,那么您将需要按照此处概述的线条和 Pedro Witzel 的一些技术来完成这项工作。哪个最适合您取决于您​​的要求。我们看不到您的代码,无法就此提供建议。
  • 我需要一个常数,并且在最初的问题中没有指出这一点,这不是很聪明。很清楚我是否需​​要一个常量,但是?!
  • 如果您需要字符串文字(用于字符串连接等)以及字符常量,那么我不知道有没有办法得到它;我们回到了开始的地方。有些事情不值得为之争战。您可以安排生成必须保持同步的代码:例如,给定规范 FOREGROUND_OPTION F,您的代码生成器可能会生成 #define FOREGROUND_OPTION_VALUE 'F'#define FOREGROUND_OPTION_STRING "F" — 代码生成器可以像 sed 脚本一样简单.
【解决方案2】:

static constant 变量对你有用吗?

static const char FOREGROUND_OPTION_VALUE[] = "F";

【讨论】:

  • 如何在一个地方重用 F 的规范为 charchar[]
  • @KarlRichter:当你需要字符串时你使用FOREGROUND_OPTION_VALUE,当你需要char时你使用*FOREGROUND_OPTION_VALUE
  • @KarlRichter:当你想要一个字符串时使用FOREGROUND_OPTION_VALUE,当你想要一个字符时使用FOREGROUND_OPTION_VALUE[0]*FOREGROUND_OPTION_VALUE。这是最好的。您将无法在switch 语句中将其用作case 标签,但除此之外,它应该是可行的。您也可以在问题中使用#define FOREGROUND_OPTION_VALUE "F",以及我建议的任一表达式来访问该字符。
  • 我认为你不能对两种不同的类型使用相同的变量,女巫本质上是 char 和 char*。正如@JonathanLeffler 所建议的那样,我想说最好的方法是正确投射。它会提高可读性和代码维护,因为您可以确定使用正确的类型。
猜你喜欢
  • 2015-09-17
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
相关资源
最近更新 更多