0

我想在一個函數中動態分配一個二維數組,並在另一個函數中打印它,但createMapBoard()函數的返回值需要是指向數組地址的指針。以下是我的代碼。它編譯並打印出來,但僅限於creatMapBoard()函數。它不會在數組中讀入printMapBoard(** char)函數,我不知道爲什麼。如何在一個函數中動態分配一個二維數組並在另一個函數中打印它?

#include <stdio.h> 

char **createMapBoard(void); 
void printMapBoard(char **board); 
char **destroyMapBoard(char **board); 

int main(){ 
    char **board = createMapBoard(); 
    printMapBoard(board); 
    destroyMapBoard(board); 
    printMapBoard(board); 

    return 0; 
} 

char **createMapBoard(void){ 
    char **ptr[8][8]; 
    int i,j; 
    char F = 'F'; 
    char K = 'K'; 
    char C = 'C'; 
    char D = 'D'; 
    char B = 'B'; 
    int n = 8; 
    int m = 8; 

    for(j=0; j<8; j++){ 
     for(i=0;i<8;i++){ 
      ptr[j][i] = ' '; 
     } 
    } 

    ptr[0][0] = F; 
    ptr[0][1] = F; 
    ptr[1][1] = F; 
    ptr[2][1] = F; 
    ptr[2][2] = F; 
    ptr[3][2] = F; 
    ptr[4][2] = K; 
    ptr[5][0] = C; 
    ptr[5][3] = B; 
    ptr[6][1] = C; 
    ptr[6][2] = C; 
    ptr[6][4] = D; 
    ptr[7][2] = C; 
    ptr[7][5] = D; 
    ptr[7][6] = D; 

    printf("========\n"); 

    for(j=0;j<8;j++){ 
     for(i=0;i<8;i++){ 
      printf("%c",ptr[j][i]); 
     } 
     printf("\n"); 
    } 

    printf("========\n"); 
    printf("\n"); 

    return **ptr; 
} 

void printMapBoard(char **board){ 
    int j, i; 
    printf("========\n"); 
    for(j=0;j<8;j++){ 
     for(i=0;i<8;i++){ 
      printf("%c", board[j][i]); 
     } 
     printf("\n"); 
    } 
    printf("========\n"); 
    printf("\n"); 
} 

char **destroyMapBoard(char **board){ 
    free(**board); 
    free(board); 

    return 0; 
} 
+2

在'createMapBoard'中,你不會動態創建任何東西,而你的變量'ptr'是一個由8個指向'char'指針的8個數組組成的數組,可能不是你想要的。 –

+0

好的,我該如何在createMapBoard函數中動態地分配內存然後呢? – Scarlet

+0

您是否嘗試過搜索它?在這個網站上有成千上萬的例子,可能是數百萬的因特網。嘗試輸入'c allocate 2d array dynamic例如'到你最喜歡的搜索引擎並檢查結果。 –

回答

1

有一些方法可以在C中創建二維數組。我選擇了指針方法的指針。

1 #include <stdio.h>                  
    2 #include <stdlib.h>                 
    3                      
    4 const int row = 8;                  
    5 const int col = 8;                  
    6                      
    7 char **createMapBoard(void);               
    8 void printMapBoard(char **board);              
    9 int destroyMapBoard(char **board);              
10                      
11 int main()                    
12 {                      
13 char **board = createMapBoard();             
14                      
15 printMapBoard(board);                
16 destroyMapBoard(board);                
17                      
18 return 0;                   
19 }                      
20                      
21 char **createMapBoard(void)               
22 {                      
23                      
24 char **ptr;                   
25                      
26 int i, j;                   
27                      
28 char F = 'F';                  
29 char K = 'K';                  
30 char C = 'C';                  
31 char D = 'D';                  
32 char B = 'B';                  
33                      
34 int n = 8; // rows                 
35 int m = 8; // columns                
36                      
37 ptr = (char **)malloc(row * sizeof(char *));          
38 for (i = 0; i < row; ++i) {               
39  ptr[i] = (char *)malloc(col * sizeof(char *));         
40 }                     
41                      
42 for (j = 0; j < row; j++){               
43  for (i = 0; i < col; i++) {              
44   ptr[j][i] = ' ';                
45  }                    
46 }                     
47          
48 ptr[0][0] = F;                  
49 ptr[0][1] = F;                  
50 ptr[1][1] = F;                  
51 ptr[2][1] = F;                  
52 ptr[2][2] = F;                  
53 ptr[3][2] = F;                  
54 ptr[4][2] = K;                  
55 ptr[5][0] = C;                  
56 ptr[5][3] = B;                  
57 ptr[6][1] = C;                  
58 ptr[6][2] = C;                  
59 ptr[6][4] = D;                  
60 ptr[7][2] = C;                  
61 ptr[7][5] = D;                  
62 ptr[7][6] = D;                  
63                      
64 printf("========\n");                
65                      
66 for (j = 0; j < row; j++) {               
67  for (i = 0; i < col; i++) {              
68   printf("%c",ptr[j][i]);              
69  }                    
70  printf("\n");                 
71 }                     
72                      
73 printf("========\n");                
74 printf("\n");                  
75                      
76 return ptr;                   
77 }                      
78                      
79 void printMapBoard(char **board)              
80 {                      
81 int j, i;                   
82 printf("========\n");                
83 for (j = 0; j < row; j++) {              
84  for (i = 0; i < col; i++) {              
85   printf("%c", board[j][i]);             
86  }                    
87  printf("\n");                 
88 }                     
89 printf("========\n");                
90 printf("\n");                  
91 }                      
92  
93 int destroyMapBoard(char **board)              
94 {                      
95 int i;                    
96 for (i = 0; i < col; ++i)               
97  free(board[i]);                
98                      
99 free(board);                  
100                      
101 return 0;                   
102 } 
+0

