C字符串指针与数组[重复]

Posted

技术标签:

【中文标题】C字符串指针与数组[重复]【英文标题】:C strings pointer vs. arrays [duplicate] 【发布时间】:2011-03-13 13:06:06 【问题描述】:

可能重复:What is the difference between char s[] and char *s in C?

为什么:

char *ptr = "Hello!"

不同于:

char ptr[] = "Hello!"

具体来说,我不明白为什么可以使用 (*ptr)++ 来更改数组中 'H' 的值,但不能更改指针。

谢谢!

【问题讨论】:

【参考方案1】:

ptr 是指针而不是数组时,您可以(通常)使用表达式(*ptr)++ 来更改ptr 指向的值(即,如果ptr 被声明为char* ptr )。

但是,在您的第一个示例中:

char *ptr = "Hello!"

ptr是指向一个字串,字串是不允许被修改的(实际上可能是存放在不可写的内存区域,比如ROM或者被标记为只读的内存页)。

在你的第二个例子中,

char ptr[] = "Hello!";

数组被声明并且初始化实际上复制字符串字面量中的数据到分配的数组内存中。该数组内存是可修改的,因此 (*ptr)++ 有效。

注意:对于您的第二个声明,ptr 标识符本身是一个数组标识符,而不是指针,也不是“左值”,因此无法修改(即使在大多数情况下它很容易转换为指针) )。例如,表达式++ptr 将无效。我认为这是其他一些答案试图提出的观点。

【讨论】:

最后,有人回答了我的问题。如果我有一个注册帐户,我会给你一个upvote。谢谢好心的先生。 @John McGee:你发布了一个问题意味着你有一个“帐户”,你有足够的声望来投票,你总是可以将答案标记为“接受”。 我现在懒得尝试,但 (*ptr)++ 在第一种情况下真的会导致编译器错误吗?编译器需要分析 ptr 自初始化以来是否没有改变,不是吗? @Martin:它通常不会导致编译时错误(如果您的编译器很聪明并且可以检测到 ptr 指向文字,则可能会发出警告),但通常会导致在运行时错误中。但是,它可能似乎在某些平台上工作 - 但它是未定义的行为,应该被视为任何平台上的错误。 @Michael:谢谢。更不用说共享常量字符串(即重用)的情况了,我认为这更常见......【参考方案2】:

当指向一个字符串字面量时,你不应该声明字符是可修改的,一些编译器会警告你:

char *ptr = "Hello!"    /* WRONG, missing const! */

原因正如其他人所指出的那样,字符串文字可能存储在程序内存的不可变部分中。

对你来说正确的“注释”是确保你有一个指向常量字符的指针:

const char *ptr = "Hello!"

现在您可以直接看到无法修改存储在指针处的文本。

【讨论】:

【参考方案3】:

数组自动分配空间,它们不能被重新定位或调整大小,而指针被显式分配为指向分配的空间并且可以重新定位。

数组名称是只读的

【讨论】:

谢谢,但它没有回答我的问题。我在问为什么数组的 (*ptr)++ 会将“H”更改为“I”,但对于其他情况则不然。【参考方案4】:

如果您使用字符串文字"Hello!",文字本身会变成一个包含 7 个字符的数组,并存储在数据存储器的某个位置。该内存可能是只读的。

声明

char *ptr = "Hello!";

定义一个指向char 的指针并初始化它,方法是在其中存储文字开头的地址(前面提到的7 个字符的数组)。更改ptr指向的内存内容是非法的。

声明

char ptr[] = "Hello!";

定义一个char 数组(char ptr[7])并通过将字符从文字复制到数组来初始化它。数组可以修改。

【讨论】:

【参考方案5】:

在 C 中,字符串是字符数组。 指针是一个变量,它包含另一个变量的内存位置。 数组是一组有序的数据项。 当你放 (*ptr)++ 时,你会得到指针的分段错误。

也许您正在将 1 添加到整个字符串(使用指针),而不是添加 1 到变量的第一个字符(使用数组)。

【讨论】:

以上是关于C字符串指针与数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的java字符串数组空指针异常[重复]

《C语言程序设计》指针

《C语言程序设计》指针

深度长文教你彻底掌握C++/C指针:指针和数组与字符串

深度长文教你彻底掌握C++/C指针:指针和数组与字符串

c语言字符串数组&数组名与指针