二维数组函数的动态分配
所以我有一个程序在C结构化的3个文件中:main,alloc.h和alloc.c: 在主我有一个指向另一个指针,我打算alloc的指针decclaration一个*米阵列:二维数组函数的动态分配
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
int **mat,n,m;
alloc_matrix(&mat,int &n,int &m);
return 0;
}
在alloc.ci具有以下声明:
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);
#endif
在alloc.ci具备的功能:
void alloc_matrix(int ***mat,int *n,int *m)
{
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n,sizeof(int*));
int i;
for(i = 0; i < *n; i++)
*(mat+i) = (int*)calloc(*m,sizeof(int));
}
但程序不起作用。它进入某种循环并没有结束。 如果我将它分配在main
它会工作,但我不知道我在做什么错误在alloc
函数。
这里是正确的代码。你的错误是在alloc_matrix
的定义中,你在分配循环中使用了*(mat+i)
,这应该是*(*mat+i)
,因为mat是int***
,所以2D阵列的基地址应该在*mat
。然后,您需要移动偏移量i
,然后取消引用1D阵列的内存位置。
主要:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
int **mat,n,m;
alloc_matrix(&mat,&n,&m);
return 0;
}
alloc.h
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);
#endif
alloc.c:
void alloc_matrix(int ***mat,int *n,int *m)
{
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n,sizeof(int*));
int i;
for(i = 0; i < *n; i++)
*(*mat+i) = (int*)calloc(*m,sizeof(int));
}
用于读功能的代码:
void read_matrix(int ***mat,int n,int m)
{
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
printf("mat[%d][%d] = ", i, j);
scanf("%d", (*(*mat+i))+j);
}
}
它的问题是它只读取第一行并且它冻结。
void alloc_matrix(int ***mat,int *n,int *m)
这条线有两个问题。两者都不是致命的,但都值得修复。
第一个问题:该程序中的矩阵表示为int**
。为什么alloc_matrix
接受int***
?所有分配内容的标准函数(malloc和friends)都会返回一个指向该内容的指针。这是一种用C语言做事的惯用方式。它减少了你的星数(作为一名三星级C程序员并不值得引以为傲的成就)并简化了代码。该功能应改为
int** alloc_matrix(// but what's inside the() ?
第二个问题是,为什么要调用的函数alloc_matrix
提示用户,且读取值?这些东西与分配无关。一个函数应该做一件事,做得很好。 malloc
是否提示您输入尺寸? fopen
是否提示你输入文件名?这些事情将被视为第一学位的废话,正确如此。建议读取其他地方的尺寸并将它们传递给alloc_matrix
作为输入参数。因此,
int** alloc_matrix(int n, int m) { // but what's inside the {}?
剩下的alloc_matrix
很简单:
int** alloc_matrix(int n, int m) {
int** mat; // that's what we will return
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
// here comes the important part.
既然我们已经简化alloc_matrix
和mat
减少了星数,我们应该怎样做与老体循环的?它是:
*(mat+i) = (int*)calloc(...);
但如果我们去掉一个明星,就成了
(mat+i) = (int*)calloc(...);
这是一个明显的废话。也许旧的路线是一个问题。它引发编译器警告的事实当然并不代表其正确性。那么如何纠正呢?没有太多的选择。事实证明,为了恢复理智,我们必须保留原来的左手边(写作为三星级的mat
)。或者更好的是,使用等效但更地道的符号:
mat[i] = (int*)calloc(m, sizeof(int));
所以整个函数现在变成
int** alloc_matrix(int n, int m) {
int **mat;
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
mat[i] = (int*)calloc(m, sizeof(int));
return mat;
}
,它应该被称为像
mat = alloc_matrix(n, m);
人们常说那一个不应该投calloc
和朋友的结果。但在这种情况下,演员已启用了一条警告,帮助发现了一个错误。我现在要离开剧组。
您能否准确解释演员是如何启用此警告的,以及警告是什么? –
@BradenBest由于作业左侧的类型与右侧的类型不匹配,演员阵容会产生警告。原来左手边是错的。 –
啊,赶上新手的错误。虽然我很确定,如果在类型上对间接级别进行欺骗,他们可能也会对剧组摸索。除此之外,我认为降低间接水平并使用更好的设计符合提问者的最大利益。一个'int **'对于一个矩阵,IMO来说几乎没有用处。 –
没有二维数组,也没有指向一个或一个可以代表一个的指针!作为一名三星级C程序员并不是一种恭维。 – Olaf
如果这是你的代码:请不要纠正它在问题中的错误。如果不是,请使用* actual *代码重新发布整个问题。 –
'alloc_matrix(&mat,int&n,int &m);'这是不合法的C.你使用什么编译器? –