下面是一个常量字符数组。它实际上包含五个元素,因为 C 语言在由" 符号分隔的字符串末尾添加了一个'\0'。在C中,一个数组对象,比如MEAT,实际上是指向数组第一个元素的指针,所以MEAT实际上是一个内存地址而不是整个字符数组!
const char[] MEAT = "Meat";
下面是指向const char 的指针。 * 符号告诉您它是一个指针。 (无论是按指向的类型还是按变量的名称放置星号都没有关系。这可能会造成混淆,因此我通常将类型信息放在一起并拥有自己的名称,但我相信这一点这不是最常用的约定。)favFood 变量使用MEAT 数组中的第一个字符的地址进行初始化。 (记住MEAT是一个内存地址,所以这是设置一个内存地址等于另一个。)
const char* favFood = MEAT;
在未来的某个时候,您的动物可能会突然决定不再喜欢肉,而现在它实际上更喜欢饼干(我知道,猫比狗更容易改变主意,但这只是一个例子)。
const char BISCUITS[] = "Biscuits";
/* Some code is done here, until you find... */
favFood = BISCUITS;
现在,MEAT 和 BISCUITS 都是常量,这意味着您无法更改它们,但 favFood 本身不是常量,而是指向常量字符串(无论如何是字符串中的第一个字符),所以您可以改变它!
你也可以有非常量字符串:
char nameAndFaveFood[50];
sprintf(nameAndFaveFood, "%.26s likes %.9s best.", name, favFood);
... 但请确保您复制的字符(包括终止的 '\0' 空字符)不超过分配的空间,在本例中为 49 个字符和一个终止符。这就是为什么sprint 函数有精确说明符来限制子字符串的长度。
你可以拥有指向可变内存的常量指针。
char* const LIKES_FOOD = &nameAndFaveFood[27];
注意LIKES_FOOD 对象被初始化为指向nameAndFaveFood 数组的一部分。它总是指向那个地址。您可以使用不同的name 和favFood 参数调用上一个代码块中的例程,但LIKES_FOOD 将始终指向nameAndFaveFood 数组中的第28 个字符。