什么是做strlen(const)的最佳方法?

时间:2015-06-11 19:07:05

标签: c string const

我正在创建一个带有一些硬编码参数的C程序。 (这是设计,不用担心。)

//global constants
const char * const USERNAME = "username";
const int USERNAME_LEN = strlen(USERNAME);

当然,这个错误因为strlen显然不是常数。有没有办法做到这一点?或者我应该不关心并直接从strlen传递strncmp结果?

2 个答案:

答案 0 :(得分:4)

如果你真的需要USERNAME作为const char * const对象(对吗?),那么一种方法就是

#define USERNAME_LITERAL "username"

const char * const USERNAME = USERNAME_LITERAL;
const int USERNAME_LEN = sizeof USERNAME_LITERAL - 1;

它可以像人们希望的那样优雅,但确实将代码保持在"自我维护"形状。即你只需要编辑文字,其余的将自动更新。

您也可以

const char USERNAME[] = "username";
const int USERNAME_LEN = sizeof USERNAME - 1;

甚至

#define USERNAME "username"
const int USERNAME_LEN = sizeof USERNAME - 1;

但在这种情况下,USERNAME不再是const char * const,这就是为什么我会问你是否真的需要它。

答案 1 :(得分:0)

如果必须初始化文字的指针,可以使用以下内容:

const char un_str[] = "...", *un_ptr = un_str;
const size_t un_len = sizeof(un_str);

注意:sizeof()返回size_t,它是无符号的。

您可以将其打包到宏中:

#define STR_LEN_PAIR(name, value) const char name##_str[] = value; \
        const size_t name##_len = sizeof(name##_str)

这使用参数连接。请注意在最后一行之后缺少;,它允许在调用时使用标准语法。小心只能按预期使用它:

// at file level
STR_LEN_PAIR(un,"...");

可以访问字段un_lenun_str,...

请注意,指针本身不是const,因此它没有太多用处(你很可能不希望有一个指向每个这样的字符串的可修改指针)。您可以简单地省略其定义,就像我在*宏中所做的那样。

兼容性说明:

C const的语义不同。实际上,C没有"常数"就像C ++一样。定义为const的对象实际上是"不可修改的变量":它们只能在编译器时初始化,但它们像任何其他变量一样消耗空间(但是,它们可能位于不可更改的内存中)编译器将为任何其他变量生成读访问。例如,在C ++中,un_len将在编译时被其值替换,并且在最终程序中可​​能不会占用任何内存 - 只要它的地址不被占用。

C中的实常数旁边的内容是enum常量或`#define' ed名称。然而,后者在非常不同的水平上处理(由预处理器进行文本替换)。