我目前正在研究一种存储和显示右上角三角矩阵的简单代码。好吧,一切都很好,直到我尝试输入4x4矩阵结构并给出输入。第一个结构数组(称为a
)最后一个值已更改,但我没有输入任何代码来更改a
中的任何值。它发生在mReorder()
函数中。然后我尝试了一些try-and-errors找出mReorder()
函数第3行中的问题。我想知道为什么以及如何解决它。
这是我的完整代码:
#include<stdio.h>
//CMO fashion
typedef struct
{
int row;
int col;
int val;
}term;
#define MAX_TERMS 10
term a[MAX_TERMS], b[MAX_TERMS];
void mReorder(void);
int main()
{
int n, i, j;
printf("Enter the number of rows: ");
scanf("%d", &n);
if (n<1 || n>MAX_TERMS)
{
printf("\nInvalid number of rows!!");
exit(0);
}
i=nCount(n);
mRead(n,i);
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
mReorder();
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", a[j].col, a[j].row, a[j].val);
printf("\n");
for (j=0; j<i+1; j++) printf("\n%d\t%d\t%d", b[j].col, b[j].row, b[j].val);
mDisplay();
return 0;
}
void mReorder(void)
{
int i, j, k, m=1;
b[0].col=a[0].col;
b[0].row=a[0].row;
b[0].val=a[0].val;
for(i=0; i<a[0].col; i++)
for (j=1; j<=a[0].val; j++)
if (a[j].row==i)
{
b[m].col=a[j].col;
b[m].row=a[j].row;
b[m].val=a[j].val;
m++;
}
}
void mDisplay(void)
{
int i, j, k, m=1;
printf("\nThe resulting matrix is:\n");
for (i=0; i<b[0].col; i++)
{
//printf("\na");
for (k=0; k<i; k++) printf("%5c", '-');
for (j=i; j<b[0].col; j++)
{
printf("%5d", b[m].val);
m++;
}
printf("\n");
}
}
void mRead(int n, int x)
{
int i, j, m=1, val;
printf("\nEnter %d elements of the matrix: \n", x);
a[0].row=a[0].col=n;
a[0].val=x;
for (i=0; i<n; i++)
{
for (j=0; j<=i; j++)
{
scanf("%d", &val);
a[m].row=j;
a[m].col=i;
a[m].val=val;
m++;
}
}
}
int nCount(int n)
{
if (n==1)
return 1;
return (n+nCount(n-1));
}
你能解释一下这里发生了什么吗?
答案 0 :(得分:1)
您为10 term
项分配了足够的空间,但nCount(4)
返回10,nCount(5)
返回15,等等。如果指定的值大于4,则会溢出数组边界导致未定义的行为 - 这是不惜一切代价避免的。在实践中,你的两个数组之一践踏另一个,但是当你访问另一个数组超出范围时会发生什么完全取决于编译器。它似乎有效;它可能会崩溃;它可能会破坏其他数据结构。
名义上,由于您在数组a
和b
中分配了10个元素,因此您应该可以使用4x4数据,但在mRead()
中,您可以将m = 1
设置为开始于,所以你最后在循环的最后一次迭代中写入a[10]
,这超出了数组的范围。请记住,C数组的索引编号为0,因此定义为SomeType array[N];
的数组包含从array[0]
到array[N-1]
的元素。
请注意,您可以将nCount()
重写为简单(非递归)函数:
static inline int nCount(int n) { return (n + 1) * n / 2; }
(当然需要在它被调用之前出现)。或者,如果您使用不支持C99或C11的古老编译器,请删除inline
关键字。