在这份声明中
char *variable_name = "data";
声明了一个指针。该指针指向字符串文字“data”的第一个字符。编译器将字符串文字放置在内存的某个区域,并通过文字的第一个字符的地址分配指针。
您可以重新分配指针。例如
char *variable_name = "data";
char c = 'A';
variable_name = &c;
但是您不能更改字符串文字本身。尝试更改字符串文字会导致程序的未定义行为。
在这些声明中
char variable_name[] = "data";
char variable_name[5] = "data";
声明了两个数组元素,其元素由用于初始化字符串文字的字符初始化。例如这个声明
char variable_name[] = "data";
等价于下面的
char variable_name[] = { 'd', 'a', 't', 'a', '\0' };
该数组将有 5 个元素。所以这个声明完全等同于声明
char variable_name[5] = "data";
如果您指定数组的其他大小,则会有所不同。例如
char variable_name[7] = "data";
在这种情况下,数组将按以下方式初始化
char variable_name[7] = { 'd', 'a', 't', 'a', '\0', '\0', '\0' };
也就是说,数组中没有显式初始化器的所有元素都被零初始化。
请注意,在 C 中,您可以按以下方式使用字符串文字声明字符数组
char variable_name[4] = "data";
即字符串文字的终止零未放置在数组中。
在 C++ 中这样的声明是无效的。
当然,如果您愿意,您可以更改数组的元素(如果它没有定义为常量数组)。
请考虑到您可以将用作初始化程序的字符串文字括在大括号中。例如
char variable_name[5] = { "data" };
在 C99 中,您还可以使用所谓的目标初始值设定项。例如
char variable_name[] = { [4] = 'A', [5] = '\0' };
这是一个演示程序
#include <stdio.h>
#include <string.h>
int main(void)
{
char variable_name[] = { [4] = 'A', [5] = '\0' };
printf( "%zu\n", sizeof( variable_name ) );
printf( "%zu\n", strlen( variable_name ) );
return 0;
}
程序输出是
6
0
当您应用标准 C 函数时strlen
在标头中声明<string.h>
您会发现它返回 0,因为索引为 4 的元素之前的数组的第一个元素初始化为零。