执行特殊类型的字符串初始化的用C
你知道在C,我们可以初始化字符串变量是这样的:执行特殊类型的字符串初始化的用C
char text[1024] =
"Hello "
"World";
但如果我有一个返回单词“世界”的功能?
char text[1024] =
"Hello "
World();
在我看来,这是不可能在C. 请确认。
你想要什么是不可能的。
Assigment操作符的L值需要可修改,而数组不是。
从C11-标准:
6.5.16/2
赋值操作员有修改的左值作为它的左操作数。
char text[1024] = "Hello ""World";
从C11-标准:
的唯一例外此使用的文字作为R值时初始化期间是
6.7.9/14
字符类型的数组可以通过字符串文字或UTF-8字符串 升al,可选地包含在大括号中。字符串文字的连续字节(包括 ,如果有空间或数组大小未知,则终止空字符)将初始化数组的元素 。
答案已接受。 – 2014-11-24 10:01:44
如果World()
的东西,总是返回 “世界”,然后把它定义为一个宏:
#define World "World"
然后执行:
char text[1024] =
"Hello "
World; //Without parentheses
编辑
字符串连接在你期望的做法是由C预处理器完成的。你实际上是在寻找一个两个字符串的运行时连接,其中c以多种方式执行。最简单的一个是由strcat
函数来实现,而应该由函数明确执行初始化:
char text[1024];
void init_text() {
strcpy(text, "Hello ");
strcat(text, World()); //World() defined somewhere else
}
使用sprintf
备选:
void init_text() {
sprintf(text, "Hello %s", World());
}
然后在main
函数,调用init_text()
开头:
int main() {
init_text();
...
}
标准C中不可能用某些运行时特定的行为来初始化某些东西。因此,标准的便携式方法是通过调用main
开头的函数来初始化数据,如answered by Claudix。但是,如果您最近使用了一些GCC编译器(或Clang/LLVM),那么您可以在某些系统(包括Linux和其他POSIX系统)上使用某些constructor attribute on function。所以,你会宣称:
static void init_text(void) __attribute__((constructor));
,并定义init_text
像Claudix's answer没有不必调用它的main
:因为它具有constructor
属性,它会神奇地main
之前,如果出现叫,或在dlopen(3)在一个动态链接的插件或库中。
更便携的技巧可能是让函数返回该文本,以便在第一次调用期间对其进行初始化。因此,不要使用text
,您可以拨打get_my_text()
(可能通过将#define text get_my_text()
放在标题中,但出于可读性原因,我不建议这样做,因此请将text
的每次出现替换为get_my_text()
...),并将其定义为:
const char*get_my_text() {
static char textbuf[1024];
if (textbuf[0]) {
// already initialized, so return it
return textbuf;
};
snprintf(textbuf, sizeof(textbuf), "Hello %s", World());
return textbuf;
}
当心,这样的把戏是不可靠的多线程程序:两个线程可能在同一时间正好运行get_my_text
,和你有一个数据race。在多线程应用中,例如, pthread_once
您甚至可以在头文件中将get_my_text
定义为static inline
函数。
PS始终优先选择snprintf(3)至sprintf
以避免buffer overflows。还要注意,在标准C++任何static
或全球数据与一些给出constructor是main
之前进行初始化... GCC功能属性故名...
不,这是不可能的。您只能使用此方法连接字符串文字。 – 2014-11-22 11:59:46
@CoolGuy我需要它到初始化部分。问题已关闭。 – 2014-11-22 12:02:16
@alk嗯什么?你绝对可以... – 2014-11-22 12:02:36