You are on page 1of 22

Programlamaya Giriş

ve Algoritmalar

Araş. Gör. Dr. Yasemin POYRAZ KOÇAK

E-mail :yasemin.poyraz@iuc.edu.tr
ÇOK BOYUTLU DİZİLER
iki ya da daha çok boyuta sahip diziler tanımlanabilir:

• Aşağıdaki bildirimde a dizisi 3 boyutlu bir dizidir.

int a[5][10][20];

• m dizisi 2 boyutlu bir dizidir.

int m[5][10];

Uygulamalarda daha çok kullanılan 2 boyutlu dizilerdir. 2 boyutlu diziler matris olarak da
isimlendirilir.

Matrisler

İki boyutlu bir dizi aslında belirli bir boyuttaki tek boyutlu dizilerin dizisi olarak ele alınır:

int a[5][10];

– a dizisi her elemanı 10 elemanlı int türden bir dizi olan 5 elemanlı bir dizidir.
– a dizisinin gerçekte boyutu 5' tir.
– İkinci köşeli ayraç içinde yer alan 10 ifadesi a dizisinin elemanları olan dizilerin boyutudur.
Aşağıdaki programı inceleyin. Bu programda bir matriste yer alan tüm elemanlara 0-
100 aralığında rastgele değerler veriliyor. Daha sonra matriste yer alan tüm
elemanların değeri ekrana yazdırılıyor:

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

int main()
{
int a[5][10];
int i, k
srand(time(0));

for (i = 0; i < 5; ++i)


for (k = 0; k < 10; ++k)
a[i][k] = rand() % 100;
for (i = 0; i < 5; ++i) {
for (k = 0; k < 10; ++k)
printf("%2d ", a[i][k]);
printf("\n");
}
return 0;
}
• ptr = &a[0][0]: int * türünden ptr nesnesine matris içinde yer alan ilk int türden nesnenin adresi atanır.
• i değişkenine ROW * COL ifadesinin değeri, yani matriste yer alan toplam eleman sayısı atanmıştır.
• Bu durumda while (i--) döngüsü matrisin eleman sayısı kadar döner.
• Döngünün gövdesinde yer alan printf çağrısı ile döngünün her turunda *ptr nesnesinin değeri yazdırılmış.
• ++ işleci ile göstericinin değeri 1 artırılarak bellekte bir sonraki nesneyi göstermesi sağlanmıştır.
• İki boyutlu dizinin elemanları aslında belleğe ardışıl olarak yerleştirilen tek boyutlu dizilerdir.

int main()
{
int a[5][10L];
int i, k;
int *ptr;
srand(time(0));
for (i = 0; i < 5; ++i)
for (k = 0; k < 10; ++k)
a[i][k] = rand() % 100;
for (i = 0; i < 5; ++i) {
for (k = 0; k < 10; ++k)
printf("%2d ", a[i][k]);
printf("\n");
}
ptr = &a[0][0];
i = 5 * 10;
while (i--)
printf("%2d ", *ptr++);
printf("\n");
return 0;
}
İLK DEĞER ATAMASI
Örneğin iki boyutlu bir dizi

int B[2][2] ={{1,2},{3,4}};

Biçiminde bildirilip değerler atanabilir.

• Değerler parantezler içinde satırlara göre gruplandırılmıştır.

B[0][0] = 1;
B[0][1] = 2;
B[1][0] = 3;
B[1][1] = 4;

int B[2][2] ={{1},{3,4}};

• Eğer satır içinde yeterince atama değeri yoksa, satırda kalan diğer elemanlara 0 atanır.

B[0][0] = 1;
B[0][1] = 0;
B[1][0] = 3;
B[1][1] = 4;
3 Adet 2 boyutlu dizinin elemanlarını satır satır ekrana yazdıran kod.

#include<stdio.h>

int main()
{
int dizi1[2][3]={{1,2,3},{4,5,6}};
int dizi2[2][3]={1,2,3,4,5,6};
int dizi3[2][3]={{1,2},{4}};

printf("Satir satir dizi1 elemanlari\n");


diziyiYazdir(dizi1);

printf("Satir satir dizi2 elemanlari\n");


diziyiYazdir(dizi2);

printf("Satir satir dizi3 elemanlari\n");


diziyiYazdir(dizi3);

return 0;
}
void diziyiYazdir(int a[][3])
{
int i,j;
for(i=0; i<=1;i++){
for(j=0; j<=2; j++)
printf("%d", a[i][j]);
printf("\n");

}
}
• İki boyutlu dizilere verilen ilk değerler sırasıyla iki boyutlu dizinin elemanı olan tek boyutlu dizilerin elemanlarına atanır.

