C++:当多维数组超出范围时,为什么要得到下一行值?

C++:当多维数组超出范围时,为什么要得到下一行值?,c++,C++,这是我的密码 int a[3][3] ={ {0,1,2}, {3,4,5}, {6,7,8} }; for(int i = 0 ; i < 3 ; i ++) for(int j = 3 ; j>0 ; j--) cout << a[i-1][j] << " "; 我期望输出是0 0 0 2 1 0 5 4 但结果是0 0 1 3 2 1

这是我的密码

int a[3][3] ={
            {0,1,2},
            {3,4,5},
            {6,7,8}
    };
for(int i = 0 ; i < 3 ; i ++)
        for(int j = 3 ; j>0 ; j--)
            cout << a[i-1][j] << " ";
我期望输出是0 0 0 2 1 0 5 4 但结果是0 0 1 3 2 1 6 5 4


这背后的原因是什么

查看输出0 0 1 3 2 1 6 5 4中的第一个4和第七个值是垃圾值,它们可以是任何东西。当我执行这段代码时,我得到了020321654。这是因为您正在访问[-1][3]、[-1][2]、[-1][1]、[0][3]和[1][3]的越界值。

请参见您得到的输出0 0 1 3 2 1 6 5 4中的第一个4和第七个值是垃圾值,它们可以是任何值。当我执行这段代码时,我得到了020321654。这是因为您正在访问a[-1][3]、a[-1][2]、a[-1][1]、a[0][3]和a[1][3]的越界值。在第一个循环中,i等于0 当你使用

cout << a[i-1][j] << " ";


i-1是-1,我认为这是您的问题,因为访问数组的-1索引将导致未定义的行为

在第一个循环中,i等于0 当你使用

cout << a[i-1][j] << " ";

i-1是-1,我认为这是您的问题,因为访问数组的-1索引将导致未定义的行为

for(int j = 3 ; j>0 ; j--)
j应该从2开始,而不是从3开始,因为索引是基于0的。条件应为j>=0

这应该像forint j=2;j>=0;j-

或者你也可以选择像这样的内环

for(int j = 3 ; j - 1 >= 0 ; j--)
        cout << a[i-1][j-1] << " ";
但是0 0 0 0 2 1 0 5 4对我来说没有意义,因为你正在尝试这种循环。

我看到了一个错误

for(int j = 3 ; j>0 ; j--)
j应该从2开始,而不是从3开始,因为索引是基于0的。条件应为j>=0

这应该像forint j=2;j>=0;j-

或者你也可以选择像这样的内环

for(int j = 3 ; j - 1 >= 0 ; j--)
        cout << a[i-1][j-1] << " ";
但是0 0 0 2 1 0 5 4对我来说,你尝试的那种循环没有意义

这背后的原因是什么

首先,越界数组访问是未定义的行为。因此,您对a[-1][3]的首次访问无效

但对于你的问题,那里发生了什么:

你可以想象你的:

int a[3][3] = {
  {0, 1, 2}, 
  {3, 4, 5},
  {6, 7, 8}
};
要在系统内存中具有此布局,请执行以下操作:

+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
[-1][3]中的[-1]在arr数组之前指向三个元素

使用[-1][3]中的[3]可以尝试从该位置访问索引3处的元素

  0   1   2   3
+---+---+---+---+---+---+---+---+---+---+---+---+
| ? | ? | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+---+---+---+
因此,您看到的第一个值是arr的第一个元素,接下来的两个a[-1][2]和a[-1][1]是垃圾值

这就是系统上发生的情况,但请记住,这依赖于未定义的行为

这背后的原因是什么

首先,越界数组访问是未定义的行为。因此,您对a[-1][3]的首次访问无效

但对于你的问题,那里发生了什么:

你可以想象你的:

int a[3][3] = {
  {0, 1, 2}, 
  {3, 4, 5},
  {6, 7, 8}
};
要在系统内存中具有此布局,请执行以下操作:

+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
[-1][3]中的[-1]在arr数组之前指向三个元素

使用[-1][3]中的[3]可以尝试从该位置访问索引3处的元素

  0   1   2   3
+---+---+---+---+---+---+---+---+---+---+---+---+
| ? | ? | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+---+---+---+
因此,您看到的第一个值是arr的第一个元素,接下来的两个a[-1][2]和a[-1][1]是垃圾值


这就是您的系统上发生的情况,但请记住,这依赖于未定义的行为。

对于给定的输入,您将0 0 0 2 1 0 5 4作为输出的逻辑是什么?您是否打算按照我的理解,从右到左,从上到下。在顶部添加一个零行。@t.niese后面的逻辑是我假设未定义/未初始化的值为0。在a[3][3]数组中,您有9个值,因此该数组中没有未定义/未初始化的值。任何超出该数组界限的东西都可以是任何东西。对于给定的输入,你想得到0 0 0 0 2 1 0 5 4作为输出的逻辑是什么?你打算用cout@t.niese吗?按照我的理解,它是从右到左,从上到下的。在顶部添加一个零行。@t.niese后面的逻辑是我假设未定义/未初始化的值为0。在a[3][3]数组中,您有9个值,因此该数组中没有未定义/未初始化的值。任何超出该数组界限的内容都可以是任何内容。a[0][3]和a[1][3]也是指向UB的越界访问。@Jarod42您是对的。a[0][3]和a[1][3]也是指向UB的越界访问。@Jarod42您是对的。我相信这个问题并没有增加任何内容。此外,您可能希望链接到。尽管如此,+1.我相信这个问题并没有增加任何内容。此外,您可能希望链接到。仍然是+1。