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,因此您需要假装它们是一维数组(并将它们转换为适当的需要的类型)
相关问题