【问题标题】:Why does s[s[3]] = '1' when char *s = "123"?为什么当 char *s = "123" 时 s[s[3]] = '1'?
【发布时间】:2021-07-10 16:58:31
【问题描述】:
char* s = "123";
std::cout << s[s[3]] << std::endl; // prints 1
std::cout << s[3] << std::endl; // prints nothing?

我尝试运行以下 sn-p 并且第一个打印语句输出 1 而第二个输出(似乎)没有。此处使用 char 指针数组的长度解引用指针时会发生什么?

【问题讨论】:

  • s[3] 为零。 s[0] 是“1”。
  • 零不是'0'。
  • "123" 实际上是一个 4 字符数组,因为它以空值结尾。所以s[3]就是'\0',可以转换成整数0所以s[s[3]]就是s[0]就是'1'
  • 更准确地说,像"123" 这样的文字字符串是一个四元素常量字符数组。这意味着您应该使用const char* s 来指向此类字符串。你的编译器真的应该警告你这一点。
  • 另外,请尝试打印 static_cast&lt;int&gt;(s[3])。它应该打印整数值0(不同于字符'0')。但是,不要尝试使用索引 4 及以后的任何内容,因为这超出了范围并会导致未定义的行为

标签: c++ pointers char c-strings


【解决方案1】:

不清楚为什么要使用 索引 3 处字符的值 (s[3]) 再次索引字符串。但无论如何,这里的关键是您使用char 来索引数组。这意味着 char 被用作数字,转换很可能使用 ASCII 字符编码。

打印s[3] 时什么都没有打印出来的原因是s 是一个长度为4 的字符数组,最后一个字符是空终止符。 Null 表示数字 0。null 终止符标识字符串的结尾。但它不是一个可打印字符,因为它不是用来打印的。它没有与之关联的 gliph,因此您不会打印任何内容。

当然,您现在可以看到s[s[3]] 只不过是s[0],即字符“1”。

【讨论】:

  • 这里的转换与ASCII无关;如果编译器使用 EBCDIC,代码也会做同样的事情。 s[3]的值为'\0',即char,其值为0。
  • 没有。字符编码对这段代码的作用没有影响。
  • 我不知道你的意思是什么。这个问题及其答案与字符编码无关。您可能会背诵int 通常有 32 位,但可以更小或更大。是真的,但和问题无关。
  • ’\0’ 的值为 0,与编码无关。 \0 是八进制转义序列;它说帽子的字符值为0。
  • 别把话塞进我嘴里。我认为一个角色就是一个角色;我认为char 是一种数字类型,因为它就是这样。在char ch = 42; 之后,ch 保存值 42。在 char ch = '\0'; 之后,ch 保存值 0。在 char ch = 'x'; 之后,ch 保存一个取决于字符编码的值。再一次(我希望,最后一次),字符编码与 '\0' 的值无关。
猜你喜欢
  • 2010-12-14
相关资源
最近更新 更多