C++

C Programlama Dersi – XIV

Yeni Değişken Tipi Oluşturma

Kullandığımız birçok değişken tipi oldu. Tam sayıları, karakterleri, virgüllü sayıları, katarları gördük. Ancak kullanabileceğimiz değişken tipleri bunlarla sınırlı değildir. Kendi değişken tiplerimizi, yaratabiliriz. Örneğin boolean diye yeni bir tip yaratarak, bunun alabileceği değerleri true ve false olarak belirleyebiliriz; üçüncü bir ihtimal olmaz. Ya da mevsimler diye bir değişken tipi belirleyip, alabileceği değerleri aylar olarak kısıtlayabiliriz. İşte bu tarz işlemleri yapmak için enum kullanılır. enum kelimesi, enumerator yani ‘sayıcı‘, ‘numaralandırmacı‘dan gelmektedir.

Hayat, rakamlarla ifade edilebilir. Bunun en bariz uygulamalarını programlama yaparken görürsünüz. Bir karakter olan A harfi, ASCII Tablo’da 65 sayısına denk düşer; büyük B harfiyse 66’dır ve bu böyle devam eder. Bilgisayarınız işaretlerden, sembollerden, karakterlerden anlamaz. Onun için tek gerçeklik sayılardır. İşte enum bu felsefeye hizmet ediyor. Örneğin doğruyu göstermek için 1, yanlış içinse 0’ı seçersek; yeni bir değişken tipi belirlemiş oluruz. Bilgisayar doğrunun ya da yanlışın ne olduğunu bilmez, onun için sadece 0 ve 1 vardır. Ancak insanların yararına, okunurluğu artan programlar ortaya çıkar. İsterseniz, boolean diye tabir ettiğimiz değişken tipini oluşturalım:

#include<stdio.h>
int main( void )
{
	// Degisken tipinin nasil olacagini tanimliyoruz
	enum boolean {
		false = 0,
		true = 1
	};
	// Simdi de 'dogru_mu' adinda bir degisken
	// tanimliyoruz
	enum boolean dogru_mu;
	// Tanimladigimiz 'dogru_mu' degiskenine
	// deger atayip, bir alt satirda da
	// kontrol yapiyoruz.
	dogru_mu = true;
	if( dogru_mu == true )
		printf( "Doğru\n" );
	return 0;
}

Daha önce boolean diye bir veri tipi bulunmuyordu. Şimdiyse, iki farklı değeri olabilen, doğru ve yanlışları göstermekte kullanabileceğimiz yeni bir değişken tipi oluşturduk. Yanlışı göstermek için 0; doğruyu ifade etmek içinse 1 rakamları kullandık. Yanlışın ve doğrunun karşılığını belirtmemiz gerekmiyordu; boolean veri tipini tanımlarken, 0 ve 1 yazmadan sadece false ya da true da yazabilirdik. Programınız derlenirken, karşılık girilmeyen değerlere sırayla değer atanmaktadır. İlla ki sizin bir eşitlik oluşturmanız gerekmez. Mesela üç ana rengi ( Kırmızı, Sarı ve Mavi )alabilecek ana_renkler veri tipini oluşturalım:

#include<stdio.h>
int main( void )
{
	// Degisken tipinin nasil olacagini tanimliyoruz
	enum ana_renkler {
		Kirmizi,
		Mavi,
		Sari
	};

	// Degiskeni tanimliyoruz.
	enum ana_renkler piksel;

	// Degisken degerini Mavi olarak belirliyoruz.
	// Dilersek Sari ve Kirmizi da girebiliriz.
	piksel = Mavi;

	// Degisken degeri karsilastiriliyor.
	if( piksel == Kirmizi )
		printf( "Kırmızı piksel\n" );
	else if( piksel == Mavi )
		printf( "Mavi piksel\n" );
	else
		printf( "Sarı piksel\n" );
	return 0;
}

