Çok Boyutlu Diziler ve Pointer Kullanımı
2D/3D diziler, satır-major düzen ve pointer ile indeks hesabı teknikleri.
C++’ta birden fazla boyut içeren diziler (örneğin matrisler), verileri tablo veya ızgara şeklinde düzenlemeye yarar. Çok boyutlu diziler bellekte ardışık şekilde saklanır ve pointer’larla doğrudan erişilebilir. Bu makalede 2 ve 3 boyutlu dizilerle pointer ilişkisini, erişim tekniklerini ve dinamik matris oluşturmayı öğreneceğiz.
1. İki Boyutlu (2D) Diziler
İki boyutlu diziler genellikle satır-sütun (row-column) şeklinde düşünülür. Aşağıdaki örnek 2 satır × 3 sütunluk bir matrisi tanımlar:
#include <iostream>
using namespace std;
int main() {
int matris[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
cout << matris[0][1] << endl; // 2
cout << matris[1][2] << endl; // 6
}
Bu örnekte matris[0][1], 0. satırın 1. sütunundaki değeri temsil eder.
C++ dizileri 0’dan başladığı için [1][2] aslında 2. satırın 3. sütunudur.
2. Bellekte Saklanma Şekli
C++ çok boyutlu dizileri bellekte row-major order biçiminde saklar. Yani her satır, bellekte ardışık olarak yer alır:
Bellek düzeni:
matris[0][0], matris[0][1], matris[0][2],
matris[1][0], matris[1][1], matris[1][2]
Bu nedenle pointer aritmetiği ile tüm elemanlara tek boyutlu gibi erişmek mümkündür.
3. Pointer ile 2D Dizi Elemanlarına Erişim
Çok boyutlu diziler aslında bir pointer zinciridir.
Örneğin int matris[2][3] ifadesinde matris, bir int[3] dizisinin adresini tutar.
#include <iostream>
using namespace std;
int main() {
int matris[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
cout << *(*(matris + 0) + 1) << endl; // 2
cout << *(*(matris + 1) + 2) << endl; // 6
}
matris→ ilk satırın adresini gösterir.*(matris + 1)→ ikinci satırın adresine gider.*(*(matris + 1) + 2)→ 2. satırın 3. sütunundaki değeri getirir.
4. Pointer ile Döngü Üzerinden Erişim
Matris elemanlarını pointer aritmetiğiyle gezmek mümkündür.
int matris[2][3] = {{10,20,30},{40,50,60}};
int *ptr = &matris[0][0];
for (int i = 0; i < 6; i++) {
cout << *(ptr + i) << " ";
}
Çıktı:
10 20 30 40 50 60
Görüldüğü gibi 2D dizi bellekte tek bir blok halinde saklandığı için düz bir pointer ile tüm elemanlara ulaşmak mümkündür.
5. Fonksiyonlara Çok Boyutlu Dizi Göndermek
2D diziler fonksiyonlara parametre olarak gönderilebilir. Ancak C++’ta ikinci boyutun (sütun sayısı) belirtilmesi gerekir.
void Yazdir(int dizi[][3], int satir) {
for (int i = 0; i < satir; i++) {
for (int j = 0; j < 3; j++) {
cout << dizi[i][j] << " ";
}
cout << endl;
}
}
int main() {
int matris[2][3] = {{1,2,3},{4,5,6}};
Yazdir(matris, 2);
}
Alternatif olarak pointer sözdizimi kullanılabilir:
void Yazdir(int (*p)[3], int satir) {
for (int i = 0; i < satir; i++)
for (int j = 0; j < 3; j++)
cout << p[i][j] << " ";
}
Burada int (*p)[3] → “3 elemanlı int dizisine işaret eden pointer” anlamına gelir.
6. Üç Boyutlu (3D) Diziler
Üç boyutlu diziler, 2D dizilerin bir koleksiyonudur.
Yani int uzay[2][3][4] yapısı, 2 adet 3x4 boyutlu matristen oluşur.
#include <iostream>
using namespace std;
int main() {
int uzay[2][3][4] = {
{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} },
{ {13,14,15,16}, {17,18,19,20}, {21,22,23,24} }
};
cout << uzay[1][2][3] << endl; // 24
}
3D diziler genellikle grafik işlemleri, oyun motorları ve bilimsel hesaplamalarda kullanılır.
7. Dinamik 2D Dizi (Matris) Oluşturma
Boyutu çalışma zamanında belli olmayan matrisleri dinamik olarak oluşturmak için
new operatörüyle pointer dizileri kullanılabilir.
#include <iostream>
using namespace std;
int main() {
int satir = 2, sutun = 3;
int **matris = new int*[satir]; // Satır pointer dizisi
for (int i = 0; i < satir; i++)
matris[i] = new int[sutun]; // Her satır için dizi oluştur
// Değer atama
for (int i = 0; i < satir; i++)
for (int j = 0; j < sutun; j++)
matris[i][j] = (i+1)*(j+1);
// Yazdırma
for (int i = 0; i < satir; i++) {
for (int j = 0; j < sutun; j++)
cout << matris[i][j] << " ";
cout << endl;
}
// Belleği serbest bırakma
for (int i = 0; i < satir; i++)
delete[] matris[i];
delete[] matris;
}
Bu yöntemle matris boyutu kullanıcıdan alınarak dinamik olarak belirlenebilir.
Ancak unutulmamalıdır: her new[] için mutlaka bir delete[] gerekir.
8. Modern Alternatif: std::vector<vector<int>>
C++’ta dinamik matris oluşturmanın en güvenli ve kolay yolu std::vector kullanmaktır.
#include <iostream>
#include <vector>
using namespace std;
int main() {
int satir = 2, sutun = 3;
vector<vector<int>> matris(satir, vector<int>(sutun));
for (int i = 0; i < satir; i++)
for (int j = 0; j < sutun; j++)
matris[i][j] = (i+1) + (j+1);
for (auto &satir : matris) {
for (int deger : satir)
cout << deger << " ";
cout << endl;
}
}
std::vector otomatik bellek yönetimi sağlar,
delete[] veya new gerektirmez ve boyutu kolayca değiştirilebilir.
9. TL;DR
- 2D diziler bellekte satır satır (row-major order) saklanır.
*(matris + i) + j→matris[i][j]ile eşdeğerdir.- Fonksiyon parametresinde ikinci boyut mutlaka belirtilmelidir.
- 3D diziler, 2D dizilerin kümesidir:
int uzay[2][3][4]. - Dinamik matrisler
new/delete[]ile oluşturulabilir. - Modern C++’ta
std::vector<vector<>>önerilir. - Tüm örnekler Visual Studio 2022 veya GCC 11+ derleyicilerinde çalıştırılabilir.