「有一些方法可以在C中創建二維數組」 - 但在這個答案中沒有二維數組。 ... –

0
#include <stdio.h> 
#include <stdlib.h> 

char * createMapBoard(void); 
void printMapBoard(char board[8][8]); 
char **destroyMapBoard(char board[8][8]); 

int main(){ 
    char (*board)[8] = (char (*)[8])createMapBoard(); 
    printMapBoard(board); 
    destroyMapBoard(board); 
    //printMapBoard(board); 

    return 0; 
}  

char *createMapBoard(void){ 
    char (*ptr)[8] = (char (*)[8])malloc(sizeof(char) * 8 * 8); 
    int i,j; 
    char F = 'F'; 
    char K = 'K'; 
    char C = 'C'; 
    char D = 'D'; 
    char B = 'B'; 
    int n = 8; 
    int m = 8; 

    for(j=0; j<8; j++){ 
     for(i=0;i<8;i++){ 
      ptr[j][i] = ' '; 
     } 
    } 

    ptr[0][0] = F; 
    ptr[0][1] = F; 
    ptr[1][1] = F; 
    ptr[2][1] = F; 
    ptr[2][2] = F; 
    ptr[3][2] = F; 
    ptr[4][2] = K; 
    ptr[5][0] = C; 
    ptr[5][3] = B; 
    ptr[6][1] = C; 
    ptr[6][2] = C; 
    ptr[6][4] = D; 
    ptr[7][2] = C; 
    ptr[7][5] = D; 
    ptr[7][6] = D; 

    printf("========\n"); 

    for(j=0;j<8;j++){ 
     for(i=0;i<8;i++){ 
      printf("%c",ptr[j][i]); 
     } 
     printf("\n"); 
    } 

    printf("========\n"); 
    printf("\n"); 

    return (char *)ptr; 
}  

void printMapBoard(char board[8][8]){ 
    int j, i; 
    printf("========\n"); 
    for(j=0;j<8;j++){ 
     for(i=0;i<8;i++){ 
      printf("%c", board[j][i]); 
     } 
     printf("\n"); 
    } 
    printf("========\n"); 
    printf("\n"); 
} 

char **destroyMapBoard(char board[8][8]){ 
    free(board); 

    return 0; 
} 

之前讓你原來的如何分配二維數組並把它傳遞到另外一個問題,你的代碼是在幾個方面,使人們談論你的初始點難以打破。讓我們先解決它們,然後再解決問題。首先,通過使用像ptr [j] [i] =''這樣的語句,你大概想要有一個二維的字符數組,在這種情況下,你應該聲明ptr是這樣的。

char ptr[8][8]; // 2D array of chars 

char** ptr[8][8]; // 2D array of pointers to pointers to chars 

如果你想回到你的內心createMapBorad創建數組(PTR)二,那麼你就需要返回PTR,不** PTR。即,

return ptr; 

return ** ptr; 

表達** PTR取消引用PTR的兩倍,其相當於PTR [0] [0]在此情況下,這將返回 'F'(0×46 )僞裝成它是指向字符指針的指針(char **)。您的printMapBoard然後訪問地址0x46,這會導致段錯誤。這幾乎肯定不是你想要做的。

修復它們後,如果你想返回一個「二維字符數組」而不是指針數組,你需要讓createMapBoard返回char *而不是char **。 char **是指針(對字符)的數組(指針)。

到目前爲止,你至少需要修正createMapBoard於:(我們尚未敬請關注)

char * createMapBoard(void) { 
    char ptr[8][8]; 
    ... 
    return (char *)ptr; 
} 

順便說一句,如果你可以說一個函數返回一個二維數組,而不是char *(它基本上是一維數組,所以你不能像[i] [j]那樣做),但是AFAIK C不允許我們這樣做。以下(假設)代碼是語法錯誤。

char[8][8] createMapBoard(void) { 
    char ptr[8][8]; 
    ... 
    return ptr; 
} 

所以你需要假裝你返回一個常規的一維數組(char *)。稍後您可以將它投射到真正的2D陣列上(我們很快就會開始使用它)。

以這種方式修復createMapBoard之後,您仍然在返回本地數組作爲返回值時出錯。這是錯誤的,因爲本地數組的生存期限於函數調用的結束。所以代碼

char * createMapBoard(void) { 
    char ptr[8][8]; 
    ... 
    return (char *)ptr; 
} 

在語法上沒問題,但打印錯誤的結果。

你需要調用malloc創建一個數組,你從函數返回後是活的,如:

char * createMapBoard(void) { 
    char * ptr = (char *)malloc(sizeof(char) * 8 * 8); 
    ... 
    return ptr; 
} 

但隨後PTR實質上成爲createMapBoard功能,這使得作業像

內一維數組
ptr[i][j] = ' ' 

不再有效。

可以使PTR二維數組的方式是這樣的:

char (*ptr)[8] = (char (*)[8])malloc(sizeof(char) * 8 * 8); 

這是從C99的標準支持。

這樣,編譯器就能理解ptr是一個指向2D數組的指針,其每行元素的數量是8(因此它可以正確計算[i] [j]的地址)。

可以有printMapBorad簡單地採取炭的自變量[8] [8]是這樣的:

void printMapBorad(char board[8][8]) { 
    ... 
} 

總結:

  • 功能參數可以被直接聲明爲2D陣列(像炭a [8] [8])
  • 通過char(* a)[8];可以將局部變量聲明爲二維數組。 (和普通指針類似地由(char(*)[8])普通函數執行;
  • 函數返回類型不能被聲明爲二維數組AFAIK,因此您需要假裝它們是一維數組(並將它們轉換爲適當的需要的類型)
相關問題