当定义一个 C 字符串,又名 char 数组时,使用双引号 "...",格式如下:
char * <varName> = "<someString>"
只有数组的元素是不可变的(它们的内容不能改变)。换句话说,<varName> 具有const char * 类型(指向只读内存的可变指针)。每次使用双引号 <varName> = "<otherString>" 调用赋值运算符时,它都会自动更改指针值。下面的例子应该对不同的可能性给出一个完整的概述:
#include <stdio.h>
int main()
{
char * var_1 = "Lorem";
printf("1. %s , %p\n", var_1, var_1); // --> 1. Lorem , 0x400640
var_1 = "ipsu";
printf("2. %s , %p\n", var_1, var_1); // --> 2. ipsu , 0x400652
// var_1[0] = 'x'; // --> Segmentation fault
var_1++;
printf("3. %s , %p\n", var_1, var_1); // --> 3. psu , 0x400653
char var_2[] = {'L', 'o', 'r', 'e', 'm', '\0'};
printf("4. %s , %p\n", var_2, var_2); // --> 4. Lorem , 0x7ffed0fc5381
var_2[0] = 'x';
printf("5. %s , %p\n", var_2, var_2); // --> 5. xorem , 0x7ffed0fc5381
// var_2++; //error: lvalue required as increment operand
char var_3[] = "Lorem";
printf("6. %s , %p\n", var_3, var_3); // --> 6. Lorem , 0x7ffe36a42d5c
// var_3 = "ipsu"; // --> error: assignment to expression with array type
var_3[0] = 'x';
printf("7. %s , %p\n", var_3, var_3); // --> 7. xorem , 0x7ffe36a42d5c
char * const var_4 = "Lorem";
// var_4 = "ipsu"; // --> error: assignment of read-only variable
// var_4[0] = 'x'; // --> Segmentation fault
char const * var_5 = "Lorem";
printf("8. %s , %p\n", var_5, var_5); // --> Lorem , 0x400720
var_5 = "ipsu";
printf("9. %s , %p\n", var_5, var_5); // --> ipsu , 0x400732
// var_5[0] = 'x'; // --> error: assignment of read-only location
const char * var_6 = "Lorem";
printf("10. %s , %p\n", var_6, var_6); // --> 10. Lorem , 0x400760
var_6 = "ipsu";
printf("11. %s , %p\n", var_6, var_6); // --> 11. ipsu , 0x400772
// var_6[0] = 'x'; // --> error: assignment of read-only location
const char const * var_7 = "Lorem"; // clang only --> warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier]
printf("12. %s , %p\n", var_7, var_7); // --> 12. Lorem , 0x400760
var_7 = "ipsu";
printf("13. %s , %p\n", var_7, var_7); // --> 13. ipsu , 0x400772
// var_7[0] = 'x'; // --> error: assignment of read-only location
char const const * var_8 = "Lorem"; // clang only --> warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier]
printf("14. %s , %p\n", var_8, var_8); // --> 14. Lorem , 0x400790
var_8 = "ipsu";
printf("15. %s , %p\n", var_8, var_8); // --> 15. ipsu , 0x4007a2
// var_8[0] = 'x'; // --> error: assignment of read-only location
char const * const var_9 = "Lorem";
// var_9 = "ipsu"; // --> error: assignment of read-only variable
// var_9[0] = 'x'; // --> error: assignment of read-only location
const char var_10[] = {'L', 'o', 'r', 'e', 'm', '\0'};
// var_10[0] = 'x'; // --> error: assignment of read-only location
// var_10++; // --> error: lvalue required as increment operand
char const var_11[] = {'L', 'o', 'r', 'e', 'm', '\0'};
// var_11[0] = 'x'; // --> error: assignment of read-only location
// var_11++; // --> error: lvalue required as increment operand
const char var_12[] = "Lorem";
// var_12[0] = 'x'; // --> error: assignment of read-only location
// var_12++; // --> error: lvalue required as increment operand
char const var_13[] = "Lorem";
// var_13[0] = 'x'; // --> error: assignment of read-only location
// var_13++; // --> error: lvalue required as increment operand
return 0;
}
此代码已在 GCC、Clang 和 Visual Studio 上进行了测试。
基本上有三种可能:
-
不可变指针,可变内容
char <varName>[] = {'L', 'o', 'r', 'e', 'm', '\0'};
char <varName>[] = "Lorem";
-
可变指针,不可变内容
char * <varName> = "Lorem";
char const * <varName> = "Lorem";
const char * <varName> = "Lorem";
const char const * <varName> = "Lorem";
char const const * <varName> = "Lorem";
-
不可变指针,不可变内容
char * const <varName> = "Lorem";
char const * const <varName> = "Lorem";
const char * const <varName> = "Lorem";
const char <varName>[] = {'L', 'o', 'r', 'e', 'm', '\0'};
char const <varName>[] = {'L', 'o', 'r', 'e', 'm', '\0'};
const char <varName>[] = "Lorem";
char const <varName>[] = "Lorem";
结论:
-
<typing> <varName>[] = <string> 总是返回一个不可变的指针,并且内容的可变性独立于 <array> 格式("Lorem" 或 {'L', 'o', 'r', 'e', 'm', '\0'})
-
<typing> * <varName> = "someString" 总是返回不可变的内容
-
<typing> * const <varName> = "someString" 总是返回不可变的内容和指针
-
char const <other>、char const <other>、const char const <other> 和 char const const <other> 始终创建不可变的内容。
我试图详细总结 C 的数组行为here。