在C语言中,可以在这样的声明中使用字符串字面值:

char s[] = "hello";

或者像这样:

char *s = "hello";

那么有什么不同呢?我想知道在编译和运行时,在存储持续时间方面实际发生了什么。


当前回答

char s[] = "Hello world";

这里,s是一个字符数组,如果我们愿意,它可以被覆盖。

char *s = "hello";

字符串字面值用于在内存中的某个地方创建这些字符块。我们可以通过改变它所指向的对象来重新赋值,但只要它指向一个字符串字面值,它所指向的字符块就不能被改变。

其他回答

char s[] = "hello";

声明s为一个char数组,其长度足以容纳初始化式(5 + 1个字符),并通过将给定字符串文字的成员复制到数组中来初始化数组。

char *s = "hello";

声明为指向一个或多个(在本例中是多个)字符的指针,并将其直接指向一个包含文字“hello”的固定(只读)位置。

此声明:

char s[] = "hello";

Creates one object - a char array of size 6, called s, initialised with the values 'h', 'e', 'l', 'l', 'o', '\0'. Where this array is allocated in memory, and how long it lives for, depends on where the declaration appears. If the declaration is within a function, it will live until the end of the block that it is declared in, and almost certainly be allocated on the stack; if it's outside a function, it will probably be stored within an "initialised data segment" that is loaded from the executable file into writeable memory when the program is run.

另一方面,这个声明:

char *s ="hello";

创建两个对象:

一个6个字符的只读数组,包含值'h', 'e', 'l', 'l', 'o', '\0',它没有名称,具有静态存储持续时间(意味着它存在于程序的整个生命周期中);而且 一个类型为指针到字符的变量,称为s,用该未命名只读数组中第一个字符的位置初始化。

未命名的只读数组通常位于程序的“文本”段中,这意味着它与代码本身一起从磁盘加载到只读内存中。s指针变量在内存中的位置取决于声明出现的位置(就像在第一个例子中一样)。

char *s1 = "Hello world"; // Points to fixed character string which is not allowed to modify
char s2[] = "Hello world"; // As good as fixed array of characters in string so allowed to modify

// s1[0] = 'J'; // Illegal
s2[0] = 'J'; // Legal

另外,考虑到对于只读目的,两者的使用是相同的,您可以通过使用[]或*(<var> + <index>)索引来访问一个char。 格式:

printf("%c", x[1]);     //Prints r

And:

printf("%c", *(x + 1)); //Prints r

很明显,如果你试图这么做

*(x + 1) = 'a';

你可能会得到一个分割错误,因为你试图访问只读内存。

在下列情况下:

char *x = "fred";

X是左值,它可以被赋值给。但在这种情况下:

char x[] = "fred";

X不是一个左值,它是一个右值——你不能给它赋值。