2016-11-28 92 views
-4

所以我有一個程序在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.你使用什麼編譯器? –

回答

2

這裏是正確的代碼。你的錯誤是在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]'**。 –

0
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來說幾乎沒有用處。 –