这两个初始化之间有什么区别?
char a[] = "string literal";
char *p = "string literal";
答案 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。