[B]Yeni Değişken Tipi Oluşturma
Kullandığımız bircok değişken tipi oldu. Tam sayıları, karakterleri, virgullu sayıları, katarları gorduk. Ancak kullanabileceğimiz değişken tipleri bunlarla sınırlı değildir. Kendi değişken tiplerimizi, yaratabiliriz. Orneğin boolean diye yeni bir tip yaratarak, bunun alabileceği değerleri true ve false olarak belirleyebiliriz; ucuncu 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 icin 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 gorursunuz. Bir karakter olan A harfi, ASCII Tablo'da 65 sayısına denk duşer; buyuk B harfiyse 66'dır ve bu boyle devam eder. Bilgisayarınız işaretlerden, sembollerden, karakterlerden anlamaz. Onun icin tek gerceklik sayılardır. İşte enum bu felsefeye hizmet ediyor. Orneğin doğruyu gostermek icin 1, yanlış icinse 0'ı secersek; yeni bir değişken tipi belirlemiş oluruz. Bilgisayar doğrunun ya da yanlışın ne olduğunu bilmez, onun icin sadece 0 ve 1 vardır. Ancak insanların yararına, okunurluğu artan programlar ortaya cıkar. İsterseniz, boolean diye tabir ettiğimiz değişken tipini oluşturalım:
Kod:
#include int main( **** ) ; // 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 once boolean diye bir veri tipi bulunmuyordu. Şimdiyse, iki farklı değeri olabilen, doğru ve yanlışları gostermekte kullanabileceğimiz yeni bir değişken tipi oluşturduk. Yanlışı gostermek icin 0; doğruyu ifade etmek icinse 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 uc ana rengi ( Kırmızı, Sarı ve Mavi )alabilecek ana_renkler veri tipini oluşturalım:
Kod:
#include int main( **** ) ; // 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 numerik değerini bilmiyoruz; muhtemelen birden başlamış ve sırayla uce kadar devam etmişlerdir. Değerlerin numerik karşılığını bilmesek bile, bu onlarla işlem yapmamızı engellemiyor. Bir onceki ornekte olduğu gibi rahatca kullanabiliyoruz.
Oluşturduğumuz yeni veri tiplerinden, değişken tanımlarken her defasında enum koyduğumuzu gormuşsunuzdur. Bunu defalarca yazmak yerine iki alternatif bicim bulunuyor. Birincisi yeni veri tipini oluştururken, değişkeni tanımlamak şeklinde... boolean orneğimize geri donup, farklı şekilde nasıl tanımlama yapabileceğimizi gorelim:
Kod:
#include int main( **** ) dogru_mu; dogru_mu = true; if( dogru_mu == true ) printf( "Doğru\n" ); return 0; }
Yukarda gorduğunuz yontem, 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 yontemse, typedef kullanmaktan gecer. typedef kullanımı şu şekildedir:
Kod:
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. Orneğin yazacağınız "typedef int tam_sayi;" komutuyla, değişken tanımlarken int yerine tam_sayi da yazabilirsiniz. Bunun enum icin uygulamasına bakalım:
Kod:
#include int main( **** ) ; // 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; }
Ozel Değişken Tipleri ve Fonksiyonlar
enum konusu genişletilebilir. Orneğin enum tanımlamasını, global olarak yaparsanız, fonksiyon parametresi olarak kullanabilirsiniz. Cok basit bir fonksiyon oluşturalım. Alacağı değişken bilgisine gore, ekrana ona dair bilgi yazdırılsın:
Kod:
#include // Ay listesini olusturuyoruz. Ocak // ayi 1 olacak sekilde, aylar sirayla // numerik degerler aliyor. enum ay_listesi ; // Degisken tanimlamasini kolaylastirmak // icin typedef kullaniliyoruz. aylar diyerek // tanimlama yapmak mumkun hale geliyor. typedef enum ay_listesi aylar; **** ay_ismini_yazdir( aylar ); int main( **** ) // Kendisine verilen aylar tipindeki degiskene gore // hangi ayin oldugunu ekrana yazmaktadir. **** ay_ismini_yazdir( aylar ay_adi ) }
Gorduğunuz gibi enum ile oluşturacağınız ozel veri tiplerini fonksiyonlara aktarmak mumkun. enum aracılığı ile yeni bir değişken tipi yaratmak, bircok konuda işinizi basit hÂle getirir. Ozellikle gruplandırılması/tasnif edilmesi gereken veriler varsa, enum kullanmak yararlıdır. Ornek olması acısından aşağıda enum ile tanımlanmış bazı veri tiplerini bulabilirsiniz:
Kod:
enum medeni_durum ; enum medeni_durum ayse = bekar;
Kod:
enum egitim_durumu ; enum egitim_durumu ogrenci;
Kod:
enum cinsiyet ; enum cinsiyet kisi;
Yapılar ( Structures )
Yapılar ( structures ); tam sayı, karakter vb. veri tiplerini gruplayıp, tek bir catı altında toplar. Bu gruplandırma icinde aynı ya da farklı veri tipinden dilediğiniz sayıda eleman olabilir. Yapılar, nesne tabanlı programlama ( Object Oriented Programming ) dilleri icin onemli bir konudur. Eğer Java, C# gibi modern dillerle calışmayı duşunuyorsanız, bu konuya daha bir onem vermeniz gerekir.
Vakit kaybetmeden bir ornekle konumuza girelim. Doğum gunu bilgisi isteyip, bunu ekrana yazdıran bir program oluşturalım:
Kod:
#include int main( **** ) dogum_gunu; printf( "Doğum gununuzu " ); printf( "GG-AA-YYYY olarak giriniz> "); scanf( "%d-%d-%d", &dogum_gunu.gun, &dogum_gunu.ay, &dogum_gunu.yil ); printf( "Doğum gununuz: " ); printf( "%d/%d/%d\n", dogum_gunu.gun, dogum_gunu.ay, dogum_gunu.yil ); return 0; }
Bir kullanıcının doğum gununu sorup, gun, ay ve yıl bilgilerini uc farklı int değişken icersinde 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 icin aynı anda sizin ve iki kardeşinizin doğum gunlerini soran bir program yazalım:
Kod:
#include int main( **** ) siz, kiz_kardes, erkek_kardes; printf( "Doğum gununuzu 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; uc kişinin doğum gunu bilgilerini tutmak icin 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 uc değişken olarak duşunmeyelim; nufus cuzdanı bilgilerini soracağımız bir program, yirminin uzerinde değişkene ihtiyac duyar. Bu kadar cok değişken barındırıp, yapıları kullanmadan hazırlanacak bir programı gormek bile istemezsiniz.
Yapıları kullanmanın bir diğer avantajı, kopyalama konusundadır. Orneğin, sizin bilgilerinizi, erkek kardeşinize kopyalamak icin tek yapmanız gereken, "erkek_kardes = siz" yazmaktır. Bu basit işlem ilgili butun değişkenlerin kopyalamasını yapar.
İc İce Yapılar
Bir yapı icersine tıpkı bir değişken koyar gibi, bir başka yapı da koyulabilir. Orneğ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ı icersinde tutmak yararlı olabilir. Bunu koda dokersek şoyle olur:
Kod:
#include int main( **** ) 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 icin nokta kullanıp, ardından yapının adını yazdığımızı goruyorsunuz. Yapıları kullanarak, bir arada durması yararlı olan değişkenleri gruplarız. İc ice yapıları kullanaraksa, bu gruplandırmayı daha da ufak boyutlara indirgemekteyiz. Kısacası her şey, daha derli toplu calışma icin 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 ornek yapalım:
Kod:
#include #include int main( **** ) ; // 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. Onemli 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, uzerinde 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 ornek etiket kullanmadan oluşturduğunuz yapılarda, ilk değer atamasının nasıl olduğunu gostermektedir. 'kisi' isimli yapı icersinde bulunan isim ve boy değişkenlerine sırasıyla Ali ve 167 değerleri atanmaktadır.
Kod:
#include int main( **** ) kisi = ; return 0; }
Etiket kullanarak oluşturduğunuz yapılarda, ilk değer ataması değişkenlerin tanımlanması aşamasında gercekleşir. Once yapıyı kurar ve ardından değişken tanımlarken, ilk değerleri atarsınız. Kullanımı aşağıdaki kod icersinde gorulmektedir:
Kod:
#include int main( **** ) ; // sahis_bilgileri yapisindan kisi adinda // bir degisken tanimliyoruz. Tanimlama // esnasinda atanacak ilk degerler belirleniyor. struct sahis_bilgileri kisi = ; return 0; }
Bir yapı değişkenine, ilk değer ataması yapıyorsanız sıra onemlidir. Atayacağınız değerlerin sırası, ilgili değişkenlere gore olmalıdır. Yani ilk yazacağınız değer, ilk yapı ici değişkene; ikinci yazacağınız değer, ikinci yapı ici değişkene atanır. Sırayı şaşırmadığınız surece bir problem yaşamazsınız. Aksi durumda, yanlış değer yanlış değişkene atanacaktır. Sırayı şaşırmak icin, ekstra ayrac işaretleri kullanabilirsiniz. Orneğin yerine } yazmakta mumkundur.
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ı duşunup, ona gore bir program oluşturalım. Her eleman icin ayrı ayrı değişken tanımlamaya gerek yoktur; yapılardan oluşan bir dizi yaratabiliriz.
Kod:
#include int main( **** ) ; // Kisiye ait bilgileri tutmak // icin 'sahis_bilgileri' adinda // bir yapi kuruluyor. struct sahis_bilgileri ; // Dizi elemanlarina ilk deger atamasi yapiyoruz. Dilerseniz // klavyeden deger girmeyi tercih edebilirsiniz. struct sahis_bilgileri kisi[3] = , "Veli", 178, , "Cenk", 176, }; // Yapi dizisi yazdiriliyor: for( i = 0; i < 3; i++ ) return 0; }
Tek bir yapı değişkeniyle, bir yapı dizisi arasında buyuk fark bulunmuyor. Sadece koşeli parantezlerle eleman indisini belirtmek yetiyor. Yoksa, değer okuma, değer yazma... bunların hepsi tıpatıp aynı. Bu yuzden ayrıca detaya inmiyorum.
Yapı Dizilerine Pointer ile Erişim
Kambersiz duğun olmaz. Aynı şekilde, dizilerden bahsettiğimiz bir yerde pointer'lardan bahsetmemek mumkun değil. Bir yapı dizisinin başlangıc adresini pointer'a atadığınız takdirde, elemanlara bu işaretci uzerinde de ulaşabilirsiniz. Bir ustteki orneğimizi pointer'larla kullanalım:
Kod:
#include int main( **** ) ; // Kisiye ait bilgileri tutmak // icin 'sahis_bilgileri' adinda // bir yapi kuruluyor. struct sahis_bilgileri ; struct sahis_bilgileri *ptr; // Dizi elemanlarina ilk deger atamasi yapiyoruz. Dilerseniz // klavyeden deger girmeyi tercih edebilirsiniz. struct sahis_bilgileri kisi[3] = , "Veli", 178, , "Cenk", 176, }; // Yapi dizisi yazdiriliyor: for( i = 0, ptr = &kisi[0]; ptr
C Programlama Dersi | Yeni Değişken Tipi Oluşturma
Android & IOS Uygulama Geliştirme0 Mesaj
●29 Görüntüleme
- ReadBull.net
- Programlama ve Yazılım
- Android & IOS Uygulama Geliştirme
- C Programlama Dersi | Yeni Değişken Tipi Oluşturma