将映射分配给 char*.. 这是如何工作的? 包括代码示例

问题描述

我正在尝试使用一些现有代码,但我遇到了这段代码,但我不太明白它是如何工作的:

char *c_token = R(
{
  "1":"abcdef","2":"ghijkl","3":"mnopqr","4":"stuvwx"
});

其中 R() 定义为:

#define R(...) #__VA_ARGS__

c_token 缓冲区在这之后是什么样子的?与仅分配 map 相比,这样做有什么优势吗?我正在尝试阅读代码,但老实说我不明白这是在做什么。

假设这是用来传递这张地图的,你如何将它翻译回另一端的地图?

解决方法

预处理器正在将括号之间的所有内容(包括逗号)转换为字符串文字。它几乎可以是完全的语法垃圾。例如:这很好。 R(!@#,*&#,(,));

作为实验,尝试:

#define R(...) "BEGIN" #__VA_ARGS__ "END"

这产生:"BEGIN!@#,)END"

并比较当你这样做时会发生什么:

#define R(x) "BEG" #x "END"

这会产生:"BEGIN!@#END" 并带有如下警告:

类似函数的宏调用'R'的参数过多

,

这里发生的是预处理器StringificationR() 的参数中出现的任何内容都将转换为字符串。宏参数前面的 # 是导致这种情况的语法。

所以 R("foo",abc!@#) 变成了字符串字面量 "\"foo\",abc!@#"。换行符和前导空格将转换为单个空格。

这样做的原因是使包含大量 " 的字符串更易于编写,无需对它们进行转义,并允许更轻松的换行。如果您直接直接编写 JSON 字符串,则每个 " 都需要写为 \" 以防止它分隔字符串。每行还需要结束字符串并在下一行开始新的一行,因为字符串文字中不能有换行符。

所以这个例子可以写成:

const char *c_token = 
"{"
  "\"1\":\"abcdef\","
  "\"2\":\"ghijkl","
  "\"3\":\"mnopqr","
  "\"4\":\"stuvwx""
"}";

宏允许的更自然的语法更复杂。