【问题标题】:Difference between char[] and int[] [duplicate]char[] 和 int[] 之间的区别 [重复]
【发布时间】:2025-12-24 00:05:12
【问题描述】:

最近,我看了一个视频,上面说当我定义了一个整数数组时

int my_array[] = {1,2,3};

然后我打印了 my_array cout << my_array; 然后我会得到内存中第一个整数的地址,但是当我们定义一个像

这样的字符数组时
char my_string[] = "Hello";

然后,当我尝试打印 my_string cout << my_string 时,它会返回 Hello类似地在我们定义指向字符的指针时带有指针

char mystring[] = "HELLO";
char *my = mystring;
cout << my << endl;//HELLO

我们尝试打印指针变量它返回的字符串。

现在我读到了这个article,我读到这个字符串带走了他的内存地址。但我仍然不明白为什么它们不一样,为什么字符数组打印字符串文字,而 int 数组打印第一个的地址。

提前致谢。

【问题讨论】:

  • char *my = mystring; -> char *my = my_string;? why an array of chars returns the string literal 你的意思是 cout &lt;&lt; mystring打印字符串?
  • 抱歉改错了
  • 它们都返回第一个的地址。这就是字符串在 C 中的表示方式:作为指向以 '\0' 字符结尾的字符序列的指针。 (至少转换为指针时;int[] 将分解为 int* 但最初不同。)
  • @UlrichEckhardt 抱歉,写错了,请看我的编辑

标签: c++ arrays pointers operator-overloading implicit-conversion


【解决方案1】:

为什么 chars 数组返回字符串字面量,而 int 数组返回第一个字符的地址。

我假设“returns”这个词的意思是“print”。

因为non-member std::ostream::operator&lt;&lt;(ostream&amp;, const char *) overload 遍历内存,char* 指针指向并打印它的内容,而没有std::ostream::operator&lt;&lt;(int*) 重载,所以int* 被强制转换为const void*std::ostream::operator&lt;&lt;(const void*) overload用于打印值,该函数打印指针的值。

您仍然可以通过手动转换来打印指向字符串的指针的值:

cout << static_cast<void*>(my_string) << endl;

【讨论】:

  • 谢谢,所以最后打印字符串的唯一原因是因为 i/o 流过载?
  • 嗯,是的,因为它被指定以这种方式运行。
【解决方案2】:

这是 C 的后遗症,标准库必须支持 C 样式的字符串(以 char* 为空终止)。为此,std::cout 具有 const char* 的重载,将其视为 C 样式字符串并打印到空终止符。

打印地址是传递给std::cout的指针的正常行为(因此您的int指针内存位置打印输出)。

【讨论】:

    【解决方案3】:

    my_array 将包含内存中第一个整数的地址,

    没有。 my_array 将包含内存中的三个整数。

    如果我执行 cout

    是的。这就是指定字符流的行为方式。插入指针时,将打印地址。除非您插入指向不同处理的 char 的指针。

    如何区别对待?

    根据文档,将打印指向的字符及其兄弟,直到达到空终止符为止。

    【讨论】:

    • 如果我做cout &lt;&lt; myarray &lt;&lt; endl 那么这将打印内存中第一项的地址
    • 哦,好的,谢谢,如何区别对待?
    【解决方案4】:

    其实my_arrayint[3],而mystring是char[6]

    cout &lt;&lt; my_string; 打印字符串的原因是因为应用了这些转换 char[6] -&gt; char const *,ostream operator&lt;&lt; 知道将char const * 视为string

    对于cout &lt;&lt; my_array,转换为int[3] -&gt; int * -&gt; void const *void const * 上的 ostream operator&lt;&lt; 只是打印地址。

    【讨论】:

      【解决方案5】:

      这个字符数组的声明

      char my_string[] = "Hello";
      

      等价于下面的声明

      char my_string[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
      

      即数组的元素由字符串字面量的字符初始化,包括其终止的零。

      在表达式中使用的数组有极少数例外被转换为指向它们的第一个元素的指针。

      例如,如果您使用 sizeof 运算符,则数组类型的对象不会转换为指向其第一个元素的指针。这是一个罕见的例外。

      这是一个演示程序

      #include <iostream>
      
      int main() 
      {
          int my_array[] = { 1, 2, 3 };
          char my_string[] = "Hello";
      
          std::cout << "sizeof( my_array ) = " << sizeof( my_array ) << '\n';
          std::cout << "sizeof( my_string ) = " << sizeof( my_string ) << '\n';
      
          return 0;
      }
      

      它的输出是

      sizeof( my_array ) = 12
      sizeof( my_string ) = 6
      

      但是例如,当一个数组类型的对象被用作运算符 * 的操作数时,它会被转换为指向其第一个元素的指针。

      这是另一个演示程序

      #include <iostream>
      
      int main() 
      {
          int my_array[] = { 1, 2, 3 };
          char my_string[] = "Hello";
      
          std::cout << "*my_array = " << *my_array << '\n';
          std::cout << "*my_string = " << *my_string << '\n';
      
          return 0;
      }
      

      程序输出是

      *my_array = 1
      *my_string = H
      

      在 C++ 标准中,定义了重载的 operator &lt;&lt; 以输出指向 char 的指针所指向的字符串(以零字符结尾的字符序列)。

      所以如果你会写

      std::cout << my_string << '\n';
      

      然后在调用此操作符

      对于整数数组,运算符

      这是一个演示程序。

      #include <iostream>
      
      int main() 
      {
          int my_array[] = { 1, 2, 3 };
          char my_string[] = "Hello";
      
          std::cout << my_array << '\n';
          std::cout << my_string << '\n';
      
          return 0;
      }
      

      它的输出可能看起来像

      0x7ffdcfe094e4
      Hello
      

      如果你想为字符数组选择重载运算符

      这里还有一个演示程序。

      #include <iostream>
      
      int main() 
      {
          int my_array[] = { 1, 2, 3 };
          char my_string[] = "Hello";
      
          std::cout << my_array << '\n';
          std::cout << static_cast<void *>( my_string ) << '\n';
      
          return 0;
      }
      

      它的输出可能是

      0x7ffef7ac0104
      0x7ffef7ac0112
      

      【讨论】:

        最近更新 更多