为什么数组的维是其类型的一部分?

oct*_*pus 10 c++ arrays c++11

在阅读C ++ Primer书籍时,我遇到了这样的说法:“数组中元素的数量是数组类型的一部分。” 因此,我想使用以下代码进行查找:

#include<iostream>

int main()
{
    char Array1[]{'H', 'e', 'l', 'p'};
    char Array2[]{'P', 'l', 'e', 'a', 's', 'e'};

    std::cout<<typeid(Array1).name()<<std::endl;        //prints  A4_c
    std::cout<<typeid(Array2).name()<<std::endl;        //prints  A6_c

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,两个数组上的typeid结果表明它们有所不同。

  • 幕后发生了什么事?
  • 为什么数组必须具有包含其大小的类型?仅仅是因为它的大小不应该改变吗?
  • 这将如何影响比较数组?

只是希望能够深刻理解这个概念。

Vit*_*meo 18

幕后发生了什么事?

根据定义,非动态分配的是固定大小的同类元素容器。N类型的元素数组T作为N类型的对象的连续序列布置在内存中T


为什么数组的类型必须包含其大小?

我不认为数组的类型包括它的大小是“必要的”-事实上,您可以使用指针来引用连续的T对象序列。这样的指针将丢失有关数组的大小信息。

但是,这是一件有用的事情。它提高了类型安全性,并在编译时对有用的信息进行了编码,可以以多种方式使用。例如,您可以使用引用数组来重载不同大小的数组

void foo(int(&array)[4]) { /* ... */ }
void foo(int(&array)[8]) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

或找出数组的大小作为常数表达式

template <typename T, std::size_t N>
constexpr auto sizeOf(const T(&array)[N]) { return N; }
Run Code Online (Sandbox Code Playgroud)

这将如何影响比较数组?

确实不是。

您不能以比较两个数字(例如int对象)的相同方式比较C样式数组。您将必须编写某种词典比较,并确定这对于不同大小的集合意味着什么。std::vector<T>提供,并且可以将相同的逻辑应用于数组。


奖励: C ++ 11和更高版本提供std::array,它是带有容器状接口的C样式数组的包装。应该首选C风格的数组,因为它与其他容器(例如std::vector<T>)更加一致,并且还支持开箱即用的词典编目比较

  • 可能值得注意的是,基于范围的for循环(其范围是数组)需要在编译时读取数组的大小-这有点微妙,因为(非常感谢!)在此示例中,从未写出数组的类型,但似乎比基于大小的重载要多得多。 (3认同)
  • “您将必须编写某种词典比较,并确定这对于不同大小的集合意味着什么。” 您可以只使用`std :: equal`(通过为数组定义的`std :: begin`和`std :: end`)。在这种情况下,不同大小的数组是不相等的。 (2认同)

Sir*_*Guy 7

创建对象时分配给对象的空间量完全取决于其类型。我所说的分配不是来自new或的分配malloc,而是分配的空间,以便您可以运行构造函数并初始化对象。

如果您将结构定义为(例如)

struct A { char a, b; }; //sizeof(A) == 2, ie an A needs 2 bytes of space
Run Code Online (Sandbox Code Playgroud)

然后,当您构造对象时:

A a{'a', 'b'};
Run Code Online (Sandbox Code Playgroud)

您可以将构造对象的过程视为一个过程:

  • 分配2个字节的空间(在堆栈上,但是对于本示例而言,无关紧要)
  • 运行对象的构造函数(在这种情况下,复制'a''b'到对象)

重要的是要注意,所需的2个字节的空间完全由对象的类型决定,函数的参数无关紧要。因此,对于数组,处理过程是相同的,除了现在所需的空间量取决于数组中元素的数量。

char a[] = {'a'}; //need space for 1 element
char b[] = {'a', 'b', 'c', 'd', 'e'}; //need space for 5 elements
Run Code Online (Sandbox Code Playgroud)

所以类型的ab必须反映一个事实,a需要有足够的空间1个char和b需要足够的空间,5个字符。这确实意味着这些数组的大小不能突然改变,一旦创建了5个元素的数组,它始终是5个元素的数组。为了拥有大小可能变化的类似“数组”的对象,您需要动态的内存分配,这应该在您的书中有所介绍。