【问题标题】:Why can a string be assigned to a char* pointer, but not to a char[] array?为什么可以将字符串分配给 char* 指针,但不能分配给 char[] 数组?
【发布时间】:2011-10-11 19:34:42
【问题描述】:

有人能解释一下为什么这适用于指针吗:

char * str1;

str1 = "Hello1";

str1 = "new string";

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

// or this
char str3 [];
str3 = "hello";
str3 = "hello";

【问题讨论】:

  • This question 涵盖相同的领域,只是措辞不同。我不确定这是否足够重复以关闭,但那里的答案确实适用。
  • @Tim Post:所谓的重复问题及其答案与 IMO 无关,因为这个问题是编译时问题,另一个是运行时问题

标签: c string pointers initialization reusability


【解决方案1】:

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

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

str3的情况相同。您还没有在定义中定义数组的大小,因此它计算出它的大小为 0。如果不调整数组大小,您将无法分配任何新内容。

【讨论】:

  • 干杯,TryUrBest。我看过的大多数 C 书籍都非常重视字符串、指针和数组。在 str1 (指针)的情况下是这样做的吗?不要再担心“我做的是否 100% 正确”,只需像上面那样创建指向字符串的指针并使用它们吗?你说,第一个方法移动指针,是原点。然后数据被破坏,还是泄漏?
  • @tryurbest:我可以再补充一个问题吗?如果使用 char* str="some string",这个字符串是否被认为是一个固定大小的字符串。如果稍后,则处理此指针以添加更多字符串。这会产生内存访问冲突吗?谢谢!实际上,我已经对其进行了测试并看到了错误。但是我不确定那边的“固定大小字符串”或“常量字符串”部分
  • 旧字符串“Hello”会发生什么。这是否存在内存并导致内存泄漏?还是自动释放?
  • 根据 K. N. King 的说法,在您的第二个示例中 char str2 [] = "Hello",虽然 "Hello" 似乎是字符串文字,但它不是。相反,C 将其视为数组初始值设定项的缩写。
【解决方案2】:

数组和指针是不同的东西,这就是为什么。 您可以分配给指针,但不能分配给数组。使用字符串文字初始化 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`

字符串文字(例如“Hello”)的类型为char[N],其中N 是字符数(包括终止符'\0')。数组可以转换为指向其第一个元素的指针,但数组和指针不是一回事,不管一些坏书或老师怎么说。

【讨论】:

  • 不要忘记const 是这里的问题。
  • @DeadMG:C 字符串文字中的 AFAIK 不是 const char [N]。他们是char [N]。这就是我们(过去)在 C++ 中将字符串文字隐式转换为 char* 的原因。我错了吗?
  • @Armen:不,他们正式不是const char[N],但实际上,他们经常是。大多数编译器将字符串文字放在只读内存中。这意味着用户通常不应该尝试做*p = 'A';
  • @Rudy:无论编译器在哪里保存字符串文字,*p = 'A' 都有未定义的行为,这与 OP 的问题无关。但是字符串文字的类型(不幸的是)在 C 中只是 char[N]
  • 好的,谢谢。 Armen 提出了一个非常好的观点。我读过指针和数组基本上是一样的。
【解决方案3】:

简单地说,因为数组不是 C/C++ 中的一等对象。分配给数组的唯一方法是使用 str(n)cpy 或 memcpy。

虽然数组在传递给函数时会折叠成指针,但无法分配给数组,除非在编译时作为初始化。

【讨论】:

    【解决方案4】:

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

    char str2 [] = "hello";
    

    甚至:

    int arr[] = {1,2,4,4,5};
    

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

    【讨论】:

      【解决方案5】:

      带指针的案例 它之所以有效,是因为当您像 str1="Hello" 一样分配时,您实际上是在创建一个名为 hello 的字符串文字,将其分配到内存中的某个位置,并将文字的第一个字符的地址分配给指针,并且由于指针不是常量,您可以再次分配不同的地址。还有一点需要注意的是,创建的字符串字面量在只读内存中。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        • 2017-01-18
        • 2014-12-14
        • 2018-03-26
        • 2021-08-03
        • 1970-01-01
        相关资源
        最近更新 更多