char s []和char * s有什么区别?

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

char s[] = "hello";

或者像这样:

char *s = "hello";

那么区别是什么呢? 我想知道在编译和运行时在存储时间方面实际发生了什么。


这里的区别在于

char *s = "Hello world";

将放置"Hello world"在内存的只读部分,使s的指针,使得在这个内存非法任何写入操作。

在做:

char s[] = "Hello world";

将文字字符串放入只读存储器,并将该字符串复制到堆栈上新分配的内存中。 这样做

s[0] = 'J';

法律。


首先,在函数参数中,它们完全等价:

void foo(char *x);
void foo(char x[]); // exactly the same in all respects

在其他上下文中, char *分配一个指针,而char []分配一个数组。 在前一种情况下,绳子在哪里?你问? 编译器秘密地分配一个静态匿名数组来保存字符串文字。 所以:

char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;

请注意,您不得尝试通过此指针修改此匿名数组的内容; 效果未定义(通常意味着崩溃):

x[1] = 'O'; // BAD. DON'T DO THIS.

使用数组语法直接将其分配到新的内存中。 因此修改是安全的:

char x[] = "Foo";
x[1] = 'O'; // No problem.

然而,数组只能在其持续范围内生存,所以如果在函数中这样做,不要返回或泄漏指向此数组的指针 - 使用strdup()或类似方法创建副本。 如果数组在全局范围内分配,当然没问题。


此声明:

char s[] = "hello";

创建一个对象 - 一个大小为6的char数组,名为s ,用值'h', 'e', 'l', 'l', 'o', ''初始化。 这个数组在内存中分配的位置,以及它的存活时间取决于声明的出现位置。 如果声明在函数中,它将一直存在直到它声明的块结束,并且几乎肯定会被分配到堆栈中; 如果它不在函数中,它可能会存储在一个“初始化数据段”中,该段在程序运行时从可执行文件加载到可写入的内存中。

另一方面,这个声明:

char *s ="hello";

创建两个对象:

  • 一个只读的6阵列char小号包含值'h', 'e', 'l', 'l', 'o', '' ,它没有名称并具有静态存储的持续时间(这意味着它在整个项目的整个生命中都活着); 和
  • 一个类型为pointer-to-char的变量,称为s ,它用该未命名的只读数组中的第一个字符的位置初始化。
  • 未命名的只读数组通常位于程序的“文本”段中,这意味着它会连同代码一起从磁盘加载到只读存储器中。 s指针变量在内存中的位置取决于声明出现的位置(就像第一个示例中一样)。

    链接地址: http://www.djcxy.com/p/21193.html

    上一篇: What is the difference between char s[] and char *s?

    下一篇: Multiline String Literal in C#