【问题标题】:How is a char pointer an entire string?char 指针如何成为整个字符串?
【发布时间】:2023-03-12 01:38:01
【问题描述】:

假设我有以下字符串:

char *my_string = "Stack";

据我所知char * 保存着字符串"Stack" 的第一个字符的内存地址。在计算机内存中它可能表示为:

 ------------------------
| S | t | a | c | k | \0|
 ------------------------
  ^
  my_string

如果我调用:printf("%s\n", my_string);,则会打印整个字符串。编译器如何知道打印整个字符串?因为据我了解,它只有一个字符的地址。

【问题讨论】:

  • %s 说:打印所有字符,直到找到'\0'
  • 编译器不会打印字符串,printf 会。它通过一次打印每个字符来做到这一点,直到它到达 NUL。很难看出您对此有何难处。
  • 与您的地址识别整个房子的方式相同,而不仅仅是前门。

标签: c string pointers char char-pointer


【解决方案1】:

char* 确实只指向字符串的第一个字符,但是像printf("%s") 这样的函数只会开始读取并继续,直到找到一个 0 字节。像您的 "Stack" 示例这样的字符串文字默认情况下以零结尾,因此 printf 会知道打印您的字符串并在此之后停止。

【讨论】:

  • 确实@MrHug,很好的解释,只是想添加一些用低级语言解释这一点的东西。 6 个字节用于存储“堆栈”(每个字母 1 个字节加上末尾的 NULL 字节)。编译器会将它放在数据段中(参考汇编部分)。这个内存(位置和值)是在编译时设置的,不能在运行时修改(如果你尝试它会出现段错误)。
【解决方案2】:

编译器除了编译你的程序之外什么都不做。

然而,库函数printf 对您提出以下要求(而您恰好满足此要求):当给定格式说明符 %s 时,相应的参数必须是键入char *,并假定指向以零结尾的字符数组的第一个元素。然后该函数将打印出该数组的连续元素,直到它达到零字节。

【讨论】:

    【解决方案3】:

    因为它知道一个字符有多大,所以它可以计算第二个字符的地址并打印出来(基本上是在原始指针上加 1)。然后它可以再次执行相同的操作以获取第三个字符,依此类推,直到找到值为 '\0' 的字符并认为该字符串结束。

    【讨论】:

      【解决方案4】:

      char* 只是一个指向字符串开头的指针。许多 C 函数(printf、strcpy、strlen、...)依赖于传递给它们的指针恰好指向的字符串末尾的终止 '\0'。在将指向字符串的指针传递给此类函数时,请务必记住以 '\0' 终止字符串,以避免未定义的行为、分段错误、访问冲突等。

      【讨论】:

        【解决方案5】:

        编译器对传递的变量地址的大小或类型一无所知,因此当您传递 char 的第一个地址并使用字符串 %s 的说明符时,编译器只知道传递的地址并且它具有并将地址解释为字符串。因此通常 printf 打印所有字符并在读取 \0 空指针时结束执行。而字符串基本上只是以空指针\0 结尾的字符集合。

        【讨论】:

          【解决方案6】:

          char *my_string = "堆栈"; 这意味着以下几点:

          1. my_string 是指向 char 'S' 的指针
          2. 在增加指针时,它将增加 sizeof(char)。

          正如大多数人所引用的那样,添加一个观察结果: 如果您用其他任何内容覆盖普通字符串的“\0”地址,它将继续打印,直到遇到“\0”(一种诱导网络攻击的技术)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-18
            • 1970-01-01
            • 1970-01-01
            • 2015-05-19
            • 1970-01-01
            相关资源
            最近更新 更多