2014-12-03 132 views
-2

我希望能够传递一个二维数组到一个函数,并让它直接在main中更改数组,所以通过引用传递。当我尝试编译时,我在开关盒中得到error: expected expression before {。 (boardSize = 10,但在编译时未知)通过引用传递二维数组

void fillBoard(int **, int); 

int main() { 
    int **board = malloc(sizeof(int *) * boardSize); 
    fillBoard(board, boardSize); 
} 

void fillBoard(int **board) { 
    int i, *row = malloc(sizeof(int) * boardSize); 
    for (i=0; i<boardSize; i++) { 
     board[i] = malloc(sizeof(int) * boardSize); 
     switch(i) { 
      case 1: row = {1,0,1,0,1,1,0,0,1,0}; break; 
      default: row = {0,0,0,0,0,0,0,0,0,0}; break; 
     } 
     board[i] = row; 
    } 
} 
+2

'int **'不等于'int [N] [M]'。一个是指针指针,另一个是数组数组。 – WhozCraig 2014-12-03 17:39:14

+0

http://stackoverflow.com/a/26877227/971127 – BLUEPIXY 2014-12-03 17:39:16

+0

'void fillBoard(int board [] [boardsize]);' – ooga 2014-12-03 17:41:52

回答

1

有很多不同的方法可以做到这一点。关键是要跟踪你在哪里解决问题。您可以使用singledouble指针来传递并填充board,这一切取决于您如何跟踪元素。 (而二维数组提供了引用元素的便利,所有值在内存中都是连续的,并且可以通过一维参考和偏移来访问)。

当为numeric数组分配内存时有一个重要建议。您必须始终初始化数组的全部元素,以防止试图访问或取消引用未初始化的值(未定义的行为)。简单的做法是用calloc而不是malloc进行分配。 calloc分配将所有值初始化为zeroNULL)。

另外请注意,当您不再需要时,需要跟踪您在程序生命周期中分配的内存和free内存。这将防止内存泄漏的发展。在如下所示的一小段代码中,程序退出时会释放内存。如果这是一些较大代码的一部分,那么当不再需要数据时,您需要释放boardboard2

使用原始阵列将是一个例子:

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

#define boardSize 10 

void fillBoard_p (int *a); 
void fillBoard_p2p (int **a); 

int main() { 
    int i = 0; 
    int j = 0; 

    /* declaring board as an integer pointer */ 
    int *board = calloc (boardSize * boardSize, sizeof (*board)); 

    /* declaring board as a pointer to pointer */ 
    int **board2 = calloc (boardSize, sizeof (*board2)); 
    for (i = 0; i < boardSize; i++) { 
     board2[i] = calloc (boardSize, sizeof (**board2)); 
    } 

    fillBoard_p (board); 
    fillBoard_p2p (board2); 

    printf ("\nboard as an integer pointer:\n"); 
    for (i = 0; i < boardSize * boardSize; i++) { 
     if (i % boardSize == 0) 
      printf ("\n %d", board[i]); 
     else 
      printf (" %d", board[i]); 
    } 

    printf ("\n"); 

    printf ("\nboard2 as an pointer to integer pointer:\n\n"); 
    for (i = 0; i < boardSize; i++) { 
     for (j = 0; j < boardSize; j++) { 
      printf (" %d", board2[i][j]); 
     } 
     printf ("\n"); 
    }  
    printf ("\n"); 

    return 0; 
} 

void fillBoard_p(int *a) { 
    // 0=WHITE, 1=BLACK 
    int i = 0; 
    int j = 0; 
    int b [][boardSize] = { 
     {1,0,1,0,1,1,0,0,1,0}, 
     {1,0,1,1,0,0,1,1,1,0}, 
     {0,0,1,0,1,0,1,0,1,1}, 
     {1,1,0,1,1,0,1,0,0,0}, 
     {0,0,1,0,0,0,1,1,0,1}, 
     {1,1,0,1,1,0,0,1,1,0}, 
     {0,0,1,0,0,1,1,0,1,1}, 
     {0,0,1,0,0,1,0,0,0,0}, 
     {1,1,1,1,0,0,1,1,1,1}, 
     {0,1,0,0,1,1,0,0,0,1} 
    }; 

    for (i = 0; i < boardSize; i++) 
     for (j = 0; j < boardSize; j++) 
      a[i*boardSize+j] = b[i][j]; 
} 