Kirmizi, Mavi ya da Sari’nin nümerik değerini bilmiyoruz; muhtemelen birden başlamış ve sırayla üçe kadar devam etmişlerdir. Değerlerin nümerik karşılığını bilmesek bile, bu onlarla işlem yapmamızı engellemiyor. Bir önceki örnekte olduğu gibi rahatça kullanabiliyoruz.

Oluşturduğumuz yeni veri tiplerinden, değişken tanımlarken her defasında enum koyduğumuzu görmüşsünüzdür. Bunu defalarca yazmak yerine iki alternatif biçim bulunuyor. Birincisi yeni veri tipini oluştururken, değişkeni tanımlamak şeklinde… boolean örneğimize geri dönüp, farklı şekilde nasıl tanımlama yapabileceğimizi görelim:

#include<stdio.h>
int main( void )
{
	// Yeni veri tipini olusturuyoruz
	// Ayrica yeni veri tipinden,
	// bir degisken tanimliyoruz.
	enum boolean {
		false = 0,
		true = 1
	} dogru_mu;

	dogru_mu = true;
	if( dogru_mu == true )
		printf( "Doğru\n" );
	return 0;
}

Yukarda gördüğünüz yöntem, yeni veri tipini oluşturduğunuz anda, bu veri tipinden bir değişken tanımlamanızı sağlar. Her seferinde enum yazmanızdan kurtaracak diğer yöntemse, typedefkullanmaktan geçer. typedef kullanımı şu şekildedir:

typedef veri_tipi_eski_adi veri_tipi_yeni_adi

Kullanacağınız typedef ile herhangi bir değişken tipini, bir başka isimle adlandırabilirsiniz. Örneğin yazacağınız “typedef int tam_sayi;” komutuyla, değişken tanımlarken int yerine tam_sayi da yazabilirsiniz. Bunun enum için uygulamasına bakalım:

#include<stdio.h>
int main( void )
{
	// Yeni veri tipini olusturuyoruz
	// Ayrica yeni veri tipinden,
	// bir degisken tanimliyoruz.
	enum boolean {
		false = 0,
		true = 1
	};
	// Alttaki komut sayesinde, boolean
	// veri tipini tek adimda yaratabiliyoruz.
	typedef enum boolean bool;

	bool dogru_mu;

	dogru_mu = true;
	if( dogru_mu == true )
		printf( "Doğru\n" );
	return 0;
}

Özel Değişken Tipleri ve Fonksiyonlar

enum konusu genişletilebilir. Örneğin enum tanımlamasını, global olarak yaparsanız, fonksiyon parametresi olarak kullanabilirsiniz. Çok basit bir fonksiyon oluşturalım. Alacağı değişken bilgisine göre, ekrana ona dair bilgi yazdırılsın:

#include<stdio.h>
// Ay listesini olusturuyoruz. Ocak
// ayi 1 olacak sekilde, aylar sirayla
// numerik degerler aliyor.
enum ay_listesi {
	ocak = 1, subat, mart, nisan,
	mayis, haziran, temmuz, agustos,
	eylul, ekim, kasim, aralik
};
// Degisken tanimlamasini kolaylastirmak
// icin typedef kullaniliyoruz. aylar diyerek
// tanimlama yapmak mumkun hale geliyor.
typedef enum ay_listesi aylar;

void ay_ismini_yazdir( aylar );
int main( void )
{
	// aylar tipinde bir degisken
	// yaratip, 'kasim' degerini atiyoruz.
	aylar bu_ay = kasim;
	// kasim, numerik olarak 11'i ifade edecektir.
	printf( "%d. ay: ", bu_ay );
	// fonksiyonumuzu cagiriyoruz.
	ay_ismini_yazdir( bu_ay );
	return 0;
}
// Kendisine verilen aylar tipindeki degiskene gore
// hangi ayin oldugunu ekrana yazmaktadir.
void ay_ismini_yazdir( aylar ay_adi )
{
	switch( ay_adi ) {
		case ocak: printf( "Ocak\n" );break;
		case subat: printf( "Şubat\n" );break;
		case mart: printf( "Mart\n" );break;
		case nisan: printf( "Nisan\n" );break;
		case mayis: printf( "Mayıs\n" );break;
		case haziran: printf( "Haziran\n" );break;
		case temmuz: printf( "Temmuz\n" );break;
		case agustos: printf( "Ağustos\n" );break;
		case eylul: printf( "Eylül\n" );break;
		case ekim: printf( "Ekim\n" );break;
		case kasim: printf( "Kasım\n" );break;
		case aralik: printf( "Aralık\n" );break;
	}
}

