C 有人能解释这种行为吗?

C 有人能解释这种行为吗?,c,C,我写了一个简单的代码,得到了一个最大M行的矩阵,我不明白为什么它会给我一个奇怪的输出: 对于M=50: “单元格[1][0]为:17273520”(我每次都会得到随机输出) 对于M=4: “单元格[1][0]为:0”(始终) 有人能解释一下M的确切含义吗?它是如何工作的? 我如何使函数对少于M行的矩阵起作用?您将a定义为数组a[3][4],但在printImage中,您告诉编译器最后一个维度是50而不是4。 这样会弄乱数组的内存映射,编译器会读取远远落后于数组的错误内存位置 您应该始终使用正确的

我写了一个简单的代码,得到了一个最大M行的矩阵,我不明白为什么它会给我一个奇怪的输出:

对于M=50:

“单元格[1][0]为:17273520”(我每次都会得到随机输出)

对于M=4:

“单元格[1][0]为:0”(始终)

有人能解释一下M的确切含义吗?它是如何工作的?
我如何使函数对少于M行的矩阵起作用?

您将
a
定义为数组
a[3][4]
,但在
printImage
中,您告诉编译器最后一个维度是50而不是4。 这样会弄乱数组的内存映射,编译器会读取远远落后于数组的错误内存位置

您应该始终使用正确的尺寸。 可以这样做:

 int a[3][M]; 

在main()中,您将
a
定义为数组
a[3][4]
,但在
printImage
中,您告诉编译器最后一个维度是50,而不是4。 这样会弄乱数组的内存映射,编译器会读取远远落后于数组的错误内存位置

您应该始终使用正确的尺寸。 可以这样做:

 int a[3][M]; 

在main()中,

C中的二维数组
A
是数组的数组。因此,
a
的每个成员的大小必须相同。定义中的第二个尺寸参数是该尺寸

传递给
printImage
的是一个二维数组,该数组衰减为指针。它指向
a
的第一个数组元素

现在,由于真正二维数组的多维指针算术
a[i][j]
*(a+i*M+j)
,我们看到M是类型定义的一部分

如果指定要通过
a[][50]
但实际上要通过
a[][4]
,则
a[1][0]
的索引将远远超出数组边界

由于访问数组边界以外的区域是未定义的行为,因此任何情况都可能发生,您会得到一些随机值。但是这个程序可能会和你的硬盘一样崩溃或者格式化

这也是为什么您应该始终以尽可能高的警告级别构建程序(甚至将大多数警告级别转换为硬错误)。例如,通过以下有用的诊断:

错误:从不兼容的指针类型[-Wincompatible指针类型]传递“printImage”的参数1


如果需要二维数组的数组元素具有不同的大小。您可以指定该函数接受。首先传递数组维度的大小,然后传递具有以下维度的数组:

void printImage(size_t n, size_t m, int a[n][m])
{
  // a is a VLA with dimensions specified by n and m
  // pointer arithmetic will be *(a + i * m + j) 
}

在C语言中,二维数组A是数组的数组。因此,
a
的每个成员的大小必须相同。定义中的第二个尺寸参数是该尺寸

传递给
printImage
的是一个二维数组,该数组衰减为指针。它指向
a
的第一个数组元素

现在,由于真正二维数组的多维指针算术
a[i][j]
*(a+i*M+j)
,我们看到M是类型定义的一部分

如果指定要通过
a[][50]
但实际上要通过
a[][4]
,则
a[1][0]
的索引将远远超出数组边界

由于访问数组边界以外的区域是未定义的行为,因此任何情况都可能发生,您会得到一些随机值。但是这个程序可能会和你的硬盘一样崩溃或者格式化

这也是为什么您应该始终以尽可能高的警告级别构建程序(甚至将大多数警告级别转换为硬错误)。例如,通过以下有用的诊断:

错误:从不兼容的指针类型[-Wincompatible指针类型]传递“printImage”的参数1


如果需要二维数组的数组元素具有不同的大小。您可以指定该函数接受。首先传递数组维度的大小,然后传递具有以下维度的数组:

void printImage(size_t n, size_t m, int a[n][m])
{
  // a is a VLA with dimensions specified by n and m
  // pointer arithmetic will be *(a + i * m + j) 
}

.

您定义了一个维度为3x4的矩阵,总共12整数。但在函数中,您将第二个维度定义为50,这超过了真实维度。当您尝试从
[1][0]
读取一个值时,它会转到位置50,该位置距离位置11的上次初始化值非常远。这就是为什么你会得到一些随机值。

你已经定义了一个维度为3x4的矩阵,总共12个整数。但在函数中,您将第二个维度定义为50,这超过了真实维度。当您尝试从
[1][0]
读取一个值时,它会转到位置50,该位置距离位置11的上次初始化值非常远。这就是为什么你会得到一些随机值。

如何定义
M
它的定义是这样的:#define M 50
M
在这个代码中不是一个变量-它是一个同意你的(编辑的),虽然这不是我的问题,
M
是如何定义的?它是这样定义的:#define M 50
M
在这个代码中不是一个变量-这是一个同意你的意见(编辑),虽然这不是我的问题首先感谢你回答我的问题:)但我需要M作为矩阵中行数的最大值。我需要它能够接受不同维度的不同矩阵(最多50行)。@user1993748-我会解决它。但请将该信息添加到question@user1993748-添加了我的2个cent我按照你说的做了,但在上:“printf(“%d,”,(*(a+i*m+j));”它告诉我:警告:格式“%d”要求参数的类型为“int”,但参数2在我定义的函数声明中的类型为“int*”:int a[][m]首先谢谢你回答我的问题:)但是我需要M作为矩阵中行数的最大值。我需要它能够接受不同维度的不同矩阵(最多50行)。@user1993748-我会解决它。