#include <stdio.h>
int main()
{
int a[3][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int i, k;
for (i = 0; i < 3; ++i) {
for (k = 0; k < 5; ++k)
printf("%2d ", a[i][k]);
printf("\n");
}
return 0;
}

• İlk değerleri bloğun içinde içsel bloklar kullanılarak verilebilir. İlk değer verilmeyen elemanlara otomatik olarak 0 değeri atanır.

#include <stdio.h>
int main()
{
int a[3][5] = { {1, 2}, {3, 4, 5}, {6, 7, 8, 9}};
int i, k;
for (i = 0; i < 3; ++i) {
for (k = 0; k < 5; ++k)
printf("%2d ", a[i][k]);
printf("\n");
}
return 0;
}
int main(){
int a[3][3], b[3][3],c[3][3]={0,0,0,0,0,0,0,0,0}; Ekrandan aldığı matrisler ile kullanıcının tercihine
int i,j,k, secim=0; göre toplama çıkarma ve çarpma işlemi yapıyor.
printf("a matrisini giriyorsunuz\n");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scanf("%d", &a[i][j]);
printf("b matrisini giriyorsunuz\n");
for(i=0;i<3;i++)
for(j=0;j<3;j++)
scanf("%d", &b[i][j]);
printf(" 1- Toplama islemi\n");
printf(" 2- Cikarma islemi\n");
printf(" 3- Carpma islemi\n");
scanf("%d", &secim);
if(secim == 1)
for(i=0;i<3;i++)
for(j=0;j<3;j++)
c[i][j]=a[i][j]+b[i][j];
if(secim == 2)
for(i=0;i<3;i++)
for(j=0;j<3;j++)
c[i][j]=a[i][j]-b[i][j];
if(secim == 3)
for(i=0;i<3;i++)
for(j=0;j<3;j++)
for(k=0;k<3;k++)
c[i][j]+=a[i][k]+b[k][j];
for(i=0;i<3;i++){
for(j=0;j<3;j++)
printf("%d \t", c[i][j]);
printf("\n");
}
return 0;
#include <stdio.h>

int main()
{
int a[10][10];
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
printf("* ");
printf("\n");
}

return 0;
}
#include <stdio.h>

int main()
{
int a[10][10];
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<i+1;j++)
printf("* ");
printf("\n");
}

return 0;
}
#include <stdio.h>

int main()
{
int a[10][10];
int i,j,k;
for(i=0;i<10;i++)
{
for(j=0;j<10-i;j++)
printf(" ");
for(k=0;k<i+1;k++)
printf(" *");
printf("\n");
}

return 0;
}
ÖDEV
char Türden İki Boyutlu Diziler
Nasıl bir yazı char türden bir dizinin içinde tutulabiliyor ise, mantıksal bir ilişki içindeki n tane yazı iki boyutlu bir dizi içinde
tutulabilir:
char kelimeler[10][50];
Yukarıda tanımlanan kelimeler isimli dizinin 10 elemanı vardır. kelimeler isimli dizinin her bir elemanı char türden 50 elemanlı
dizidir. kelimeler dizisinin içinde uzunluğu 49 karakteri geçmeyen, 10 tane yazı tutulabilir. kelimeler[3] Bu yazılardan
dördüncüsünün adresi kelimeler[6][2] Bu yazılardan yedincisinin üçüncü karakteridir.
Aşağıdaki programı inceleyin:

#include <stdio.h>
#include <string.h>

int main()
{
char *isimlerdizisi[10] = {"Ali", "Veli", "Hasan", "Necati", "Deniz", "Kaan", "Selami","Salah", "Nejla", "Figen"};
char isimler[10][20];
int k;
for (k = 0; k < 10; ++k)
strcpy(isimler[k], isimlerdizisi[k]);
for (k = 0; k < 10; ++k)
printf("(%s) ", isimler[k]);
printf("\n");
for (k = 0; k < 10; ++k)
strrev(isimler[k]);
for (k = 0; k < 10; ++k)
printf("(%s) ", isimler[k]);
printf("\n");
return 0;
}
main işlevi içinde iki boyutlu isimler isimli bir dizi tanımlanıyor.

char isimler[10][20];

Bu dizi içinde uzunluğu en fazla 19 karakter olabilecek 10 kere isim tutulabilir, değil mi?

for (k = 0; k < 10; ++k)


strcpy(isimler[k], isimlerdizisi[k]);