Gördüğünüz gibi enum ile oluşturacağınız özel veri tiplerini fonksiyonlara aktarmak mümkün. enum aracılığı ile yeni bir değişken tipi yaratmak, birçok konuda işinizi basit hâle getirir. Özellikle gruplandırılması/tasnif edilmesi gereken veriler varsa, enum kullanmak yararlıdır. Örnek olması açısından aşağıda enum ile tanımlanmış bazı veri tiplerini bulabilirsiniz:

enum medeni_durum { bekar, evli, dul };
enum medeni_durum ayse = bekar;
enum egitim_durumu { ilkokul, ortaokul, lise, universite, master };
enum egitim_durumu ogrenci;
enum cinsiyet { erkek, kadin };
enum cinsiyet kisi;

Yapılar ( Structures )

Yapılar ( structures ); tam sayı, karakter vb. veri tiplerini gruplayıp, tek bir çatı altında toplar. Bu gruplandırma içinde aynı ya da farklı veri tipinden dilediğiniz sayıda eleman olabilir. Yapılar, nesne tabanlı programlama ( Object Oriented Programming ) dilleri için önemli bir konudur. Eğer Java, C# gibi modern dillerle çalışmayı düşünüyorsanız, bu konuya daha bir önem vermeniz gerekir.

Vakit kaybetmeden bir örnekle konumuza girelim. Doğum günü bilgisi isteyip, bunu ekrana yazdıran bir program oluşturalım:

#include<stdio.h>
int main( void )
{
	struct {
		int yil;
		int ay;
		int gun;
	} dogum_gunu;

	printf( "Doğum gününüzü " );
	printf( "GG-AA-YYYY olarak giriniz> ");
	scanf( "%d-%d-%d", 	&dogum_gunu.gun,
				&dogum_gunu.ay,
				&dogum_gunu.yil );
	printf( "Doğum gününüz: " );
	printf( "%d/%d/%d\n",	dogum_gunu.gun,
				dogum_gunu.ay,
				dogum_gunu.yil );
	return 0;
}

Bir kullanıcının doğum gününü sorup, gün, ay ve yıl bilgilerini üç farklı int değişken içersinde tutabilirdik. Ancak gruplandırmak her zaman daha iyidir. Hem yaptığınız işlerin takibi kolaylaşır, hem de hata yapma riskinizi azaltır. Bunu daha iyi anlatmak için aynı anda sizin ve iki kardeşinizin doğum günlerini soran bir program yazalım:

#include<stdio.h>
int main( void )
{
	struct {
		int yil;
		int ay;
		int gun;
	} siz, kiz_kardes, erkek_kardes;

	printf( "Doğum gününüzü giriniz> ");
	scanf( "%d-%d-%d",	&siz.gun,
				&siz.ay,
				&siz.yil );
	printf( "Kız kardeşiniz> " );
	scanf( "%d-%d-%d", 	&kiz_kardes.gun,
				&kiz_kardes.ay,
				&kiz_kardes.yil );
	printf( "Erkek kardeşiniz> " );
	scanf( "%d-%d-%d", 	&erkek_kardes.gun,
				&erkek_kardes.ay,
				&erkek_kardes.yil );
	return 0;
}

Eğer yapılardan ( structures ) yararlanmasaydık; üç kişinin doğum günü bilgilerini tutmak için toplamda 9 adet farklı değişken tanımlamak gerekecekti. Tanımlama zahmeti bir yana, değişkenlerin karıştırılma ihtimali de ayrı bir sıkıntı yaratacaktı. Sadece üç değişken olarak düşünmeyelim; nüfus cüzdanı bilgilerini soracağımız bir program, yirminin üzerinde değişkene ihtiyaç duyar. Bu kadar çok değişken barındırıp, yapıları kullanmadan hazırlanacak bir programı görmek bile istemezsiniz.

