C 中 #define 的区别 - char 与 char*

Difference in #define in C - char vs char*

想问一下有什么区别:

#define STR 'a'

#define STR "a"

我认为不同之处在于第一个作为单个 char 传递,第二个作为 char* 传递并且是一个双字符数组,如:['a','[=14= ]'].

你刚才搞错了宏的全部要点。宏是无类型的。它们没有数据类型。它们只是文本。只是文字。

例如

#define X 'a'
printf("%c\n", X);

这将首先进行预处理并生成以下代码:

printf("%c\n", 'a');

然后将编译此代码,您将获得程序集。

如果您有此代码:

#define X WobbleWobbleJobbleTheDobble__
printf("%d\n", X);

然后预处理器将产生这个:

printf("%d\n", WobbleWobbleJobbleTheDobble__);

显然编译会失败,但预处理器不在乎。 macors 所做的只是替换文本。

#define X "a"

预处理器会在整个代码中寻找标识符X,并将其替换为"a"。宏只是文本。

顺便说一句,是的,您在最后一段中的想法是正确的:

void *ch = "a";

ch其实是有类型的,不像宏那样是文本

宏不是对象。在被替换之前它们没有任何意义

在 C 中 'a'character constant of type int, and "a" is a string literal of type char[N] (with N = 2 in this case). But there's much more than that. Firstly, multiple consecutive string literals will be concatenated into a single literal. For example the below snippet will print xyzabca:

#define STR "a"
const char str1[] = "xyz" STR "bc";
printf("%s" STR "\n", str1);

可以看到,STR宏的内容只是最终结果的一部分。输出中没有 "a" 数组,生成的文字不是 2 字符数组。你不能像那样连接字符常量

另一件事是字符和字符串文字都可以有前缀,如 LUuu8... 所以替换后的结果文本可能是完全不同的类型

#define CONCAT2(str) L##str
#define CONCAT(str)  CONCAT2(str)
#define STR_S        "a"
#define STR_C        'a'

int main() {
    wchar_t c = STR_C;
    printf("wstring: %ls, wchar_t: %lc\n", CONCAT(STR_S), CONCAT(STR_C));
}

所以上面的代码中根本就没有char[N],只有wchar_t[N]。参见 demo