【问题标题】:In C (also C++), how does the printf("%s",&st[0]) function knows how much it has to print, as we have passed only address of byte of string [duplicate]在 C(也是 C++)中,printf("%s",&st[0]) 函数如何知道它必须打印多少,因为我们只传递了字符串字节的地址 [重复]
【发布时间】:2020-11-15 21:37:39
【问题描述】:

对于 C char st[] = "heloThere"; printf("%s",&st[0]); 中的代码,printf 怎么知道它只需要打印到 heloThere,而不是除此之外,因为我们只将第一个字节的地址传递给函数。还突出显示 C++。这也有效printf("%s",st)。因为我们没有像上面那样传递任何地址。 printf 的工作方式有何不同?是单独定义的吗? (然后会重载,C 不支持)

【问题讨论】:

  • C "strings" 是 char 数组,末尾有一个额外的 '\0' 终止符。它不打印,但用于标记字符串的结尾。
  • 你知道array to pointer decay吗?
  • 在C中,大部分字符串以'\0'结尾,所以printf会循环遍历字节数组找到'\0'得到字符串长度。
  • 因为 C 中的字符串实际上被称为 null-终止字节字符串

标签: c++ arrays c printf c-strings


【解决方案1】:

C 或 C++ 编译器在字符串或字符数组的末尾添加 '\0' 以标记结束。

char* s = (char*)"Hello!";

这一行实际上看起来像内存

所以你可能会注意到添加的 '\0',这就是 printf 的作用,它循环并计算 "" 之间的字符并将那部分内存发送到输出流,printf 做的另一件事是,它返回最后的字符计数器的值,但是 c++ 中的 cout 更复杂,因为它是一个对象而不是函数。

以下代码的执行表明 printf 返回了计数器值。

cout << printf("%d", printf("%s",s));

执行:你好!61

上面的执行是我们首先打印 'hello!'这是由右侧的 printf 完成的,然后我们通过左侧的第二个 printf 打印它的返回值,我们得到 6(“hello!”中的字符数)然后我们再次使用 cout 打印第二个的返回值printf 这是一个字符,它是第一个字符数组大小的“6”。

【讨论】:

    【解决方案2】:

    printf(“%s”,&amp;st[0]) 函数如何知道它必须打印多少,因为我们只传递了字符串字节的地址?

    它知道它是因为字符串终止的空字符'\0',每个字符串都需要在其末尾提供。

    例如,字符串文字"hello""hello\0" 的形式存储在内存中,并且该字符串由6 字符组成,而不是5

    请注意,strlen 不计算终止 \0,因此它返回 5,而不是 6

    char 的每个数组都必须至少为该终止字符保留一个元素。否则,如果您通过字符串操作函数访问该数组,则会调用未定义的行为。

    如果你声明

    char st[] = "heloThere";
    

    编译器会自动计算所需的元素数量,在本例中为 10,而不是 9

    【讨论】:

      【解决方案3】:

      在 C 和 C++ 中,字符串是由零字符 '\0' 终止的字符序列。

      这个数组声明

      char st[] = "heloThere";
      

      等价于

      char st[] = { 'h', 'e', 'l', 'o', 'T', 'h', 'e', 'r', 'e', '\0' };
      

      所以printf的这个电话

      printf("%s",&st[0]);
      

      输出表达式&amp;st[0]指向的字符,直到遇到零字符。

      这个电话

      printf("%s",st)
      

      与前面的调用等效,因为在表达式中使用的数组指示符具有罕见的异常,它们被转换为指向它们的第一个元素的指针。

      【讨论】:

        猜你喜欢
        • 2011-12-08
        • 2021-04-05
        • 1970-01-01
        • 2018-11-07
        • 1970-01-01
        • 2013-10-02
        • 2021-03-15
        • 2018-01-23
        • 1970-01-01
        相关资源
        最近更新 更多