C語言的二維陣列
複習一維陣列
介紹陣列與指標相關的文章實在太多了,我們簡單帶過一維陣列:
#include <stdio.h>
int main()
{
const int length = 3;
int arr[length];
int i;
printf(" arr = %p\n", arr);
printf("&arr = %p\n", &arr);
printf("size of array: %lu = %lu * %d\n", sizeof(arr), sizeof(int), length);
printf("length of array: %ld\n", sizeof(arr) / sizeof(arr[0]));
for (i = 0; i < length; i++)
arr[i] = i;
// Show.
for (i = 0; i < length; i++)
printf("address %p: value = %d (size = %lu)\n", &arr[i], arr[i], sizeof(arr[i]));
return 0;
}
輸出如下:
arr = 0x7ffdcf290ce0
&arr = 0x7ffdcf290ce0
size of array: 12 = 4 * 3
length of array: 3
address 0x7ffdcf290ce0: value = 0 (size = 4)
address 0x7ffdcf290ce4: value = 1 (size = 4)
address 0x7ffdcf290ce8: value = 2 (size = 4)
「&arr」與陣列變數「arr」是等價的。
有時遇到長度不固定,可以在長度確定後,再用malloc()配置指標,記得養成好習慣,使用後用free()釋出記憶體,不然在程式結束之前,會一直佔用malloc的記憶體區域。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int length;
int *ptr;
int i;
length = 3;
ptr = (int*)malloc(sizeof(int) * length);
printf("ptr = %p\n", ptr);
printf("&ptr = %p\n", &ptr);
// Wrong
//printf("size of array: %lu = %lu * %d\n", sizeof(ptr), sizeof(int), length);
//printf("length of array: %lu\n", sizeof(ptr) / sizeof(ptr[0]));
printf("size of array: %lu * %d\n", sizeof(int), length);
printf("size of pointer: %lu\n", sizeof(ptr));
for (i = 0; i < length; i++)
ptr[i] = i;
// Show 1: as an array.
printf("--- Show 1 ---\n");
for (i = 0; i < length; i++)
printf("address %p: value = %d (size = %lu)\n", &ptr[i], ptr[i], sizeof(ptr[i]));
// Show 2: as a pointer.
printf("--- Show 2 ---\n");
for (i = 0; i < length; i++)
printf("address %p: value = %d (size = %lu)\n", ptr + i, *(ptr + i), sizeof(*(ptr + i)));
free(ptr);
return 0;
}
輸出如下:
ptr = 0x55cd601b02a0
&ptr = 0x7ffd42666ec0
size of array: 4 * 3
size of pointer: 8
--- Show 1 ---
address 0x55cd601b02a0: value = 0 (size = 4)
address 0x55cd601b02a4: value = 1 (size = 4)
address 0x55cd601b02a8: value = 2 (size = 4)
--- Show 2 ---
address 0x55cd601b02a0: value = 0 (size = 4)
address 0x55cd601b02a4: value = 1 (size = 4)
address 0x55cd601b02a8: value = 2 (size = 4)
sizeof()輸入一個指標變數,得到的大小,是儲存一個位址所需要的大小,在64位元的作業系統中,是8-Byte,也就是64-bit。
二維陣列
先來看3×5的二維陣列範例。
| Column 0 | Column 1 | Column 2 | Column 3 | Column 4 | |
|---|---|---|---|---|---|
| Row 0 | 0 | 1 | 2 | 3 | 4 |
| Row 1 | 10 | 11 | 12 | 13 | 14 |
| Row 2 | 20 | 21 | 22 | 23 | 24 |
#include <stdio.h>
int main()
{
const int row = 3, column = 5;
int arr[row][column];
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < column; j++) {
arr[i][j] = (10 * i) + j;
}
}
// Show.
printf("arr: address = %p, address = %p\n", arr, &arr);
for (i = 0; i < row; i++) {
printf("Row %d: address: %p, address = %p\n", i, arr[i], &arr[i]);
for (j = 0; j < column; j++) {
printf("(Row %d, Column %d): value = %d, address = %p\n", i, j, arr[i][j], &arr[i][j]);
}
}
return 0;
}
輸出如下:
arr: address = 0x7fffac0e4490, address = 0x7fffac0e4490
Row 0: address: 0x7fffac0e4490, address = 0x7fffac0e4490
(Row 0, Column 0): value = 0, address = 0x7fffac0e4490
(Row 0, Column 1): value = 1, address = 0x7fffac0e4494
(Row 0, Column 2): value = 2, address = 0x7fffac0e4498
(Row 0, Column 3): value = 3, address = 0x7fffac0e449c
(Row 0, Column 4): value = 4, address = 0x7fffac0e44a0
Row 1: address: 0x7fffac0e44a4, address = 0x7fffac0e44a4
(Row 1, Column 0): value = 10, address = 0x7fffac0e44a4
(Row 1, Column 1): value = 11, address = 0x7fffac0e44a8
(Row 1, Column 2): value = 12, address = 0x7fffac0e44ac
(Row 1, Column 3): value = 13, address = 0x7fffac0e44b0
(Row 1, Column 4): value = 14, address = 0x7fffac0e44b4
Row 2: address: 0x7fffac0e44b8, address = 0x7fffac0e44b8
(Row 2, Column 0): value = 20, address = 0x7fffac0e44b8
(Row 2, Column 1): value = 21, address = 0x7fffac0e44bc
(Row 2, Column 2): value = 22, address = 0x7fffac0e44c0
(Row 2, Column 3): value = 23, address = 0x7fffac0e44c4
(Row 2, Column 4): value = 24, address = 0x7fffac0e44c8
「arr」與「arr[]」分別是二維和一維陣列變數,「&arr」等價於「arr」,「&arr[]」等價於「arr[]」。
二級指標
若是用malloc()配置指標,可選用二級指標實現二維陣列。
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int row = 3, column = 5;
int **pptr = (int**)malloc(sizeof(int*) * row);
int i, j;
for (i = 0; i < row; i++) {
pptr[i] = (int*)malloc(sizeof(int) * column);
for (j = 0; j < column; j++) {
pptr[i][j] = (10 * i) + j;
}
}
// Show.
printf("pptr: value = %p, address = %p\n", pptr, &pptr);
for (i = 0; i < row; i++) {
printf("Row %d: value: %p, address = %p\n", i, pptr[i], &pptr[i]);
for (j = 0; j < column; j++) {
printf("(Row %d, Column %d): value = %d, address = %p\n", i, j, pptr[i][j], &pptr[i][j]);
}
}
//// Show as a pointer.
//for (i = 0; i < row; i++) {
// printf("Row %d: value: %p, address = %p\n", i, *(pptr + i), pptr + i);
// for (j = 0; j < column; j++) {
// printf("(Row %d, Column %d): value = %d, address = %p\n", i, j, *(*(pptr + i) + j), *(pptr + i) + j);
// }
//}
return 0;
}
輸出如下:
pptr: value = 0x55640558c2a0, address = 0x7fffd8e91810
Row 0: value: 0x55640558c2c0, address = 0x55640558c2a0
(Row 0, Column 0): value = 0, address = 0x55640558c2c0
(Row 0, Column 1): value = 1, address = 0x55640558c2c4
(Row 0, Column 2): value = 2, address = 0x55640558c2c8
(Row 0, Column 3): value = 3, address = 0x55640558c2cc
(Row 0, Column 4): value = 4, address = 0x55640558c2d0
Row 1: value: 0x55640558c2e0, address = 0x55640558c2a8
(Row 1, Column 0): value = 10, address = 0x55640558c2e0
(Row 1, Column 1): value = 11, address = 0x55640558c2e4
(Row 1, Column 2): value = 12, address = 0x55640558c2e8
(Row 1, Column 3): value = 13, address = 0x55640558c2ec
(Row 1, Column 4): value = 14, address = 0x55640558c2f0
Row 2: value: 0x55640558c300, address = 0x55640558c2b0
(Row 2, Column 0): value = 20, address = 0x55640558c300
(Row 2, Column 1): value = 21, address = 0x55640558c304
(Row 2, Column 2): value = 22, address = 0x55640558c308
(Row 2, Column 3): value = 23, address = 0x55640558c30c
(Row 2, Column 4): value = 24, address = 0x55640558c310
可觀察出,5個數的一維陣列,被分為3組,3組的位址是分開的,且比起直接使用arr[][]宣告陣列,多了3個位址(&pptr[0]、&pptr[1]、&pptr[2])分別去記錄每組的起始位址。
指向一維陣列的指標做二維陣列
宣告陣列arr[][]若要用指標形式實現,可使用指標指向int[]。
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int row = 3, column = 5;
int (*parr)[column] = (int(*)[column])malloc(sizeof(int) * column * row);
int i, j;
for (i = 0; i < row; i++) {
parr[i] = (int*)malloc(sizeof(int) * column);
for (j = 0; j < column; j++) {
parr[i][j] = (10 * i) + j;
}
}
// Show.
printf("parr: value = %p, address = %p\n", parr, &parr);
for (i = 0; i < row; i++) {
printf("Row %d: value: %p, address = %p\n", i, parr[i], &parr[i]);
for (j = 0; j < column; j++) {
printf("(Row %d, Column %d): value = %d, address = %p\n", i, j, parr[i][j], &parr[i][j]);
}
}
//// As a pointer to an array.
//for (i = 0; i < row; i++) {
// printf("Row %d: value: %p, address = %p\n", i, *(parr + i), parr + i);
// for (j = 0; j < column; j++) {
// printf("(Row %d, Column %d): value = %d, address = %p\n", i, j, *(parr[i] + j), parr[i] + j);
// }
//}
return 0;
}
輸出如下:
parr: value = 0x555d6a0e92a0, address = 0x7ffc637cd9e0
Row 0: value: 0x555d6a0e92a0, address = 0x555d6a0e92a0
(Row 0, Column 0): value = 0, address = 0x555d6a0e92a0
(Row 0, Column 1): value = 1, address = 0x555d6a0e92a4
(Row 0, Column 2): value = 2, address = 0x555d6a0e92a8
(Row 0, Column 3): value = 3, address = 0x555d6a0e92ac
(Row 0, Column 4): value = 4, address = 0x555d6a0e92b0
Row 1: value: 0x555d6a0e92b4, address = 0x555d6a0e92b4
(Row 1, Column 0): value = 10, address = 0x555d6a0e92b4
(Row 1, Column 1): value = 11, address = 0x555d6a0e92b8
(Row 1, Column 2): value = 12, address = 0x555d6a0e92bc
(Row 1, Column 3): value = 13, address = 0x555d6a0e92c0
(Row 1, Column 4): value = 14, address = 0x555d6a0e92c4
Row 2: value: 0x555d6a0e92c8, address = 0x555d6a0e92c8
(Row 2, Column 0): value = 20, address = 0x555d6a0e92c8
(Row 2, Column 1): value = 21, address = 0x555d6a0e92cc
(Row 2, Column 2): value = 22, address = 0x555d6a0e92d0
(Row 2, Column 3): value = 23, address = 0x555d6a0e92d4
(Row 2, Column 4): value = 24, address = 0x555d6a0e92d8
parr的作用,是一個指向arr[][],也可以這樣宣告。
const int row = 3, column = 5;
int arr[row][column];
int (*parr)[column] = arr;
留言
張貼留言