Yapıları kullanmanın bir diğer avantajı, kopyalama konusundadır. Örneğin, sizin bilgilerinizi, erkek kardeşinize kopyalamak için tek yapmanız gereken, “erkek_kardes = siz” yazmaktır. Bu basit işlem ilgili bütün değişkenlerin kopyalamasını yapar.

İç İçe Yapılar

Bir yapı içersine tıpkı bir değişken koyar gibi, bir başka yapı da koyulabilir. Örneğin kullanıcı bilgisi alan bir programda, isim, boy ve doğum tarihi bilgilerini aynı yapı altına toplayabilirsiniz. Ancak doğum tarihi bilgilerini daha alt bir yapı içersinde tutmak yararlı olabilir. Bunu koda dökersek şöyle olur:

#include<stdio.h>
int main( void )
{
	struct {
		char isim[40];
		int boy;
		struct {
			int yil;
			int ay;
			int gun;
		} dogum_bilgileri;
	} kisi;

	printf( "Adınız: " );
	scanf( "%s", kisi.isim );
	printf( "Boyunuz: " );
	scanf( "%d", &kisi.boy );
	printf( "Doğum tarihi: ");
	scanf( "%d-%d-%d", 	&kisi.dogum_bilgileri.gun,
				&kisi.dogum_bilgileri.ay,
				&kisi.dogum_bilgileri.yil );

	printf( "Girilen bilgiler:\n" );
	printf( "İsim: %s\n", kisi.isim );
	printf( "Boy: %d\n", kisi.boy );
	printf( "Doğum tarihi: %d/%d/%d\n", 	kisi.dogum_bilgileri.gun,
						kisi.dogum_bilgileri.ay,
						kisi.dogum_bilgileri.yil );
	return 0;
}

Alt yapıya ulaşmak için nokta kullanıp, ardından yapının adını yazdığımızı görüyorsunuz. Yapıları kullanarak, bir arada durması yararlı olan değişkenleri gruplarız. İç içe yapıları kullanaraksa, bu gruplandırmayı daha da ufak boyutlara indirgemekteyiz. Kısacası her şey, daha derli toplu çalışma için yapılıyor. Yoksa programın temelinde değişen bir şey yok.

Yapı Etiketleri

Yapılara etiket koyabilir ve etiketleri kullanarak ilgili yapıyı temel alan değişkenler tanımlayabilirsiniz. Az evvel yaptığımıza benzer bir örnek yapalım:

#include<stdio.h>
#include<string.h>
int main( void )
{
	// sahis_bilgileri, yapimizin
	// etiketidir.
	struct sahis_bilgileri {
		char isim[40];
		int boy;
	};

	// Yapidan iki adet degisken
	// tanimliyoruz.
	struct sahis_bilgileri kisi_1;
	struct sahis_bilgileri kisi_2;

	// Birinci sahsin bilgilerini
	// kaydediyoruz.
	strcpy( kisi_1.isim, "AHMET" );
	kisi_1.boy = 170;

	// Ikinci sahsin bilgilerini
	// kaydediyoruz.
	strcpy( kisi_2.isim, "MEHMET" );
	kisi_2.boy = 176;

	return 0;
}

Yapıların etiket konarak tanımlanması, daha mantıklıdır. Aksi hâlde sadece yapıyı oluştururken tanımlama yaparsınız. Etiket koyduğunuz zamansa, programın herhangi bir yerinde istediğiniz kadar yapı değişkeni tanımlayabilirsiniz. Önemli bir noktayı belirtmek isterim: yapılarda etiket kullandığınız zaman elinizde sadece bir şablon vardır. O etiketi kullanarak yapıdan bir değişken yaratana kadar, üzerinde işlem yapabileceğiniz bir şey olmaz. Yapı ( structure ) bir kalıptır; bu kalıbın etiketini kullanarak değişken tanımlamanız gerekir.