döngü deyimiyle isimlerdizisi isimli bir gösterici dizisinin elemanlarının gösterdiği isimler, iki boyutlu
isimler dizisinin elemanı olan char türden dizilere standart strcpy işleviyle kopyalanıyor. Aşağıdaki
döngü deyimiyle her bir isim ekrana yazdırılıyor:

for (k = 0; k < 10; ++k)


printf("(%s) ", isimler[k]);

Aşağıdaki döngü deyimi ile standart olmayan strrev isimli işleve yapılan çağrılarla, iki boyutlu dizi
içinde tutulan isimlerin hepsi ters çevriliyor:

for (k = 0; k < 10; ++k)


strrev(isimler[k]);
char Türden İki Boyutlu Dizilere İlk değer
Verilmesi
char türden bir diziye çift tırnak içinde yer alan karakterlerle ilk değer verilebileceğine
göre iki boyutlu bir dizinin elemanları olan char türden tek boyutlu dizinin elemanlarına
da benzer şekilde ilk değer verilebilir:

char isimler[5][10] = {"Ali", "Veli", "Hasan", "Tuncay", "Deniz"};

Yukarıda, isimler isimli iki boyutlu dizinin elemanı olan 10 elemanlı char türden dizilere,
çift tırnak içinde yer alan yazılarla ilk değer veriliyor.

Şimdi de iki boyutlu char türden bir dizi üzerinde işlem yapacak bazı işlevler:

• swap_str işlevi adreslerini aldığı iki yazıyı takas ediyor. isimleriyaz isimli işlev ise
başlangıç adresini ve boyutunu aldığı iki boyutlu dizide yer alan isimleri ekrana
yazdırıyor.

• isimleriSirala isimli işlev ise başlangıç adresini ve boyutunu aldığı iki boyutlu dizi içinde
tutulan isimleri küçükten büyüğe doğru sıralıyor.
#include <stdio.h>
#include <string.h>

void swap_str(char *p1, char *p2)


{
char temp[20];
strcpy(temp, p1);
strcpy(p1, p2);
strcpy(p2, temp);
}
void isimleriSirala(char ptr[][20], int size)
{
int i, k;
for (i = 0; i < size - 1; ++i)
for (k = 0; k < size - 1 - i; ++k)
if (strcmp(ptr[k], ptr[k + 1]) > 0)
swap_str(ptr[k], ptr[k + 1]);
}
void isimleriYaz(const char ptr[][20], int size)
{
int i;
for (i = 0; i < size; ++i)
printf("(%s) ", ptr[i]);
printf("\n");
}
int main()
{
char isimler [20][20] = {"Ali", "Veli", "Hasan", "Necati", "Deniz", "Kaan", "Selami","Salah", "Nejla", "Huseyin",
"Derya", "Funda", "Kemal", "Burak", "Burcu", "Ozlem", "Nuri", "Metin", "Guray", "Anil"};
isimleriYaz(isimler, 20);
isimleriSirala(isimler, 20);
isimleriYaz(isimler, 20);
return 0;
}
char * Türden Diziyle char Türden İki
Boyutlu Dizi Arasındaki Farklar
Mantıksal ilişki içinde n tane yazı, bir gösterici dizisi yardımıyla tutulabileceği gibi iki boyutlu bir dizi içinde de
tutulabilir:

char *pisimler[10] = {"Ali", "Veli", "Hasan", "Deniz", "Ferda", "Murat", "Ayca", "Erdem", "Kaan", "Gurbuz"};
char isimler [10][20] = {"Ali", "Veli", "Hasan", "Deniz", "Ferda", "Murat", "Ayca", "Erdem", "Kaan", "Gurbuz"};

Elemanları dizgeleri gösteren bir gösterici dizisinin elemanları, yalnızca okuma amacıyla kullanılabilecek
yazıların başlangıç adreslerini tutar.

Dizgelerin yalnızca okuma amacıyla kullanılabilecek yazılardır.

Yukarıdaki örnekte, pisimler dizisinin elemanı olan göstericilerin gösterdiği yazılar üzerinde değişiklik yapmak,
doğru değildir. Ancak isimler dizisi içinde yer alan isimler istenirse değiştirilebilir.

#include <string.h>
int main()
{
int k;
for (k = 0; k < 10; ++k) {
strrev(pisimler[k]); /* Yanlış */
strrev(isimler[k]); /* Yanlış değil*/
}
return 0;
}
Dinamik Bellek Yönetimi
• Şimdiye kadar yazdığımız programlarda kaç eleman olacağı önceden belliydi. Yani sınıf
listesiyle ilgili bir program yazacaksak, sınıfın kaç kişi olduğunu biliyormuşuz gibi
davranıyorduk.

