我正在创建一个带有一些硬编码参数的C程序。 (这是设计,不用担心。)
//global constants
const char * const USERNAME = "username";
const int USERNAME_LEN = strlen(USERNAME);
当然,这个错误因为strlen显然不是常数。有没有办法做到这一点?或者我应该不关心并直接从strlen传递strncmp结果?
答案 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_len
,un_str
,...
请注意,指针本身不是const,因此它没有太多用处(你很可能不希望有一个指向每个这样的字符串的可修改指针)。您可以简单地省略其定义,就像我在*宏中所做的那样。
兼容性说明:
C const
的语义不同。实际上,C没有"常数"就像C ++一样。定义为const
的对象实际上是"不可修改的变量":它们只能在编译器时初始化,但它们像任何其他变量一样消耗空间(但是,它们可能位于不可更改的内存中)编译器将为任何其他变量生成读访问。例如,在C ++中,un_len
将在编译时被其值替换,并且在最终程序中可能不会占用任何内存 - 只要它的地址不被占用。
C中的实常数旁边的内容是enum
常量或`#define' ed名称。然而,后者在非常不同的水平上处理(由预处理器进行文本替换)。