【问题标题】:How and why exactly does char* s2 change after the last strcpy() call?char* s2 在最后一次 strcpy() 调用之后如何以及为什么会发生变化?
【发布时间】:2019-10-24 08:21:40
【问题描述】:

这是我几天后在学校要参加的考试中可能会出现的问题之一。在最后一次 strcpy() 调用之后,我无法理解 char* s2 如何从“消息服务”更改为 “ice”。我认为这是指针的某种结果,但这就是我所知道的。

char s1[] = "Short Message Service";
char *s2, *s3;

s2 = strchr(s1, 'M');

s3 = strrchr(s2, 'S');

strncpy(s1 + 1, s2, 1);

strcpy(s1 + 2, s3);  

我尝试调试程序并观察变量和指针的变化,但我仍然不明白最后一次调用如何影响 char *s2。

我希望 s2 的值是“消息服务”,但实际输出结果却是“冰”。不过,我确实了解 s1 和 s3 如何以及为什么会发生变化。

【问题讨论】:

  • s2 指向 s1 的子串。因此,在更改 s1 的内存时,您也可以更改 s2。这就是发生的事情。
  • strchrstrrchr 各自返回一个指向原始字符串参数内部某处的指针。如果您随后更改了该字符串的内容,那么这些指针指向的任何内容也会受到影响,因为它们是同一字符串的一部分。您应该仔细阅读字符串函数的手册页。
  • @xing 谢谢你的建议,但这是一道C理论题,我需要在调用strcpy和strchr命令后写下s1、s2和s3的结果。
  • 谢谢你们的回答,伙计们,但我想知道有人能解释一下调用函数时到底发生了什么吗?我知道这是因为指针,并且指向的子字符串正在发生变化,但我想知道为什么它最终会变成“冰”。

标签: c string pointers char strcpy


【解决方案1】:

如果我们显示数组,并添加相应的指针,它将看起来像这样:

+-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+-----+-----+------+-----+-----+-----+--- --+-----+-----+-----+------+------+ | 'S' | 'h' | 'o' | 'r' | '不' | ' ' | 'M' | 'e' | 's' | 's' | '一个' | 'g' | 'e' | ' ' | 'S' | 'e' | 'r' | 'v' | '我' | 'c' | 'e' | '\0' | +-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+-----+-----+------+-----+-----+-----+--- --+-----+-----+-----+------+------+ ^ ^ ^ | | | s1 s2 s3

当你修改数组的内容时,指针s2s3本身并没有改变,它们仍然指向数组中的相同位置。

之后

strncpy(s1 + 1, s2, 1);

数组(带有指针)看起来像

+-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+-----+-----+------+-----+-----+-----+--- --+-----+-----+-----+------+------+ | 'S' | 'M' | 'o' | 'r' | '不' | ' ' | 'M' | 'e' | 's' | 's' | '一个' | 'g' | 'e' | ' ' | 'S' | 'e' | 'r' | 'v' | '我' | 'c' | 'e' | '\0' | +-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+-----+-----+------+-----+-----+-----+--- --+-----+-----+-----+------+------+ ^ ^ ^ | | | s1 s2 s3

s2 指向的单个字符被复制到s1[1]

然后用

strcpy(s1 + 2, s3);  

数组看起来像

+-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+------+-----+-----+-----+-----+-----+-- ---+-----+-----+-----+------+------+ | 'S' | 'M' | 'S' | 'e' | 'r' | 'v' | '我' | 'c' | 'e' | '\0' | '一个' | 'g' | 'e' | ' ' | 'S' | 'e' | 'r' | 'v' | '我' | 'c' | 'e' | '\0' | +-----+-----+-----+------+-----+-----+-----+-----+- -----+-----+------+-----+-----+-----+-----+-----+-- ---+-----+-----+-----+------+------+ ^ ^ ^ | | | s1 s2 s3

子字符串"Service" 被复制到从s1[2] 开始的部分字符串上。

指针s2 仍然指向同一个位置,但如果我们将s2 视为指向字符串第一个字符的指针,那么它的内容已经改变,因为你已经覆盖了那个内容。

【讨论】:

  • 我已经为这个问题强调了 2 个小时。谢谢你这个美丽而清晰的答案,现在一切都清楚了。
  • @AndrijaTošić 下次遇到数组和指针问题时,只需拿出笔和纸,自己画出来。它真的可以帮助创造奇迹。 :)
猜你喜欢
  • 2019-12-20
  • 2020-07-14
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多