• Programın en başında kaç elemanlık alana ihtiyacımız varsa, o kadar yer ayırıyorduk.

• Ama bu gerçek dünyada karşımıza çıkacak problemler için yeterli bir yaklaşım değildir.

• Örneğin bir sınıfta 100 öğrenci varken, diğer bir sınıfta 50 öğrenci olabilir ve siz her
ortamda çalışsın diye 200 kişilik bir üst sınır koyamazsınız.

• Bu, hem hafızanın verimsiz kullanılmasına yol açar; hem de karma eğitimlerin yapıldığı
bazı fakültelerde sayı yetmeyebilir.

• Statik bir şekilde dizi tanımlayarak bu sorunların üstesinden gelemezsiniz.

• Çözüm dinamik bellek yönetimindedir.

• Dinamik bellek yönetiminde, dizilerin boyutları önceden belirlenmez. Program akışında


dizi boyutunu ayarlarız ve gereken bellek miktarı, program çalışırken tahsis edilir.
• Dinamik bellek tahsisi için calloc( ) ve malloc( ) olmak üzere iki önemli fonksiyonları vardır.

• Bellekte yer ayrılmasını bu fonksiyonlarla sağlarız.

• Her iki fonksiyon da stdlib kütüphanesinde bulunur.

• Fonksiyonlardan herhangi birini kullanacağınız zaman:

#include<stdlib.h> yazılması gerekir.

• calloc( ) fonksiyonu aşağıdaki gibi kullanılır:

isaretci_adi = calloc( eleman_sayisi, her_elemanin_boyutu );

• calloc( ) fonksiyonu eleman sayısını, eleman boyutuyla çarparak hafızada gereken bellek alanını ayırır.

• Dinamik oluşturduğunuz dizi içersindeki her elemana, otomatik olarak ilk değer 0 atanır.

• malloc( ) fonksiyonu, calloc( ) gibi dinamik bellek ayrımı için kullanılır.

• calloc( ) fonksiyonundan farklı olarak ilk değer ataması yapmaz. Kullanımıysa aşağıdaki gibidir:

isaretci_adi = malloc( eleman_sayisi * her_elemanin_boyutu );


Yazdığınız programların bir süre sonra bilgisayar belleğini korkunç bir şekilde işgal etmesini istemiyorsanız,
free() fonksiyonunu kullanmanız gerekmektedir.

Bunun için calloc() fonksiyonuyla tahsis ettiğiniz alanı, işiniz bittikten sonra free( ) fonksiyonuyla
boşaltmanız yeterlidir.

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

int main()
{
// Dinamik bir dizi yaratmak icin pointer kullaniriz.
int *dizi;
int eleman_sayisi;
int i;

printf( "Eleman sayısını giriniz> ");


scanf( "%d", &eleman_sayisi );
dizi = calloc( eleman_sayisi, sizeof( int ) );

for( i = 0; i < eleman_sayisi; i++ )


printf( "%d\n", dizi[i]);
free( dizi );
return 0;
}
Az evvel calloc( ) ile yazdığımız programın aynısını şimdi de malloc( ) fonksiyonunu kullanarak yazalım:

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

int main()
{
int *dizi;
int eleman_sayisi;
int i; printf( "Eleman sayısını giriniz> ");
scanf( "%d", &eleman_sayisi );
dizi = malloc( eleman_sayisi * sizeof( int ) );
for( i = 0; i < eleman_sayisi; i++ )
printf( "%d\n", dizi[i] );
free( dizi );
return 0;
}

Hafıza alanı ayırırken bazen bir problem çıkabilir. Örneğin bellekte yeterli alan olmayabilir ya da benzeri
bir sıkıntı olmuştur.

Bu tarz problemlerin sık olacağını düşünmeyin. Ancak hafızanın gerçekten ayrılıp ayrılmadığını kontrol
edip, işinizi garantiye almak isterseniz, aşağıdaki yöntemi kullanabilirsiniz:

dizi = calloc( eleman_sayisi, sizeof( int ) );


if( dizi == NULL )
printf( "Yetersiz bellek!\n" );
KİTAP ÖNERİSİ
1- Bilgisayarda Temel Algoritmalar ve C++ Dili ile Programlama Örne
Mithat Uysal - Nirvana Yayınları

2- Algoritma ve Programlama Mantığı - H. Burak Tungut


H. Burak Tungut – Kodlab

3- Algoritma Geliştirme ve Programlamaya Giriş - Fahri Vatansever


Fahri Vatansever - Seçkin Yayıncılık

4- C ve Sistem Programcıları Derneği - C Ders Notları - Necati Ergin

You might also like