str预处理器中的strlen?

是否可以在C预处理器中实现strlen()

鉴于:

 #define MYSTRING "bob" 

是否有一些预处理器宏, X ,让我说:

 #define MYSTRING_LEN X(MYSTRING) 

它不使用预处理器,但sizeof在编译时解析。 如果您的字符串在数组中,您可以使用它来确定编译时的长度:

 static const char string[] = "bob"; #define STRLEN(s) (sizeof(s)/sizeof(s[0])) 

请记住,与strlen()不同,上面的STRLEN将包含null终止符。

是的: #define MYSTRING_LEN(s) strlen(s)

在大多数编译器中,这将为常量参数生成编译时常量…并且你不能做得更好。

换句话说:你不需要宏,只需使用strlen; 编译器足够聪明,可以为您完成工作。

你可以做:

 #define MYSTRING sizeof("bob") 

在我的机器上说4,因为null添加到最后。

当然这仅适用于字符串常量。


使用MSVC 16( cl.exe -Wall /TC file.c ):

 #include "stdio.h" #define LEN_CONST(x) sizeof(x) int main(void) { printf("Size: %d\n", LEN_CONST("Hej mannen")); return 0; } 

输出:

 Size: 11 

字符串的大小加上NUL字符。

通常,C预处理器实际上并不转换任何数据,它只替换它。 这意味着您可能能够执行此类操作,前提是您使用实现(function)持久数据结构的数据污染C预处理器命名空间。

也就是说,你真的不想这样做,因为一旦你传入一个字符串以外的东西,整个“添加”function将会失败。 C预处理器没有数据类型的概念,也没有内存解引用的概念(如果你想要存储在变量中的字符串的长度,则很有用)。 基本上,这将是一个有趣的“看你能走多远”的运动,但最后,你会有一个MYSTRING_LEN只能带你到目标的一小段距离。

此外,C预处理器缺少名称空间意味着这样的宏扩展系统不可包含。 人们必须注意保持生成的名称不会干扰其他有用的宏。 最后,您可能会在预处理器中耗尽内存以用于任何重要用途,因为预处理器实际上并不是为每个转换为“单元”令牌的字符保留名称,而是名称为每个“单位”令牌压缩成其最终的十进制表示法。