为什么可以将字符串分配给char*指针,而不是char []数组?

nic*_*ick 61 c string pointers initialization reusability

有人可以解释为什么这适用于指针:

char * str1;

str1 = "Hello1";

str1 = "new string";

// but not this
char str2 [] = "hello";
str2 = "four";

// or this
char str3 [];
str3 = "hello";
str3 = "hello";
Run Code Online (Sandbox Code Playgroud)

try*_*est 77

为什么它适用于指针:
当你char * str1在C中说,你在内存中分配一个指针.在编写时str1 = "Hello";,您在内存中创建一个字符串文字并使指针指向它.当您创建另一个字符串文字"new string"并将其分配给时str1,您所做的只是改变指针指向的位置.

为什么它不适用于数组:
当你说char str2 [] = "Hello",你正在创建一个字符串文字并在定义期间将它放在数组中.可以不给出大小,因为数组会计算并附加一个大小'\0'.如果不调整大小,则无法将任何内容重新分配给该数组.这就是为什么str2 = "four"不起作用的原因.

在这种情况下str3,情况是相同的.您尚未在定义中定义数组的大小,因此它将其大小计算为0.如果不调整数组大小,则无法分配任何新内容.

  • 旧字符串“Hello”会发生什么。这是否存在内存并导致内存泄漏?或者说是自动释放的? (2认同)

Arm*_*yan 19

数组和指针是不同的东西,这就是原因.您可以指定指针,但不能指定给数组.使用字符串文字初始化char数组时会发生特殊异常.

char a[] = "Hello"; //initialize a char array with string literal. Special case, OK
char* p = "Hello"; //initializa a pointer with an array(which gets converted to pointer)
p = "My";   //assign pointer to point to another value. OK
a = "My";   //error, arrays cannot be assigned to. Use `strcpy`
Run Code Online (Sandbox Code Playgroud)

字符串(例如"Hello")具有式char[N]其中N是字符(包括终止的数目'\0').一个数组可以转换为指向它的第一个元素的指针,但是数组和指针不是一回事,无论一些坏书或老师可能会说.

  • @DeadMG:C字符串文字中的AFAIK不是`const char [N]`.他们是`char [N]`.这就是为什么我们(习惯)在C++中隐式转换为字符串文字的`char*`.我错了吗? (4认同)
  • @Rudy:无论编译器保持字符串文字的位置,执行`*p ='A'都有不确定的行为,IMO与OP的问题无关.但是,不幸的是,字符串文字的类型只是C中的`char [N]`. (3认同)
  • 不要忘记`const`作为一个问题. (2认同)

Jul*_*ian 7

简而言之,因为数组不是C/C++中的第一类对象.分配给数组的唯一方法是使用str(n)cpy或memcpy.

虽然数组在传递给函数时会折叠成指针,但除了在编译时初始化之外,不能分配给数组.


小智 6

这只是因为,当你编写这段代码时:

char str2 [] = "hello";
Run Code Online (Sandbox Code Playgroud)

甚至:

int arr[] = {1,2,4,4,5};
Run Code Online (Sandbox Code Playgroud)

它创建str2orarr作为常量指针。这就是为什么您不能为这些指针重新分配任何其他值,而在稍后的情况下您将创建一个普通指针并且可以为其分配任何值。


jok*_*007 5

指针的情况 它之所以有效,是因为当您进行类似分配时str1="Hello",您实际上是在创建一个名为 hello 的字符串文字,将其分配在内存中的某个位置,并将文字的第一个字符的地址分配给指针,并且由于指针不是常量您可以使用不同的地址再次分配它。需要注意的更重要的一点是,创建的字符串文字位于只读存储器中。

字符数组的情况 您可以在初始化时为其分配一个字符串文字,因为语言支持这一点。并且不要将赋值与初始化混淆。在赋值时,由于它是一个字符数组,因此您必须逐个字符地更改值,您试图将字符串文字的首地址寻址到数组的第一个字符(数组的名称返回数组的第一个元素的地址)这显然是不对的,因为第一个元素不是指针,它不能存储地址。