C“string”init - 哪个更好?

时间:2011-10-25 17:28:31

标签: c string

这两个初始化之间有什么区别?

char a[] = "string literal";

char *p  = "string literal";

5 个答案:

答案 0 :(得分:17)

尽管两者看起来相似并且经常互换使用,但它们的确意味着不同的东西。第一行:

char a[] = "string literal"; 

...创建一个足以容纳字符串文字的数组,包括其NUL终止符。它使用您指定的字符串文字初始化此数组。此版本的一个好处是可以在以后修改阵列。此外,即使在编译时也可以知道数组的大小,因此您可以使用sizeof运算符来确定其大小。例如:

printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size 
                                    // including the NUL terminator

第二行:

char *p  = "string literal"; 

...只需设置指向字符串文字的指针即可。这比第一个版本更快,但是你有一个缺点,即不应该更改文字,因为它可能位于标记为只读的页面中。你还有一个缺点,即要知道字符串的长度,你需要使用strlen()函数,因为sizeof运算符只会给你指针变量的大小。例如:

printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on
                                    // whether this is a 32-bit or 64-bit build
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not
                                    // including the NUL terminator

至于哪个更好,这取决于你将对这些变量做些什么。如果您不需要对字符串进行任何更改,请使用更高版本,但执行char *更改为const char *,这样您就不会意外地尝试制作更改指向的字符。如果您打算更改数据,请使用以前基于阵列的版本,该版本允许您在初始化后对阵列进行更改。

答案 1 :(得分:3)

每个都强制编译器在静态内存中创建一个字符串文字(至少在概念上)是只读的。

然后第一个使用它来初始化数组的内容。字符串文字只用于选择其大小,并初始化它。

第二个创建一个直接指向原始字符串文字的指针。

他们之间没有真正的好或坏。他们只是不同。例如,数组通常使用更多内存(有一个字符串文字,然后是数组中字符串文字的完整副本)。但是,由于它是一个正常的数组,您可以根据需要进行修改。

直接指向字符串文字的指针通常会节省一些内存。它还意味着您可以为指针指定不同的值,以便它(例如)在不同的时间指向不同的字符串文字。但是,,允许修改它指向的数据 - 这样做会产生未定义的行为。

答案 2 :(得分:0)

取决于您的需求。

char a[] = "string literal";

创建具有自动存储持续时间的可变字符数组。这是合法的:

a[0] = 'c';

另一方面......

char *p  = "string literal";

创建一个只读内存的指针。声明应该是

const char *p  = "string literal";

您无法合法修改p指向的内容。

答案 3 :(得分:0)

第一个声明一个数组并填充它(通过逐个设置元素,直到包含结束空字节)。可以修改数组。

第二个声明一个指针,并通过将其设置为常量文字来填充它。您可以修改指针(例如,使其指向其他位置),但不能修改由其指向的常量字符串(在大多数系统上将放在只读段中)。

答案 4 :(得分:0)

一个为您提供一个填充了您指定数据的数组,第二个为您提供指向某个内存(通常为只读)的指针,其中包含您指定的数据。

为了使“你得到的”更加清晰,请尝试以下方法:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  char a[] = "string literal";
  char *b = "string literal";

  printf("a is %lu bytes, b is %lu\n", (unsigned long) sizeof a,
                                       (unsigned long) sizeof b);

  return EXIT_SUCCESS;
}

以下是包含上述代码的live demo