printf 在 C 中打印多维数组的意外最后一个元素,具体取决于输入?

printf prints unexpected last element of a multidimensional array in C, depending on input?

提问人:Hack-R 提问时间:5/30/2015 更新时间:5/30/2015 访问量:34

问:

我正在学习在 C 中使用多维数组,但我无法理解为什么有时会在以下程序中给出意想不到的结果。printf()

这个程序的想法是,我希望初始化一个 5x2 数组并接受来自用户的 5 个整数来填充第二个索引,然后打印数组:scanf

#include <stdio.h>
#include <conio.h>

int main(void)
{
    int i=0, mat[5][2] = {
        {0, 0},
        {0, 0},
        {0, 0},
        {0, 0},
        {0, 0}
    };

    printf("Please enter 5 integers then press enter: \n");

    do {
        scanf("%i", &mat[i][2]);
        i++; 
       } while (getchar() != '\n');


    printf("Here's what the 5x2 array looks like: \n");

    for(i = 0; i < 5; i++){
        printf("%i %i", mat[i][1], mat[i][2]);
        printf(" \n");
    }

    return 0;   
}

如果我以用户身份输入某些整数,则输出符合预期:

C:\Users\hackr>tmp.exe
Please enter 5 integers then press enter:
0 1 2 3 4
Here's what the 5x2 array looks like:
0 0
0 1
0 2
0 3
0 4

但是,如果我输入不同的整数,那么输出的最后一行不是我所期望的:

C:\Users\hackr>tmp.exe
Please enter 5 integers then press enter:
1 2 3 4 5
Here's what the 5x2 array looks like:
0 1
0 2
0 3
0 4
0 4

C:\Users\hackr>tmp.exe
Please enter 5 integers then press enter:
9 8 7 6 5
Here's what the 5x2 array looks like:
0 9
0 8
0 7
0 6
0 4

事实上,正如你在上面看到的,索引 2 的最后一个元素似乎是任意的“4”。

也许这是由于我对数组值的索引或引用方式存在误解?

C 多维数组

评论

1赞 cnicutar 5/30/2015
scanf("%i", &mat[i][2])超出了 的界限。mat[5][2]
0赞 Hack-R 5/30/2015
@cnicutar?我一直在努力理解这一点。我知道数组是 0 索引的,但是在声明它们的大小时,我应该像 5x2 数组一样输入实际的元素数?你能再解释一下吗?int mat[5][2]
0赞 Hack-R 5/30/2015
@cnicutar没关系,我现在明白了。谢谢!

答:

2赞 Yu Hao 5/30/2015 #1

mat定义为:

int mat[5][2];

有效元素适用于 0 ~ 4 和 0 ~ 1 范围内,而您尝试访问mat[x][y]xy

scanf("%i", &mat[i][2]);

printf("%i %i", mat[i][1], mat[i][2]);

评论

0赞 KevinDTimm 5/30/2015
并且也出界了scanf("%i", &mat[i][2]);
0赞 Hack-R 5/30/2015
谢谢。我以为我之前在第二个索引中尝试过从 0 开始的索引假设,但结果很糟糕,但显然我在代码中还有其他一些令人困惑的错误。+1
3赞 Anand 5/30/2015 #2

数组始终以索引 0 开头。

您可以尝试以下代码片段:

#include <stdio.h>
#include <conio.h>

int main(void)
{
    int i=0, mat[5][2] = {
        {0, 0},
        {0, 0},
        {0, 0},
        {0, 0},
        {0, 0}
    };

    printf("Please enter 5 integers then press enter: \n");

    do {
        scanf("%i", &mat[i][1]);
        i++; 
       } while (getchar() != '\n');


    printf("Here's what the 5x2 array looks like: \n");

    for(i = 0; i < 5; i++){
        printf("%i %i", mat[i][0], mat[i][1]);
        printf(" \n");
    }

    return 0;   
}

在声明时,您可以使用 mat[5][2],但对于访问,您应该使用

mat[0][0] mat[0][1]
mat[1][0] mat[1][1]
...
..
mat[4][0] mat[4][1]

我认为现在它应该可以工作。

评论

0赞 Hack-R 5/30/2015
谢谢。我以为我之前在第二个索引中尝试过从 0 开始的索引假设,但结果很糟糕,但显然我在代码中还有其他一些令人困惑的错误。+1 一个后续问题 -- 为什么当我输入输入时它似乎有效?0 1 2 3 4
1赞 Anand 5/30/2015
原因是矩阵分配是使用计算机体系结构的十六进制十进制范围完成的。在你的情况下,C 编程保证所有矩阵元素将以以下格式存储:mat[0][0] - in address (&mat) till mat[4][1] in &(mat+9)。您尝试使用自己的地址将元素存储在分配位置之外,并尝试使用未分配的地址进行访问。因此,计算机决定是否将值存储在特定位置。给出错误结果的位置是 &(Mat+11) 超出了分配范围。.