二维数组函数的动态分配

二维数组函数的动态分配

问题描述:

所以我有一个程序在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函数。

+0

没有二维数组,也没有指向一个或一个可以代表一个的指针!作为一名三星级C程序员并不是一种恭维。 – Olaf

+0

如果这是你的代码:请不要纠正它在问题中的错误。如果不是,请使用* actual *代码重新发布整个问题。 –

+2

'alloc_matrix(&mat,int&n,int &m);'这是不合法的C.你使用什么编译器? –

这里是正确的代码。你的错误是在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); 
     } 
    } 

它的问题是它只读取第一行并且它冻结。

+0

,你会让自己的生活变得更简单,它似乎可以工作。但是当我尝试读取它时,它只读取第一行。可能是我阅读它的方式的问题?void read_matrix(int *** mat,int n,int m) {int i,j; (j = 0; j NickName

+0

@NickName我加了正确的'read_matrix'函数 – Nishant

+0

@NickName'void read_matrix(int ***'问题是*三颗星*,你不需要那么多,另一个问题是* (*(垫+ I)+ J));'。这只是无稽之谈。矩阵是这样访问的:**'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_matrixmat减少了星数,我们应该怎样做与老体循环的?它是:

*(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和朋友的结果。但在这种情况下,演员已启用了一条警告,帮助发现了一个错误。我现在要离开剧组。

+0

您能否准确解释演员是如何启用此警告的,以及警告是什么? –

+0

@BradenBest由于作业左侧的类型与右侧的类型不匹配,演员阵容会产生警告。原来左手边是错的。 –

+1

啊,赶上新手的错误。虽然我很确定,如果在类型上对间接级别进行欺骗,他们可能也会对剧组摸索。除此之外,我认为降低间接水平并使用更好的设计符合提问者的最大利益。一个'int **'对于一个矩阵,IMO来说几乎没有用处。 –