带有1个参数的C++2D数组索引(为什么这样做?)

C++ 2D array indexing with 1 parameter (Why does this work?)

本文关键字:为什么 这样做 索引 数组 1个 参数 C++2D 带有      更新时间:2023-10-16

所以我一直在为一个2d数组类重载一个运算符()。对于我正在进行的随机测试,返回设置为array[0][index]。现在只传递列设置为0的索引(行)。如果索引小于行(那么我们在下一行),它仍然返回数据,就像我指定了列一样?

基本代码示例:

class myArr
{
private:
    float array[3][3];
public:
    myArr::myArr(float a1, float a2, ... ) { array[0][0] = a1; array[0][1] = a2; ... }
    // ^ the "..." just means, the same action till float a9/array[2][2] = a9;
    float& operator() (unsigned index) { return array[0][index]; }
    const float operator() (unsigned index) const { return array[0][index]; }
};
int main()
{
    myArr test(1, 2, 3, 4, 5, 6, 7, 8, 9);
    std::cout << myArr(4) << std::endl; // Displays 5
    myArr(4) = 0; // Set's element 4 to hold value 0
    return 0;
}

奇怪的是,这是有效的。我可以用1个参数设置/获取第5个元素。现在我想知道为什么/如何做到这一点,当然它应该是"越界"之类的错误。最后,这是"安全的"还是你强烈建议不要这样做?

我很少使用2D阵列,主要是因为它们缺乏性能增益

数组连续存储在内存中。在C++中,多维数组一行接一行地存储在内存中,所以我相信从当前行扩展到下一行是完全有效的内存。如果超出2D阵列的最后一行,则会发生越界。

这是否是一件好事是另一个问题。很明显,以这种方式编写代码会让读者挠头,试图弄清楚你在做什么,所以你要避免以这种方式写真正的代码。

如果您要声明一个2D数组,那么您希望在数组的整个生命周期中保持这些语义,所以我强烈建议不要这样做。

当您分配一个2d数组时,它的内存是连续的。因此,如果您分配一个3*3的浮点数组,您将分配9*4个连续字节。这导致:

&array[0][i] = array + 0*3 + i = array + i = array[i]

所以"偶然",你会得到正确的结果。