Yapılarda İlk Değer Atama

Yapılarda da ilk değer ataması yapabilirsiniz. Aşağıdaki örnek etiket kullanmadan oluşturduğunuz yapılarda, ilk değer atamasının nasıl olduğunu göstermektedir. ‘kisi‘ isimli yapı içersinde bulunan isimve boy değişkenlerine sırasıyla Ali ve 167 değerleri atanmaktadır.

#include<stdio.h>
int main( void )
{
	// kisi adinda bir yapi olusturulup
	// baslangic degerleri 'Ali' ve '167'
	// olacak sekilde atanir.
	struct {
		char isim[40];
		int boy;
	} kisi = { "Ali", 167 };

	return 0;
}

Etiket kullanarak oluşturduğunuz yapılarda, ilk değer ataması değişkenlerin tanımlanması aşamasında gerçekleşir. Önce yapıyı kurar ve ardından değişken tanımlarken, ilk değerleri atarsınız. Kullanımı aşağıdaki kod içersinde görülmektedir:

#include<stdio.h>
int main( void )
{
	// sahis_bilgileri adinda bir yapi
	// olusturuyoruz
	struct sahis_bilgileri {
		char isim[40];
		int boy;
	};

	// sahis_bilgileri yapisindan kisi adinda
	// bir degisken tanimliyoruz. Tanimlama
	// esnasinda atanacak ilk degerler belirleniyor.
	struct sahis_bilgileri kisi = { "Ali", 167 };

	return 0;
}

Bir yapı değişkenine, ilk değer ataması yapıyorsanız sıra önemlidir. Atayacağınız değerlerin sırası, ilgili değişkenlere göre olmalıdır. Yani ilk yazacağınız değer, ilk yapı içi değişkene; ikinci yazacağınız değer, ikinci yapı içi değişkene atanır. Sırayı şaşırmadığınız sürece bir problem yaşamazsınız. Aksi durumda, yanlış değer yanlış değişkene atanacaktır. Sırayı şaşırmamak için, ekstra ayraç işaretleri kullanabilirsiniz. Örneğin { “Mehmet”, 160, 23, 3, 1980 } yerine { “Mehmet”, 160, {23, 3, 1980} } yazmakta mümkündür.

Yapı Dizileri

Veri tiplerine ait dizileri nasıl oluşturacağımızı biliyoruz. Bir tam sayı dizisi, bir karakter dizisi rahatlıkla oluşturabiliriz. Benzer şekilde yapı ( structure ) dizileri de tanımlanabilir. 3 kişilik bir personel listesi tutacağımızı düşünüp, ona göre bir program oluşturalım. Her eleman için ayrı ayrı değişken tanımlamaya gerek yoktur; yapılardan oluşan bir dizi yaratabiliriz.

#include<stdio.h>
int main( void )
{
	int i;
	// Dogum tarihi tutmak icin
	// 'dogum_tarihi' adinda bir yapi
	// olusturuyoruz
	struct dogum_tarihi {
		int gun;
		int ay;
		int yil;
	};

	// Kisiye ait bilgileri tutmak
	// icin 'sahis_bilgileri' adinda
	// bir yapi kuruluyor.
	struct sahis_bilgileri {
		char isim[40];
		int boy;
		// Yapi icinde bir baska yapiyi
		// kullanmak mumkundur. dogum_tarihi
		// yapisindan 'tarih' adinda bir
		// degisken tanimlaniyor.
		struct dogum_tarihi tarih;
	};

	// Dizi elemanlarina ilk deger atamasi yapiyoruz. Dilerseniz
	// klavyeden deger girmeyi tercih edebilirsiniz.
	struct sahis_bilgileri kisi[3] = { "Ali", 170, { 17, 2, 1976 },
					"Veli", 178, { 14, 4, 1980 },
					"Cenk", 176, { 4, 11, 1983 } };

	// Yapi dizisi yazdiriliyor:
	for( i = 0; i < 3; i++ ) {
		printf( "Kayıt no.: %d\n", ( i + 1 ) );
		printf( "Ad: %s\n", kisi[i].isim );
		printf( "Boy: %d\n", kisi[i].boy );
		printf( "Doğum Tarihi: %d/%d/%d\n\n", kisi[i].tarih.gun,
						kisi[i].tarih.ay,
						kisi[i].tarih.yil );
	}

	return 0;
}

