微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

指针定义的字符串或数组之间的区别

如何解决指针定义的字符串或数组之间的区别

在这里阅读有关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"。 (字符串文字还可以在编码前缀u8uUL之前,如L"abc"一样。)字符串文字定义了一个包含字符串字符和结尾的空字符的数组。

尝试修改字符串文字数组的原因是,字符串文字已被并且广泛用于常量字符串-有时会打印错误消息,为printf操作设置字符串格式,事物名称的编码等。随着C的发展和标准的编写,将字符串文字视为只读是有意义的,并允许编译器将其放入只读存储中。另外,某些编译器将对出现在不同位置的相同字符串文字使用相同的存储,而对于某些字符串文字(另一个字符串文字的结尾子字符串),则将使用相同的存储。由于共享存储,修改一个字符串也会修改另一个字符串。因此,允许程序修改字符串文字可能会导致一些问题。

因此,如果您仅指向字符串文字,则表示不应修改。如果您想要自己的副本可以修改,只需使用char amessage[] = "now is the time";显示的数组定义它即可。这样的定义定义了一个具有自己的存储空间的数组amessage。该数组使用字符串文字的内容初始化,但与之分离。

,
  1. char amessage[] = "now is the time"; /* an array */

amessage是可修改的字符数组。

  1. 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 举报,一经查实,本站将立刻删除。