【问题标题】:How do char arrays and their pointers work in c++ exactly?char 数组及其指针如何在 C++ 中准确工作?
【发布时间】:2019-04-16 12:07:46
【问题描述】:

我是 C++ 的初学者,在处理字符数组时有一点我无法理解:所以,我知道指针本质上是“指向”另一个变量的内存地址的变量,而数组(例如:int a[20])是指向该数组中值的常量指针。当使用不同的数字类型(int、float 等)时,如果我们通过消息输出该数组的名称,它将显示第一个元素的地址,但如果我们对 char 类型执行相同操作,则不会显示地址,而是变量的值。 示例:

#include <iostream>

using namespace std;

int main()
{int a[]={1,2,3,4,5};
cout<<a<<endl; //through output, it shows the memory address of the first 
element of the array;
char b[]={"Mountain"};
cout<<b; //It outputs the word "Mountain"
    return 0;
}

char数组中的指针在输出时会自动转换成它的值吗?

【问题讨论】:

  • OT:引用:“C++ 初学者”你不应该研究这些类型的数组。改为研究std::vectorstd::arraystd::string。如果你要编写真正的 C++,你无论如何都不需要旧的 C 风格的数组。
  • 标题中提出的问题太宽泛了。如果您想问为什么打印 char 数组与打印 int 数组的工作方式不同,您的问题的一个好标题是“为什么打印 char 数组与打印 int 数组的工作方式不同?”

标签: c++


【解决方案1】:

没有区别。 char 指针与 int 指针并没有什么神奇的不同。那么发生了什么事呢?

std::cout &lt;&lt;(或旧的printf())有char* 的重载。这意味着如果输入是char*,则函数的行为会有所不同:迭代指针直到到达'\0' 字符(请参阅null terminated string)。


char b[]={"Mountain"};

b包含

  • {'M', 'o', 'u', 'n', 't', 'a', 'i', 'n'}

而是

  • {'M', 'o', 'u', 'n', 't', 'a', 'i', 'n', '\0'} '\0'

使迭代和停止成为可能。

这也解释了为什么b的数组大小是1大于单词内的字符数。


要添加,您应该使用这些字符指针。它们很危险,并且早已被std::string 等现代实用程序所取代。


现在int a[]={1,2,3,4,5}; 还可以,但std::array&lt;int, 5&gt; a = {1,2,3,4,5}; 更好。

  • 类型是唯一的 (std::array&lt;int, 4&gt; != std::array&lt;int, 5&gt;)
  • 它有一个.size() 函数。
  • 因此,您可以将其传递给其他函数,而无需添加大小参数
  • 它和普通数组一样快

std::array 可以通过包含&lt;array&gt; 来使用。


如果您曾经使用 int* a = new int[5]; 之类的东西,而不是停在那里,而是使用 std::vector


最后永远不要说use namespace std; (here why)

【讨论】:

  • 感谢您抽出宝贵时间回答我的问题。我知道这听起来很傻,但我想好奇心有时会与愚蠢混为一谈!您能否将我可以使用的以前在 C 中可用的字符串的不同函数的替代方法链接起来? (如 strtok、strcpy、strstr 等)
  • 对于strcpy,你只需说std::string a = std::string b; - std::istringstream 允许你做很多其他的事情(虽然大部分不是1行),就像在strtokstrstr上解释的那样.最好的字符串操作为您提供std::regex(依赖于std::string)。最后,您还可以随时在 std::string 上调用 .c_str() 以获取原始 C 样式字符串。
  • 为了简单的替换,发现std::string.replace().find()。这可以甚至像this post问题示例显示的那样被链接起来。虽然小心翼翼。
  • @mountainkingRune 您的问题仍列为未回答。 Dannys 没有回答你的问题吗?如果是,请接受答案。
【解决方案2】:

这完全取决于您如何解释参数。 cout

如果您编写一个使用自己的参数的函数,您可以按照自己喜欢的方式解释。

在这个问题中,如果你想得到地址,你可以这样做

std::cout << static_cast<const void*>(b);

【讨论】:

    【解决方案3】:

    在 C 中,字符串表示为指向char 的指针。因此,当您在 C++ 中将 char* 传递给 ostream(例如 std::cout)时,它会将其解释为以 null 结尾的字符串并打印该字符串的内容而不是地址。如果要打印地址,则必须将该指针转换为另一种类型:

    std::cout << (void*)b;
    

    【讨论】:

      【解决方案4】:

      cout 是一个输出流。当我们使用输出流并传递char* 时,它会将其视为字符串中的空终止字符串(即打印所有字符,直到找到'\0')。对于任何其他指针类型,将打印地址。

      【讨论】:

        猜你喜欢
        • 2021-01-26
        • 2013-04-17
        • 1970-01-01
        • 2021-08-25
        • 2018-06-27
        • 1970-01-01
        • 2014-10-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多