带有1个参数的C++2D数组索引(为什么这样做?)
C++ 2D array indexing with 1 parameter (Why does this work?)
所以我一直在为一个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]
所以"偶然",你会得到正确的结果。
相关文章:
- 为什么C++的文件 I/O 在读取文本文件时忽略初始空行?我怎样才能让它不这样做?
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- C++ 如果在 if 为 true 之后运行,为什么还会这样做
- 为什么 arr[i++] 与 arr[i]++ 会这样做?
- std::字符串 's' 通过 '&s[0]' 转换为字符* - 如何/为什么这样做?
- C++子字符串为什么这样做
- C++循环、作用域和堆栈(为什么这样做?
- 为什么这样做?C中的字符指针
- C++中的字符串分配:为什么这样做
- 带有1个参数的C++2D数组索引(为什么这样做?)
- 为什么这样做?[C++;无效指针]
- 线程之间的Qt连接类型:为什么这样做
- 在派生类中同时分配多个字段-为什么这样做有效
- 为什么这样做?阵列访问不正常
- 迭代char**为什么这样做
- c++ lambda, capture, Smart Ptrs和Stack:为什么这样做?
- 在信号代码中将整数转换为函数指针-为什么这样做?
- 如果一个引用一旦被初始化为一个对象,它就不能被改变,为什么这样做呢?
- 回退可变构造函数-为什么这样做
- 访问类中的私有成员变量:为什么这样做