Tek bir yapı değişkeniyle, bir yapı dizisi arasında büyük fark bulunmuyor. Sadece köşeli parantezlerle eleman indisini belirtmek yetiyor. Yoksa, değer okuma, değer yazma… bunların hepsi tıpatıp aynı. Bu yüzden ayrıca detaya inmiyorum.

Yapı Dizilerine Pointer ile Erişim

Kambersiz düğün olmaz. Aynı şekilde, dizilerden bahsettiğimiz bir yerde pointer’lardan bahsetmemek mümkün değil. Bir yapı dizisinin başlangıç adresini pointer’a atadığınız takdirde, elemanlara bu işaretçi üzerinde de ulaşabilirsiniz. Bir üstteki örneğimizi pointer’larla kullanalım:

#include<stdio.h>
int main( void )
{
	int i;
	// Dogum tarihi tutmak icin
	// 'dogum_tarihi' adinda bir yapi
	// olusturuyoruz
	struct dogum_tarihi {
		int gun;
		int ay;
		int yil;
	};

	// Kisiye ait bilgileri tutmak
	// icin 'sahis_bilgileri' adinda
	// bir yapi kuruluyor.
	struct sahis_bilgileri {
		char isim[40];
		int boy;
		// Yapi icinde bir baska yapiyi
		// kullanmak mumkundur. dogum_tarihi
		// yapisindan 'tarih' adinda bir
		// degisken tanimlaniyor.
		struct dogum_tarihi tarih;
	};

	struct sahis_bilgileri *ptr;

	// Dizi elemanlarina ilk deger atamasi yapiyoruz. Dilerseniz
	// klavyeden deger girmeyi tercih edebilirsiniz.
	struct sahis_bilgileri kisi[3] = { "Ali", 170, { 17, 2, 1976 },
					"Veli", 178, { 14, 4, 1980 },
					"Cenk", 176, { 4, 11, 1983 } };

	// Yapi dizisi yazdiriliyor:
	for( i = 0, ptr = &kisi[0]; ptr <= &kisi[2]; ptr++, i++ ) {
		printf( "Kayıt no.: %d\n", ( i + 1 ) );
		printf( "Ad: %s\n", ptr->isim );
		printf( "Boy: %d\n", ptr->boy );
		printf( "Doğum Tarihi: %d/%d/%d\n\n", ptr->tarih.gun,
						ptr->tarih.ay,
						ptr->tarih.yil );
	}

	return 0;
}

Pointer’ın tanımlamasını yaparken, ‘sahis_bilgileri‘ şablonundan türetilen değişkenlerin işaret edileceğini bildirmemiz gerekiyor. Yazmış olduğumuz “struct sahis_bilgileri *ptr;” kodu bundan kaynaklanmaktadır. for döngüsüne gelirsek, kisi isimli yapı dizisinin ilk elemanının adresini, ptr işaretçisine atadığımızı görmüşsünüzdür. Her seferinde de, ptr değeri bir adres bloğu kadar artmaktadır. Döngünün devamı, adresin son dizi elemanından küçük olmasına bağlıdır. Kullandığımız -> operatörüyse, pointer ile dizi elemanlarını göstermemizi sağlar. Bu cümleler size muhtemelen karışık gelecektir -ki bu kesinlike normal… İnanıyorum ki kodu incelerseniz, durumu daha basit kavrarsınız.

Yapılar ve Fonksiyonlar

enum ile yarattığımız değişken tiplerini, fonksiyonlarda kullanmak için global olarak tanımlıyorduk. Yapıları, fonksiyonlarda kullanılmak için izlenecek yöntem aynıdır; yine global tanımlanması gerekir. Çok basit bir örnekle yapıların fonksiyonlarla kullanımını görelim:

