C语言 C 预处理器中的 strlen?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5022067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
strlen in the C preprocessor?
提问by Joby Taffey
Is it possible to implement strlen()in the Cpreprocessor?
是否可以strlen()在C预处理器中实现?
Given:
鉴于:
#define MYSTRING "bob"
Is there some preprocessor macro, X, which would let me say:
是否有一些预处理器宏,X让我说:
#define MYSTRING_LEN X(MYSTRING)
回答by nmichaels
It doesn't use the preprocessor, but sizeof is resolved at compile time. If your string is in an array, you can use that to determine its length at compile time:
它不使用预处理器,但 sizeof 在编译时解析。如果你的字符串在一个数组中,你可以在编译时使用它来确定它的长度:
static const char string[] = "bob";
#define STRLEN(s) (sizeof(s)/sizeof(s[0]))
Keep in mind the fact that STRLENabove will include the null terminator, unlike strlen().
请记住STRLEN,与strlen().
回答by Skurmedel
You can do:
你可以做:
#define MYSTRING sizeof("bob")
That says 4 on my machine, because of the null added to the end.
在我的机器上显示为 4,因为最后添加了 null。
Of course this only works for a string constant.
当然,这只适用于字符串常量。
Using MSVC 16 (cl.exe -Wall /TC file.c) this:
使用 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;
}
outputs:
输出:
Size: 11
The size of the string plus the NUL character.
字符串的大小加上 NUL 字符。
回答by Jim Balter
Yes:
#define MYSTRING_LEN(s) strlen(s)
是的:
#define MYSTRING_LEN(s) strlen(s)
In most compilers, this will produce a compile-time constant for a constant argument ... and you can't do better than that.
在大多数编译器中,这将为常量参数生成一个编译时常量......而且你不能做得比这更好。
In other words: you dont need a macro, just use strlen; the compiler is smart enough to do the work for you.
换句话说:您不需要宏,只需使用 strlen;编译器足够聪明,可以为您完成这项工作。
回答by Edwin Buck
Generally the C pre-processor doesn't actually transform any data, it only replaces it. This means that you might be able to perform such an operation provided that you pollute your C pre-processor namespace with data implementing (functional) persistent data structures.
通常,C 预处理器实际上并不转换任何数据,它只是替换它。这意味着您可能能够执行这样的操作,前提是您使用实现(功能性)持久数据结构的数据污染了 C 预处理器命名空间。
That said, you really don't want to do this as the entire "added" functionality will fail spectacularly once you pass in something other than a string. The C pre-processor has no concept of data type, nor does it have the concept of memory de-referencing (useful if you wanted the length of a string stored in a variable). Basically, it would be a fun "see how far you could take it" exercise, but in the end, you would have a MYSTRING_LEN which would only take you a short distance to the goal.
也就是说,您真的不想这样做,因为一旦您传入字符串以外的其他内容,整个“添加”功能将严重失败。C 预处理器没有数据类型的概念,也没有内存取消引用的概念(如果您想要存储在变量中的字符串的长度,则很有用)。基本上,这将是一个有趣的“看看你能走多远”的练习,但最终,你会有一个 MYSTRING_LEN,它只会让你离目标很近。
In addition, the C pre-processor's lack of name spaces means that such a macro expansion system would not be containable. One would have to take care to keep the generated names from interfering with other useful macros. In the end, you would probably run out of memory in the pre-processor for any significant use, as the pre-processor isn't really built to hold a name for each character being converted into the "unit" token, and a name for each "unit" token being compressed into its final decimal notation.
此外,C 预处理器缺少名称空间意味着这样的宏扩展系统是不可包含的。必须注意防止生成的名称干扰其他有用的宏。最后,对于任何重要用途,您可能会在预处理器中耗尽内存,因为预处理器并没有真正构建为为每个被转换为“单元”标记的字符保存一个名称,以及一个名称对于每个“单位”标记被压缩为其最终十进制表示法。