void fillBoard_p2p (int **a) { 
    // 0=WHITE, 1=BLACK 
    int i = 0; 
    int j = 0; 
    int b [][boardSize] = { 
     {1,0,1,0,1,1,0,0,1,0}, 
     {1,0,1,1,0,0,1,1,1,0}, 
     {0,0,1,0,1,0,1,0,1,1}, 
     {1,1,0,1,1,0,1,0,0,0}, 
     {0,0,1,0,0,0,1,1,0,1}, 
     {1,1,0,1,1,0,0,1,1,0}, 
     {0,0,1,0,0,1,1,0,1,1}, 
     {0,0,1,0,0,1,0,0,0,0}, 
     {1,1,1,1,0,0,1,1,1,1}, 
     {0,1,0,0,1,1,0,0,0,1} 
    }; 

    for (i = 0; i < boardSize; i++) 
     for (j = 0; j < boardSize; j++) 
      a[i][j] = b[i][j]; 
} 

输出:

$ ./bin/fillboard 

board as an integer pointer: 

1 0 1 0 1 1 0 0 1 0 
1 0 1 1 0 0 1 1 1 0 
0 0 1 0 1 0 1 0 1 1 
1 1 0 1 1 0 1 0 0 0 
0 0 1 0 0 0 1 1 0 1 
1 1 0 1 1 0 0 1 1 0 
0 0 1 0 0 1 1 0 1 1 
0 0 1 0 0 1 0 0 0 0 
1 1 1 1 0 0 1 1 1 1 
0 1 0 0 1 1 0 0 0 1 

board2 as an pointer to integer pointer: 

1 0 1 0 1 1 0 0 1 0 
1 0 1 1 0 0 1 1 1 0 
0 0 1 0 1 0 1 0 1 1 
1 1 0 1 1 0 1 0 0 0 
0 0 1 0 0 0 1 1 0 1 
1 1 0 1 1 0 0 1 1 0 
0 0 1 0 0 1 1 0 1 1 
0 0 1 0 0 1 0 0 0 0 
1 1 1 1 0 0 1 1 1 1 
0 1 0 0 1 1 0 0 0 1 

另外,由于一个2-D array被顺序存储在存储器中,则可以利用这一事实的优点和使用memcpy(在string.h)来填充传递给你函数的数组。这样可以减少你的函数:

void fillBoard_mc (int *a) { 
    // 0=WHITE, 1=BLACK 
    int b [][boardSize] = { 
     {1,0,1,0,1,1,0,0,1,0}, 
     {1,0,1,1,0,0,1,1,1,0}, 
     {0,0,1,0,1,0,1,0,1,1}, 
     {1,1,0,1,1,0,1,0,0,0}, 
     {0,0,1,0,0,0,1,1,0,1}, 
     {1,1,0,1,1,0,0,1,1,0}, 
     {0,0,1,0,0,1,1,0,1,1}, 
     {0,0,1,0,0,1,0,0,0,0}, 
     {1,1,1,1,0,0,1,1,1,1}, 
     {0,1,0,0,1,1,0,0,0,1} 
    }; 
    memcpy (a, b, boardSize * boardSize * sizeof (int)); 
} 

要是没有编译器和pointer decay的特殊性,你可以简单地使用一个静态声明数组,如:

int board[boardSize][boardSize] = {{0}}; 

传递的地址数组你的函数(成为3星级程序员):

fillBoard (&board); 

具有类似的功能:

void fillBoard (int *a[][boardSize]) { 
    // 0=WHITE, 1=BLACK 
    int b [][boardSize] = { 
     {1,0,1,0,1,1,0,0,1,0}, 
     {1,0,1,1,0,0,1,1,1,0}, 
     {0,0,1,0,1,0,1,0,1,1}, 
     {1,1,0,1,1,0,1,0,0,0}, 
     {0,0,1,0,0,0,1,1,0,1}, 
     {1,1,0,1,1,0,0,1,1,0}, 
     {0,0,1,0,0,1,1,0,1,1}, 
     {0,0,1,0,0,1,0,0,0,0},A 
     {1,1,1,1,0,0,1,1,1,1}, 
     {0,1,0,0,1,1,0,0,0,1} 
    }; 
    memcpy (a, b, boardSize * boardSize * sizeof (int)); 
} 

由于指针衰减(board[10][10] =>board[*][10]),将收到的incompatible pointer type警告,尽管如预期的函数成功复制存储。在实践中不应该依赖不经过警告编译的代码。