#include<stdio.h>
#include<string.h>
struct sahis_bilgileri {
	char isim[40];
	int boy;
};

struct sahis_bilgileri bilgileri_al( void );
void bilgileri_goster( struct sahis_bilgileri );

int main( void )
{
	struct sahis_bilgileri kisi;
	kisi = bilgileri_al( );
	bilgileri_goster( kisi );

	return 0;
}
struct sahis_bilgileri bilgileri_al( void )
{
	struct sahis_bilgileri sahis;
	printf( "İsim> " );
	gets( sahis.isim );
	printf( "Boy> " );
	scanf( "%d", &sahis.boy );
	return sahis;
}
void bilgileri_goster( struct sahis_bilgileri sahis )
{
	printf( "Ad: %s\n", sahis.isim );
	printf( "Boy: %d\n", sahis.boy );
}

Dinamik Yapılar

Dinamik bellek tahsis etmenin ne olduğunu, niçin bunu kullandığımızı açıklamaya gerek duymuyorum. Daha önceki derslerimizde bu konuya yer vermiştik. Çok basit bir örnekle dinamik yapıların kullanımı göstermek yeterli olacaktır:

struct sahis_bilgileri *ptr;
ptr = calloc( 1, sizeof( struct sahis_bilgileri ) );
free( ptr );

Üç adımda, yapıları dinamik kullanmayı görüyorsunuz. En başta ptr adında bir pointer tanımlıyoruz. İkinci aşamada, bellek ayrımı yapılıyor. Bu örnekte, sadece tek değişkenlik yer ayrılıyor. ptr ile işimiz bittikten sonra, free(  ) fonksiyonuyla, belleği boşaltıyoruz. Sadece üç temel adımla, yapılarda dinamik bellek kullanımını sağlayabilirsiniz. Yalnız calloc(  ) ( ya da malloc(  ) ) fonksiyonunun stdlib.haltında olduğunu unutmayın. ( Bu yüzden kodun başına #include<stdlib.h> yazmak gerekmektedir. )

Yapılarda typedef Kullanımı

enum konusuna tekrar dönüyoruz. Hatırlayacağınız üzere, typedef orada da geçmişti. typedef kullanarak her seferinde fazladan enum yazma zahmetinden kurtuluyorduk. typedef, yapılar için de kullanılmaktadır. Her defasında tekrar tekrar struct yazmak yerine, bir kereye mahsus typedef kullanarak bu zahmetten kurtulabilirsiniz. Aşağıdaki gibi yazacağınız kodla, tekrar tekrar struct kelimesi kullanmanıza gerek kalmayacaktır.

typedef struct sahis_bilgileri kisi_bilgileri;

Noktalarken…

C programlama diline dair anlatımlarımız burada bitiyor. Bu demek değildir ki; C üzerine her şeyi anlattık; aksine daha birçok konu bulunuyor. ( Örneğin dosya işlemleri, union kullanımı vb… konulara hiç değinilmedi. ) Ancak şimdiye kadar öğrendikleriniz, bundan sonrasını öğrenebilmeniz için size temel teşkil edecektir. Programlama dili öğrenmek, yabancı dil öğrenmekle hemen hemen aynıdır. İngilizce üzerine dersler aldığınızda, kimse Shakespeare olacağınızı söyleyemez. Ama çok çalışıp kendinizi geliştirmek size bağlıdır. Programlama dilleri de aynen böyle… Burada ya da bir başka kaynakta anlatılanlarla işin duayeni olamazsınız; fakat işi anlar duruma gelirsiniz. Bundan sonrası sizin elinizdedir… Lütfen bol bol pratik yapıp, olabildiğince çok algoritma kurun. Sizlere temel programlama gramerini vermeye çalıştım; umarım sonunda hepiniz birer “Macbeth” yazarsınız!

Related Articles

Leave a Reply

Close

Reklam Engelleme

Please consider supporting us by disabling your ad blocker