C矩阵尺寸不同于声明
问题描述:
如果之前询问过,我很抱歉 - 我无法找到它。C矩阵尺寸不同于声明
这只是一个奇怪的错误,我不明白哪些实用性很少(如果有的话)。下面是代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void print_matrix(int a[4][3], int i, int j)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
return;
}
int main(void)
{
int i, j;
int array[3][5];
for (i = 0; i < 3; i++)
{
for(j = 0; j < 5; j++)
{
scanf("%d",&(array[i][j]));
}
}
printf("array[2][1] = %d\n", array[2][1]);
print_matrix(array, 2, 1);
printf("array[0][4] = %d\n", array[0][4]);
print_matrix(array, 0, 4);
return 0;
}
我声明的大小的矩阵[3] [5],但是当我在另一个函数使用这个矩阵,并用尺寸称之为[4] [3],则返回奇怪的结果。有人可以解释在这种情况下访问内存的方式吗?
答
你的代码有未定义的行为,所以任何事情都可能发生。该函数的第一个参数预计为int (*a)[3]
,一个指向3个整数数组的指针。作为函数参数的数组总是衰减到指针,在这种情况下是指向数组的指针。然而,当你通过array
时,它衰减到一个int(*)[5]
,一个指向5个整数数组的指针。
按照C11标准的以下几个小节:
要使两种指针类型兼容,两者应是相同的合格,双方应指向兼容的类型。
要使两个数组类型兼容,两者应具有相容的元件的类型,并且如果两个大小说明都存在,并且是整数常量表达式,则两个大小说明应具有相同的不变的价值。如果两个数组类型在需要兼容的上下文中使用,则如果两个大小说明符的值不等于,则它是未定义的行为。
由于指针类型不兼容,编译器允许发出任何想要的代码,没有任何限制。代码甚至没有意义,这是未定义行为的含义。
但是GCC(和其他编译器肯定)可以发出如下警告的代码:
warning: passing argument 1 of 'print_matrix' from incompatible pointer type [-Wincompatible-pointer-types]
所以总是启用警告编译,并听取他们!
至于最可能发生的事情,您需要考虑如何为多维数组进行数组访问。 3的大小是数组定义的一部分,所以,当你写a[i][j]
它会被解释为:
*(a + i * 3 + j)
但这不是array
正确的算法,有正确的接入就相当于给
*(array + i * 5 + j)
因此,本质上,通过array
到a
,您访问错误的单元格。
你的编译器应该警告你。编译启用所有警告。 –
只需将该函数更改为void void print_matrix(int x,int y,int a [x] [y])'。请注意,C不允许大小为零的数组。 – Lundin