Menguasai Pointer dan Array Multidimensi di C
Dalam bahasa C, array adalah kumpulan nilai dengan tipe serupa yang disimpan di lokasi memori berkelanjutan. Setiap elemen dalam array (satu dimensi atau multidimensi) diidentifikasi oleh satu atau lebih indeks bilangan bulat unik.
Sebaliknya, pointer menyimpan alamat suatu variabel. Alamat elemen ke-0 dalam array adalah penunjuk array. Anda dapat menggunakan "operator dereferensi" untuk mengakses nilai yang dirujuk oleh penunjuk.
Anda dapat mendeklarasikan array satu dimensi, dua dimensi, atau multidimensi dalam C. Istilah "dimensi" mengacu pada jumlah indeks yang diperlukan untuk mengidentifikasi elemen dalam koleksi.
Pointer dan Array Satu Dimensi
Dalam array satu dimensi, setiap elemen diidentifikasi dengan satu bilangan bulat:
int a[5] = {1, 2, 3, 4, 5};
Di sini, angka “1” berada pada indeks ke-0, “2” pada indeks 1, dan seterusnya.
Variabel yang menyimpan alamat elemen ke-0 adalah penunjuknya −
int *x = &a[0];
Sederhananya, nama array juga menunjuk ke alamat elemen ke-0. Jadi, Anda juga bisa menggunakan ungkapan ini −
int *x = a;
Contoh
Karena nilai penunjuk bertambah berdasarkan ukuran tipe data, "x++" memindahkan penunjuk ke elemen berikutnya dalam larik.
#include <stdio.h>
int main(){
int arr[] = {1, 2, 3, 4, 5};
int length = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int *ptr = arr;
while (i < length){
printf("arr[%d]: %d \n", i, *(ptr + i));
i++;
}
return 0;
}
Keluaran
Saat Anda menjalankan kode ini, ini akan menghasilkan keluaran berikut −
arr[0]: 1
arr[1]: 2
arr[2]: 3
arr[3]: 4
arr[4]: 5
Pointer dan Array Dua Dimensi
Jika array satu dimensi diibaratkan sebagai daftar elemen, maka array dua dimensi diibaratkan seperti tabel atau matriks.
Elemen-elemen dalam array 2D dapat dianggap tersusun secara logis dalam baris dan kolom. Oleh karena itu, lokasi suatu elemen ditentukan oleh dua indeks, nomor baris dan nomor kolomnya. Indeks baris dan kolom dimulai dari "0".
int arr[2][2];
Array seperti itu direpresentasikan sebagai −
| Kolom0 | Kol1 | Kol2 | Baris0arr[0][0]arr[0][1]arr[0][2]Baris1arr[1][0]arr[1][1]arr[1][2]Baris2arr[2][0]arr[2][1]arr[2][2]
Perlu dicatat bahwa susunan tabel hanyalah representasi logis. Kompiler mengalokasikan satu blok byte kontinu. Di C, alokasi array dilakukan dengan cara baris-mayor, yang berarti elemen-elemen dibaca ke dalam array secara baris-bijaksana.
Di sini, kita mendeklarasikan array 2D dengan tiga baris dan empat kolom (angka dalam tanda kurung siku pertama selalu mengacu pada jumlah baris) sebagai −
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Kompiler akan mengalokasikan memori untuk array 2D di atas dalam urutan baris. Dengan asumsi bahwa elemen pertama array berada di alamat 1000 dan ukuran tipe "int" adalah 4 byte, elemen array akan mendapatkan lokasi memori yang dialokasikan berikut ini −
| Baris 0 | Baris 1 | Baris 2 | Nilai123456789101112Alamat100010041008101210161020102410281032103610401044
Kami akan menetapkan alamat elemen pertama array num ke pointer ptr menggunakan alamat operator &.
int *ptr = &arr[0][0];
Contoh 1
Jika penunjuk bertambah 1, ia berpindah ke alamat berikutnya. Semua 12 elemen dalam array "34" dapat diakses dalam satu loop sebagai berikut −
#include <stdio.h>
int main(){
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
// pointer ptr pointing at array num
int *ptr = &arr[0][0];
int i, j, k = 0;
// print the elements of the array num via pointer ptr
for (i = 0; i < 3; i++){
for (j = 0; j < 4; j++){
printf("%d ", *(ptr + k));
k++;
}
printf("\n");
}
return 0;
}
Keluaran
Saat Anda menjalankan kode ini, ini akan menghasilkan keluaran berikut −
1 2 3 4
5 6 7 8
9 10 11 12
Secara umum, alamat setiap elemen array menggunakan rumus berikut −
add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]
Dalam array 34 kami,
add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044
Anda dapat merujuk ke gambar di atas dan ini mengonfirmasi bahwa alamat "arr[3][4]" adalah 1044.
Contoh 2
Gunakan penunjuk dereferensi untuk mengambil nilai di alamat. Mari kita gunakan rumus ini untuk melintasi array dengan bantuan penunjuknya −
#include <stdio.h>
int main(){
// 2d array
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int ROWS = 3, COLS = 4;
int i, j;
// pointer
int *ptr = &arr[0][0];
// print the element of the array via pointer ptr
for (i = 0; i < ROWS; i++){
for (j = 0; j < COLS; j++) {
printf("%4d ",*(ptr + (i * COLS + j)));
}
printf("\n");
}
return 0;
}
Keluaran
Saat Anda menjalankan kode ini, ini akan menghasilkan keluaran berikut −
1 2 3 4
5 6 7 8
9 10 11 12
Pointer dan Array Tiga Dimensi
Array tiga dimensi adalah array yang terdiri dari array dua dimensi. Array seperti itu dideklarasikan dengan tiga subskrip −
int arr [x] [y] [j];
Array ini dapat dianggap sebagai jumlah lapisan tabel "x", setiap tabel memiliki jumlah baris "x" dan jumlah kolom "y".
Contoh array 3D adalah −
int arr[3][3][3] ={
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
Pointer ke array 3D dapat dideklarasikan sebagai −
int * ptr = &arr[0][0][0];
Mengetahui bahwa nama array itu sendiri adalah alamat elemen ke-0, kita dapat menulis pointer array 3D sebagai −
int * ptr = arr;
Setiap lapisan baris "x" dan kolom "y" menempati −
x * y * sizeof(data_type)
Jumlah byte. Dengan asumsi memori yang dialokasikan ke array 3D "arr" seperti yang dideklarasikan di atas dimulai dari alamat 1000, lapisan kedua (dengan "i =1") dimulai pada posisi 1000 + (3 3) 4 =1036 byte.
ptr = Base address of 3D array arr
Jika JMAX adalah jumlah baris dan KMAX adalah jumlah kolom, maka alamat elemen pada baris ke-0 dan kolom ke-0 pada irisan ke-1 adalah −
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
Rumus untuk mendapatkan nilai suatu elemen pada baris ke-j dan kolom ke-k pada irisan ke-i dapat diberikan sebagai −
arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
Contoh:Mencetak Array 3D menggunakan Pointer Dereferencing
Mari kita gunakan rumus ini untuk mencetak array 3D dengan bantuan dereferensi penunjuk −
#include <stdio.h>
int main(){
int i, j, k;
int arr[3][3][3] = {
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};
int JMAX = 3, KMAX = 3;
int *ptr = arr; // &arr[0][0][0];
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
for(k = 0; k < 3; k++){
printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));
}
printf("\n");
}
printf("\n");
}
return 0;
}
Keluaran
Saat Anda menjalankan kode ini, ini akan menghasilkan keluaran berikut −
11 12 13
14 15 16
17 18 19
21 22 23
24 25 26
27 28 29
31 32 33
34 35 36
37 38 39
Secara umum, mengakses array dengan pointer sangat mirip dengan mengakses array dengan representasi subskrip. Perbedaan utama antara keduanya adalah bahwa deklarasi subskrip dari sebuah array mengalokasikan memori secara statis, sedangkan kita dapat menggunakan pointer untuk alokasi memori dinamis.
Untuk meneruskan array multidimensi ke suatu fungsi, Anda perlu menggunakan pointer, bukan subskrip. Namun, menggunakan array subskrip lebih nyaman dibandingkan menggunakan pointer, yang mungkin sulit bagi pelajar baru.