如何解决指针定义的字符串或数组之间的区别
我在这里阅读有关K&R书中的指针的信息:
https://hikage.freeshell.org/books/theCprogrammingLanguage.pdf
这些定义之间有重要区别:
char amessage[] = "Now is the time"; /* an array */
char *pmessage = "Now is the time"; /* a pointer */
消息是一个数组,大小足以容纳字符序列和用于初始化它的“ \ 0”。单个字符
数组中的可能会更改,但消息将始终引用相同的存储。另一方面,pmessage是一个 指针,已初始化为指向字符串常量;指针随后可能会被修改为指向 的其他位置,但结果是 如果您尝试修改字符串内容,则为undefined。
解决方法
我不明白为什么我们不能修改字符串内容!
因为C标准是这样说的:“如果程序试图修改这样的数组[由字符串文字定义的数组],则行为是不确定的”(C 2018 6.4.5 7)。字符串文字是源代码中用引号引起的一系列字符,例如"Hello,world.\n"
。 (字符串文字还可以在编码前缀u8
,u
,U
或L
之前,如L"abc"
一样。)字符串文字定义了一个包含字符串字符和结尾的空字符的数组。
尝试修改字符串文字数组的原因是,字符串文字已被并且广泛用于常量字符串-有时会打印错误消息,为printf
操作设置字符串格式,事物名称的编码等。随着C的发展和标准的编写,将字符串文字视为只读是有意义的,并允许编译器将其放入只读存储中。另外,某些编译器将对出现在不同位置的相同字符串文字使用相同的存储,而对于某些字符串文字(另一个字符串文字的结尾子字符串),则将使用相同的存储。由于共享存储,修改一个字符串也会修改另一个字符串。因此,允许程序修改字符串文字可能会导致一些问题。
因此,如果您仅指向字符串文字,则表示不应修改。如果您想要自己的副本可以修改,只需使用char amessage[] = "now is the time";
显示的数组定义它即可。这样的定义定义了一个具有自己的存储空间的数组amessage
。该数组使用字符串文字的内容初始化,但与之分离。
-
char amessage[] = "now is the time"; /* an array */
amessage
是可修改的字符数组。
-
char *pmessage = "now is the time"; /* a pointer */
pmessage
是指向字符串文字的指针。尝试修改字符串文字是未定义的行为。
当您使用字符串文字初始化指针时,编译器会创建一个只读数组(如果您有多个使用相同文字字符串(按字符一个字符)的初始化程序,则编译器可以自由地将指针合并为一个:
char *a = "abcdef",*b = "abcdef";
很可能两个指针都初始化为内存中的相同地址。这就是不允许您修改字符串的原因,以及行为无法预测的原因(您不知道编译器是否已合并两个字符串) 在下一种情况下,事情变得更进一步,因为允许编译器执行以下操作:
char *a = "foo bar",*b = "bar";
允许编译器初始化a
以指向带有字符{'f','o',' ','b','a','r','\0'}
的char数组,并还初始化指向该数组第五个位置的指针b
,作为其中之一。字符串文字是另一个的后缀。
这允许编译器在最终的可执行文件中节省大量资金,因此,字符串文本在可执行文件中被分配了一个只读段(它们被放置在.text
段或类似的段中)
另一方面,初始化数组没有问题,因为您正在定义将存储字符的数组变量,而不是由编译器执行此操作。初始化如下:
char a[] = "Hello";
会将事物安排为具有char型数组的全局变量,并带有六个字符的空间。但是您也可以在方括号之间指定数组大小,如
char a[32] = "Hello";
,然后数组将包含32个字符(从0到31),并且前五个将被初始化为字符文字'H'
,'e'
,'l'
,{{1} }和'l'
,后跟27个空字符'o'
。
您还可以说:
'\0'
但是在这种情况下,您将获得一个初始化为char a[4] = "Hello";
的数组(字符串字面量只使用前四个字符,并且编译器会警告您,提示危险弯曲)
最后,请始终认为赋值和初始化是不同的东西,尽管它们使用相同的符号{'H','e','l','l'}
来表示它,但它们不是同一件事。您将永远不会被允许写下这样的句子:
=
因为表达式 char a[26];
a = "foo bar";
表示"foo bar"
指向静态数组(不可修改),并且无法分配数组。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。