C strings pointer vs. arrays
Possible Duplicate:
What is the difference between char s[] and char *s in C?
为什么是:
不同于:
具体来说,我不明白为什么可以使用(*ptr)++来更改数组中"h"的值,但不能更改指针。
谢谢!
当ptr是指针而不是数组时,可以(通常)使用表达式(*ptr)++更改ptr指向的值(即,如果ptr声明为char* ptr)。
但是,在第一个示例中:
ptr指向的是一个文本字符串,不允许修改文本字符串(它们实际上可能存储在不可写的内存区域中,如只读存储器或标记为只读的内存页)。
在第二个例子中,
数组被声明,初始化实际上将字符串文字中的数据复制到分配的数组内存中。这个数组内存是可修改的,所以(*ptr)++工作。
注意:对于第二个声明,ptr标识符本身是数组标识符,不是指针,也不是"lvalue",因此它不能被修改(即使在大多数情况下它很容易转换为指针)。例如,表达式++ptr无效。我认为这正是其他一些答案试图提出的观点。
- 最后,有人回答了我的问题。如果我有一个注册帐户,我会给你一个赞成票。谢谢你的好意,先生。
- @约翰·麦基:你发布一个问题意味着你有一个"账户",你有足够的声望去投赞成票,你总是可以把答案标记为"接受"。
- 我现在懒得去尝试,但是在第一种情况下(*ptr)++真的会导致编译器错误吗?编译器需要分析自初始化之后ptr是否没有变化,是吗?
- @马丁:它通常不会导致编译时错误(如果您的编译器很聪明并且能够检测到ptr指向一个文本,则可能是一个警告),但它通常会导致运行时错误。然而,它可能在某些平台上工作——但它是未定义的行为,应该被视为任何平台上的bug。
- @迈克尔:谢谢。更不用说共享常量字符串(即重用)的情况了,我认为这更常见…
- @詹姆斯德林:在我注册之前不会让我投反对票。我刚尝试过。
- 为了学究,ptr在某些情况下是左值,例如当它是sizeof或&的操作数时:stackoverflow.com/questions/39021998/…
阅读C语言常见问题解答。特别是数组和指针部分。
- 我还刚刚阅读了常见问题解答,但我仍然看不到问题的答案。
- @约翰·麦基:也许C-faq.com/aryptr/aryptr 2.html(它可以回答你的确切问题)和C-faq.com/aryptr/aryptreiv.html会对你有所帮助?或者你要寻找的答案是:因为这就是语言的定义方式;数组不是指针。
- @约翰麦基-你不会让人们更容易帮助你的态度。
- 实际上,它没有回答我确切的问题,詹姆斯。我很清楚数组和指针之间的区别。我不知道的是不允许修改字符串文本。这就是我要找的。
- @约翰·麦基:关于字符串文字的问题也可以在常见问题解答中回答。我建议你阅读整个常见问题解答con c-lang。它值得一读!从上到下。说真的。很好。祝你好运。
- 啊,是的-这个精确的问题是在问题1.32中解决的,而不是在"数组和指针"部分:c-faq.com/decl/strlitinit.html
- @约翰·麦基-@pablo给你展示了一个很好的资源来回答这个问题,而且很可能还有更多的问题你将来会遇到。如果你愿意,教一个人钓鱼。一个更恰当的回答可能是"我在那里找不到它,我遗漏了一个具体的例子吗?"
当指向字符串文字时,不应将字符声明为可修改的,并且某些编译器将为此警告您:
1
| char *ptr ="Hello!" /* WRONG, missing const! */ |
原因是,正如其他人所指出的,字符串文本可能存储在程序内存的不可变部分中。
正确的"注释"是确保您有一个指向常量char的指针:
1
| const char *ptr ="Hello!" |
现在您可以直接看到,您不能修改指针处存储的文本。
在C字符串中是字符数组。指针是包含另一个变量的内存位置的变量。数组是一组有序的数据项。当您输入(*ptr)++时,指针会出现分段错误。
也许您是在整个字符串中添加1(使用指针),而不是在变量的第一个字符中添加1(使用数组)。
如果使用字符串文字"Hello!",则文字本身将成为一个7个字符的数组,并存储在数据内存的某个位置。那个内存可能是只读的。
声明
定义指向char的指针,并通过在其中存储文本开头的地址(前面提到的由7个字符组成的数组)对其进行初始化。更改ptr指向的内存内容是非法的。
声明
定义char数组(char ptr[7]并通过将字符从文本复制到数组来初始化它。可以修改数组。
数组自动分配空间,它们不能被重新定位或调整大小,而指针被显式地分配给分配的空间,并且可以被重新定位。
数组名是只读的!
- 谢谢,但它没有回答我的问题。我在问为什么数组的(*ptr)++会将"h"更改为"i",但另一种情况下不会。