在C中初始化字符串的正确方法
我认为人们的准则是:在C中初始化字符串的正确方法,c,string,char,C,String,Char,我认为人们的准则是: char *str = NULL; 我也看到了这一点 char *str; 我想知道,初始化字符串的正确方法是什么?什么时候应该初始化一个带/和w/out NULL的字符串?这是一个关于c变量的一般问题,而不仅仅是char ptr 在声明点初始化变量被认为是最佳实践。即 char *str = NULL; 这是一件好事。这样你就不会有未知值的变量。例如,如果以后在代码中 if(str != NULL) doBar(str); 将会发生什么。str处于未知(几乎肯定
char *str = NULL;
我也看到了这一点
char *str;
我想知道,初始化字符串的正确方法是什么?什么时候应该初始化一个带/和w/out NULL的字符串?这是一个关于c变量的一般问题,而不仅仅是char ptr 在声明点初始化变量被认为是最佳实践。即
char *str = NULL;
这是一件好事。这样你就不会有未知值的变量。例如,如果以后在代码中
if(str != NULL)
doBar(str);
将会发生什么。str处于未知(几乎肯定不是NULL)状态
请注意,静态变量将被初始化为零/空。这个问题不清楚你是在问局部变量还是静态变量,你应该在使用它之前设置它。这是避免未定义行为必须遵循的唯一规则。无论您是在创建时初始化它,还是在使用它之前分配给它,都没有关系 就我个人而言,我更喜欢自己永远不要将变量设置为未知值,所以我通常会做第一个,除非它设置得非常接近(在几行之内) 事实上,对于C99,您不再需要在块的顶部声明局部变量,我通常会推迟创建它,直到需要时,在这一点上它也可以初始化 请注意,在某些情况下(例如,如果变量是静态存储持续时间,例如在文件级别声明,则在任何函数之外),变量都是默认值 局部变量没有这种保证。因此,如果您上面的第二个声明(
char*str;
)在一个函数中,它可能有垃圾,尝试使用它将调用上述可怕的未定义行为
C99标准的相关部分6.7.8/10
:
如果没有显式初始化具有自动存储持续时间的对象,则其值是不确定的。如果没有显式初始化具有静态存储持续时间的对象,则:
- 如果有指针类型,则初始化为空指针李>
- 如果它有算术类型,则初始化为(正或无符号)零李>
- 如果是聚合,则根据这些规则(递归地)初始化每个成员李>
- 如果是联合,则根据这些规则(递归地)初始化第一个命名成员
编译器使用默认值初始化全局变量,但必须初始化局部变量。应将单位化指针视为未定义指针,以避免使用未定义值产生错误,最好使用未定义值
char *str = NULL;
也因为
char *str;
这将只是一个未分配的指针,指向在使用时会导致问题的地方。如果您忘记分配它,您将需要分配它(或复制另一个指针)
这意味着您可以选择:
- 如果您知道在声明后不久将分配它,您可以避免将其设置为
(这是一种经验法则)NULL
- 在任何其他情况下,如果你想确定,就去做吧。如果您在没有初始化的情况下尝试使用它,则会出现唯一真正的问题
NULL
all指针;通过这种方式,很容易发现来自未初始化指针的问题,因为取消引用NULL
指针将导致崩溃(实际上,就标准而言,这是未定义的行为,但在我见过的每台机器上都是崩溃)
但是,您不应将指向字符串的NULL
指针与空字符串混淆:指向字符串的NULL
指针意味着该指针不指向任何内容,而空字符串是一个“实”零长度字符串(即它只包含NUL
字符)
您的第一个代码段是带有初始化的变量定义;第二个代码段是一个没有初始化的变量定义 初始化字符串的正确方法是在定义字符串时提供初始值设定项。将其初始化为NULL或其他值取决于您要对其执行的操作 还要注意你所说的“字符串”
C
没有这样的类型:在C
上下文中,通常“string”表示“字符的数组”。上面的代码段中有指向char的指针
假设您有一个程序需要argv[1]中的用户名,并将其复制到字符串“name”中。定义name
变量时,可以使其保持未初始化状态,或将其初始化为NULL(如果是指向char的指针),或使用默认名称初始化
int main(int argc, char **argv) {
char name_uninit[100];
char *name_ptr = NULL;
char name_default[100] = "anonymous";
if (argc > 1) {
strcpy(name_uninit, argv[1]); /* beware buffer overflow */
name_ptr = argv[1];
strcpy(name_default, argv[1]); /* beware buffer overflow */
}
/* ... */
/* name_uninit may be unusable (and untestable) if there were no command line parameters */
/* name_ptr may be NULL, but you can test for NULL */
/* name_default is a definite name */
}
这完全取决于你将如何使用它。在下文中,不初始化变量更有意义:
int count;
while ((count = function()) > 0)
{
}
你说的正确是指没有bug?嗯,这要视情况而定。但我可以推荐一些经验法则 首先,请注意C中的字符串与其他语言中的字符串不同 它们是指向字符块的指针。其结尾以0字节或空终止符终止。因此,字符串以null结尾 举个例子,如果你要做这样的事情:
char* str;
gets(str);
char *str = NULL;
if ( somethingorother() )
{
str = malloc ( 100 );
if ( NULL == str )
goto error;
}
或者以任何方式与str交互,那么它就是一个巨大的bug。原因是,正如我刚才所说,在C语言中,字符串不像其他语言那样是字符串。它们只是指针。char*str是指针的大小,并且始终为
因此,您需要做的是分配一些内存来保存字符串
/* this allocates 100 characters for a string
(including the null), remember to free it with free() */
char* str = (char*)malloc(100);
str[0] = 0;
/* so does this, automatically freed when it goes out of scope */
char str[100] = "";
然而,有时您只需要一个指针。e、 g 通常,这实际上取决于您希望如何使用字符串指针。 我的建议是,如果您仅使用
/* This declares the string (not intialized) */
char* str;
/* use the string from earlier and assign the allocated/copied
buffer to our variable */
str = strdup(other_string);
char* str = NULL;
strcmp(str, "Hello World");
static const char str[] = "str";
static char str[] = "str";
char *str = NULL;
if ( somethingorother() )
{
str = malloc ( 100 );
if ( NULL == str )
goto error;
}
error:
cleanup();
free ( str );