有很多不同的方法可以做到這一點。關鍵是要跟蹤你在哪裏解決問題。您可以使用single
或double
指針來傳遞並填充board
,這一切取決於您如何跟蹤元素。 (而二維數組提供了引用元素的便利,所有值在內存中都是連續的,並且可以通過一維參考和偏移來訪問)。
當爲numeric
數組分配內存時有一個重要建議。您必須始終初始化數組的全部元素,以防止試圖訪問或取消引用未初始化的值(未定義的行爲)。簡單的做法是用calloc
而不是malloc
進行分配。 calloc
分配和將所有值初始化爲zero
(NULL
)。
另外請注意,當您不再需要時,需要跟蹤您在程序生命週期中分配的內存和free
內存。這將防止內存泄漏的發展。在如下所示的一小段代碼中,程序退出時會釋放內存。如果這是一些較大代碼的一部分,那麼當不再需要數據時,您需要釋放board
和board2
。
使用原始陣列將是一個例子:
#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
警告,儘管如預期的函數成功複製存儲。在實踐中不應該依賴不經過警告編譯的代碼。
'int **'不等於'int [N] [M]'。一個是指針指針,另一個是數組數組。 – WhozCraig 2014-12-03 17:39:14
http://stackoverflow.com/a/26877227/971127 – BLUEPIXY 2014-12-03 17:39:16
'void fillBoard(int board [] [boardsize]);' – ooga 2014-12-03 17:41:52