C++ Programlamaya Giriş Ve Mantığı Anlamanız.

Yazan Türk

Dost Üyeler
Katılım
7 May 2008
Mesajlar
101
Tepkime puanı
0
Puanları
0
16.FONKSİYONLAR

C dilinin en can alıcı kısımlarından biri de, şüphesiz fonksiyonlardır. Eğer buraya kadar olan kısmı okuduysanız, fonksiyonun ne olduğu hakkında ufak bir bilgi edinmişsinizdir. Fonksiyon programlayıcın yapacağı işlemleri gruplandırmasını sağlar. Bu gruplandırma sayesinde onlara ulaşım kolay olur ve program geliştirilmesi de kolaylaşır. Bu söylenileni daha önce BASIC dilini kullananlar daha iyi anlayacaktır. BASIC dilinde böyle bir gruplandırma söz konusu değildir. Bütün işlemler alt alta tek bir liste halinde yazılır. Bu dille uzun programlar yazmak o kadar zordur ki, insanı programlamadan soğutabilir. Neyse, konumuz BASIC dilinin dezavantajları değil elbette
smile.gif


C dilinde program başlatıldığında hemen devreye girecek olan fonksiyon, main ( ) fonksiyonudur. Eğer başka fonksiyonlar tanımlamak isterseniz ilk olarak fonksiyonun ne yapmak istediğini belirtmeniz gerekir. Örnek olarak, bir satırı komple * karakteri ile dolduran bir fonksiyon yapalım. Fonksiyonun ismi yildiz_doldur olsun. (Not: 1 satıra 40 adet karakter sığar)

CODEvoid yildiz_doldur( )
{
int i=1;
for( i=1;i<=40;i++)
printf(?*?);
}

Fonksiyonun başındaki void ifadesi bu fonksiyonun geriye bir değer döndürmeyeceğini belirtir. Yani getch() fonksiyonunun geriye döndürdüğü bir değer gibi bir değere sahip değildir. Eğer bir fonksiyonun geriye değer döndürmesini istiyorsak döndüreceği değerin tipini buraya yazarız. void ise bir değer döndürmeyen fonksiyonlarda kullanılır.
Bu fonksiyonu bu şekilde tanımladıktan sonra fonksiyon program başladığı gibi işlemleri faaliyete geçirmeyecektir. Çünkü bu fonksiyonu çalıştırmak için bilgisayara bunu yapmasını söyleyecek komut gerekir. Bu komutu istenilen bir fonksiyonun içine ekleyebilirsiniz. Bizim örneğimizi ana fonksiyonun içine yerleştirelim. Böylece program çalıştığı zaman ilk olarak 1. satır * karakteriyle dolacaktır. Programın tam metni şu şekilde olmalıdır.

CODE#include <stdio.h>
void yildiz_doldur( )
{
int i=1;
for( i=1;i<=40;i++)
printf(?*?);
}
void main( )
{
char kar;
clrscr( );
yildiz_doldur();
fscanf(?%c?,&kar);
}

Bu program ekranı temizler. Birinci satırı * karakterleriyle doldurur. ?Enter? tuşuna basılıncaya kadar bekler ve biter.
Fonksiyonları bir yerde çağırabilmek için, fonksiyonun o yerden önce mutlaka tanımlanmış olması gerekir. Örneğin, main fonksiyonuyla yildiz_doldur fonksiyonlarının yerlerini değişitirseydik program fonksiyonu bulamayacaktı. Eğer iki fonksiyon da birbirini çağırıyor ya da sıraları önemsememek istiyorsanız fonksiyonu ayrıca tanımlayabilirsiniz. Örnek üzerinde gösterelim:

CODE#include <stdio.h>
void yildiz_doldur( );
void main( )
{
char kar;
clrscr( );
yildiz_doldur();
fscanf(?%c?,&kar);
}
void yildiz_doldur( )
{
int i=1;
for( i=1;i<=40;i++)
printf(?*?);
}

#include satırından hemen sonra fonksiyonu olduğu şekliyle tanımlamak suretiyle programın bu halde de çalışmasını sağladık. Çünkü artık yildiz_doldur fonksiyonu, main fonksiyonundan önce tanımlanmıştır.

Fonksiyonların önemli bir özelliği, lokal değişkenlere sahip olabilmesidir. Yani bir fonksiyonun içinde tanımlanmış bir değişkene, diğer fonksiyonlarla hiçbir şekilde ulaşamazsınız. Bunun sağladığı en büyük yarar gereksiz değişken kullanımını engellemektir. Aynı isimde iki değişkenin, iki ayrı fonksiyonda kullanılması bu şekilde mümkündür. Bu işlem kesinlikle hata vermez ve programlamada sık kullanılan bir biçimdir.

Eğer bütün fonksiyonlar içerisinde de geçerli değişkenler tanımlamak isterseniz, bu tanımlamayı fonksiyonların dışında yapmanız gerekir. Tanımlama yapıldığı yerden sonraki tüm fonksiyonlarda tanımlanan global değişken kullanılabilir. Çok gerekmedikçe, global değişken kullanımı tavsiye edilmez.

Eğer bir fonksiyondan çıkmak isterseniz return komutunu kullanabilirsiniz. Fonksiyonda bu komut görüldüğü an fonksiyondan çıkılır ve programa kaldığı yerden devam edilir.Şu şekilde kullanılır:

return;
<!-->

17.FONKSİYONLARIN DEĞER DÖNDÜRMESİ

Bazen bir fonksiyonun, bir işlem yapıldığında yapılan işlemin sonuçları hakkında bilgi vermesi istenir. Örneğin getchar() fonksiyonu içerisindeki işlem, klavyeden bir tuşa basılıncaya kadar beklemeyi sağlamaktadır. Bu fonksiyon yardımıyla, aynı zamanda, hangi tuşa basıldığını öğrenebiliriz. Demek ki bu fonksiyonun, geri dönüş değeri vardır ve bu değer char veri tipindedir. Yani bu fonksiyon aşağıdaki şekliyle tanımlanmıştır.

CODEchar getchar();

İşte bu tanımlamaya uygun olarak siz de kendi geri dönüş değeri olan fonksiyonları oluşturabilirsiniz. Böyle bir fonksiyon bittiğinde yapılması gereken en önemli işlem, fonksiyonun değerini atamaktır. Bu atama return komutuyla yapılır. İngilizce?de anlamı, ?kaldığın yere geri dön? demektir. Dönerken hangi değerle döneceği ise komuttan hemen sonra belirtilmelidir.Ornek:

CODEreturn 10;
return karakter;//char tipinden bir değişken olabilir
return sayac;//int tipinden ya da başka herhangi bir tipten de olabilir.
return karekok;//Bir sınırlama yoktur.

18.FONKSİYONLARA DEĞER BİLDİRİMİ (PARAMETRELER)

Bir fonksiyonun yapacağı işi, sadece belirli kalıplara sokarak oluşturmak her zaman kullanışlı olmayabilir. Örneğin bazı matematiksel işlemler için fonksiyonun hangi sayılara bu işlemi uygulayacağını belirtmek gerekir. Bunun için fonksiyonlar parametre alabilirler. Örneğin bir sayının faktoriyelini alan bir fonksiyon yapalım.

CODEint faktoriyel(int sayi )
{
int sonuc;
sonuc=1;
for( i=2;i<=sayi;i++)
sonuc=sonuc*i;
return sonuc;
}

Bu fonksiyon parametreli olarak tanımlanmıştır. Böylelikle fonksiyonumuz istenilen sayının faktoriyelini hesaplayabilir. Örneğin, 7 sayısının faktoriyeli için aşağıdaki kodu yazmak yeterlidir.

CODEint sonuc;
sonuc=faktoriyel(7 );
veya direk ekrana yazdırmak için
printf(?%d?,faktoriyel(7 ));

Bu fonksiyon parametreli olarak tanımlanmıştır ve fonksiyonun geri döndüreceği değer bir tamsayıdır. return komutuyla bu değeri sonuç olarak gönderdik.
Parametreli fonksiyonlarda geri dönüş değeri kullanılmayabilir. Örneğin ekrana bir dikdörtgen çizecek bir fonksiyonun parametreleri dikdörtgenin koordinatlarını belirtsin. Bu fonksiyonun geriye değer döndürmesine gerek yoktur.

Parametreli fonksiyonlarda parametre sayısı 1?den fazla olabilir. Bunlar aralarına virgül konarak belirtilir. Fonksiyon çağrılırken yine virgüller kullanılarak çağrılır. Örnek:

CODEvoid pencere_ac(int x1,int y1,int x2,int y2);
pencere_ac(0,0,100,100);

<!-->

19.DEĞİŞKENLERİN ÖZELLİKLERİ

7. bölümde değişkenlere çok kısa bir bakış yapmıştık. Şimdi değişkenlerin esas yapıları hakkında duralım ve değişik değişken tiplerine göz atalım.

Değişkenler, bir sayısal değerin hafızada tutulması ve kullanılması için bellekte ayrılan yeri ve bu verinin algılanış biçimini belirler. Dolayısıyla çeşitli değişkenler bellekte değişik boyutlar kaplayabilir.

Bunları açıklamadan önce biraz da bellek yapısına değinelim. Bilgisayarda bellek verilerinin temel yapıtaşı, ikilik (binary) sistemdir. Yani bellek 1?ler ve 0?lardan oluşur. Bellekte 1 ya da 0 değeri alabilen birime bit denir. Başka bir ifadeyle bir bit 2 farlı değer alabilir. (1 ve 0) 8 tane bit yan yana getirilirse buna byte denir. 1 byte 8 tane bitten oluşur. Her bit iki farklı değer alabiliyordu. Kombinasyon hesabından, 8 tane bitin 2 üzeri 8 farklı değer alabileceği kolaylıkla bulunabilir.

Başka bir bakış açısıyla 2?lik düzende 8 basamaklı en büyük sayı 11111111 sayısıdır. Bu sayının değeri 255 ?tir. 255?e kadar 0 ?la birlikte tam 256 farklı sayı vardır. Bu da tam olarak 2 üzeri 8?e tekabül eder.

O halde bir byte?ın 256 farklı değer alabileceğini gördük. 2 byte ise 256 ?nın karesi kadar farklı değer alabilir. Buradan genelleme yaparsak, n byte 256 üzeri n farklı değer alır.

C++ ?ta bir değişkendeki ilk bit, sayının pozitif-negatif olup olmadığını belirten bit olarak değerlendirilir. Bu bitin değeri 0 ise sayı negatif, 1 ise sayı pozitiftir. Eğer bir değişken tanımından önce unsigned belirtecini kullanırsanız, C++ ilk biti de değişkene dahil edecek, ve değişken ilk bit ne olursa olsun pozitif değer içerecektir. Böylelikle sayının alabileceği maksimum değer iki katına çıkar.

Şimdi C++?taki değişken çeşitlerini inceleyelim.

CODEchar

8 bit

1 byte

Tam sayı

-128...+127

unsigned char

8 bit

1 byte

Tam sayı

0...255

int

16 bit

2 byte

Tam sayı

-32 768...+32 767

long int

32 bit

4 byte

Tam sayı

- 2 147 483 648...+2 147 483 647

unsigned int

16 bit

2 byte

Tam sayı

0...+65 535

unsigned long

32 bit

4 byte

Tam sayı

0...+4 294 967 296

float

32 bit

4 byte

Ondalıklı sayı

3.4 * (10^-3 to 3.4 * (10^+3

double

64 bit

8 byte

Ondalıklı sayı

1.7 10^-308 to 1.7 10^308

CODE1 GigaByte=1024 MegaByte=1024^2 KiloByte=1024^3 Byte=1024^4 Byte=8*1024^4 Bit
1 Byte=8 Bit
1 KiloByte (KB) =1024 Byte = 8*1024=Bit
1 MegaByte(MB)=1024 KiloByte(KB)
1 GigaByte(GB)=1024 MegaByte(MB)

20.STRUCT (YAPILAR)

typedef : Yeni tip tanımlamak için kullanılan bir komuttur. Örnek:
CODEtypedef TAMSAYI long int;

Bu satırdan sonra artık TAMSAYI diye bir tip oluşur.
TAMSAYI sayi1,sayi2;
sayi1 ve sayi2 TAMSAYI tipinden yani, long int değişkenlerdir.
struct: Belirli tipleri bir araya getirerek bir veri yapısı oluşturmak için kullanılan bir komuttur. (yapı)

Yapı, değişkenler içeren bir veri saklama ağacıdır. Programınızdaki değişkenleri düzenli tutmak için çok gerekli bir özelliktir. Yapılar kullanılmadan oluşturulan büyük programlar hantal olur ve anlaşılması ve geliştirilmesi çok zordur. Şimdi struct ifadesinin ne anlama geldiğini örneklerle inceleyelim.

Bir programda çeşitli üçgenler saklamak isteyelim. Her üçgenin üç adet koordinatı olur. Her koordinatın da 2 adet değer içermesi gerekir. (x ve y) Şimdi bunu şu ana kadar öğrendiğimiz metotlarla yapmayı deneyelim.

CODEfloat x[3],y[3];

Bu şekilde yalnızca bir üçgen belirttik. Daha fazla üçgen için ise şöyle yapabiliriz:

CODEfloat x[10][3],y[10][3];

Bu şekliyle 10 tane üçgen saklayabiliriz. Yerine göre bunu da kullanabilirsiniz. Ama emin olun ki, program karmaşıklaştıkça bu yöntemin çok kötü olduğunu anlayacaksınız. Bundan daha kolay bir yolla böyle bir tanımlama yapmak mümkündür. Şimdi bu üçgeni struct olarak tanımlayalım.

CODEtypedef struct
{
float x[3],y[3];
} UCGEN;

Böylelikle UCGEN adında yeni bir tip tanımlamış olduk. Bu tipin bellekte kapladığı alan 24 byte?dır. Çünkü içinde 6 tane float tipinden değişken var. Hatırlarsanız float tipi 4 byte?lık belleğe ihtiyaç duyar. Bu yüzden bizim tanımladığımız UCGEN veri tipi hafızada 24 byte?lık yer kaplar.

Şimdi 1 tane üçgen saklamak için aşağıdaki kodu yazalım.

CODEUCGEN ucgen1;

Bu tanımlamadan sonra ucgen1 değişkeni UCGEN tipinden bir değişkeni temsil edecektir. Bu değişkenin kendisi bir değer içermez ama üyeleri değer içerir. Üyelerine erişmek için ?nokta? operatörü kullanılır.

CODEucgen1.x[0]=0.5;
ucgen1.y[0]=15.5;
ucgen1.x[1]=7;
...
ucgen1.y[2]=8.6;

Görüldüğü gibi ucgen1 değişkeninin üyeleri UCGEN tipinde tanımladığımız değişkenlerdir. Bu üye değişkenler sadece tanımlandıkları yapı içinde geçerli oldukları için, isimleri diğer değişkenleri etkilemez. Yani başka bir yerde x adlı bir değişken tanımlayabiliriz.

Şimdi de UCGEN tipinden 10 elemanlı bir dizi tanımlayalım.

CODEUCGEN ucgen_dizisi[10];
ucgen_dizisi[0].x[0]=5.2;
ucgen_dizisi[0].y[0]=3.2;
...
ucgen_dizisi[10].y[2]=4.1;


Şimdi de koordinatlar için de bir yapı tanımlayalım. Düzlemdeki bir nokta x ve y değerinden oluşur. Buna göre:

CODEtypedef struct
{
float x,y;
}NOKTA;

Şimdi UCGEN tipini farklı bir şekilde yeniden tanımlayalım.

CODEtypedef struct
{
NOKTA noktalar[3];
} UCGEN;

Şimdi UCGEN tipinden bir değişken tanımlayalım.

CODEUCGEN u1;
u1.noktalar[0].x=3.9;
u1.noktalar[0].y=5.8;
...
u1.noktalar[2].y=2.1;

Görüldüğü gibi artık herşey daha derli toplu hale geldi. Bunun sağladığı kolaylığı daha kompleks programlar yapmaya başladıkça anlayacaksınız.

Başka bir örnekle olayı daha da açıklığa kavuşturalım. Bir veritabanı programında kullanmak üzere bir yapı tanımlayalım. Bu yapı içerisinde bir kulübe üye olan kişilerin isimlerini, telefonlarını vs. tutsun. Kulübün ismi, Hayvan Severler Derneği farzedelim. Örneğimizi oluşturalım, fakat daha önce küçük bir komutun ne işe yaradığına bakalım:

?define? komutu bir sabit belirtmek için kullanılır. Genelde program kodunun en üst taraflarında bulunur ve programın sabitleri için kullanılır. Mesela Pi sayısı şu şekilde tanımlanabilir.

CODE#define PI 3.1415926535897932384626433832795

Bu komut kendinden sonraki her PI görülen yere pi sayısı koyar. Böylece program daha anlaşılır bir hale gelir.

Şimdi örneğimizi oluşturalım:

CODE#define MAX_UYE_SAYISI 100
typedef struct
{
char *adi;
char *soyadi;
int dogum_yili;
char *tel;
char *adres;
}UYELER;
typedef struct
{
int uye_sayisi;
UYELER uye[MAX_UYE_SAYISI];
}HAYSEVDER;

Şimdi HAYSEVDER tipinden bir değişken tanımlayalım ve bir üye ekleyelim.

CODEHAYSEVDER dernek;
dernek.uye_sayisi=1;
dernek.uye[0].adi=?Ali Candar?;
dernek.uye[0].soyadi=?Karpuzcuoğlu?;
dernek.uye[0].tel=?02122447613?;
dernek.uye[0].dogum_yili=1971;
dernek.uye[0].adres=?Güven sitesi No:32 Bahçelievler/İSTANBUL?;

Görüldüğü gibi çok güzel bir yapı oluşturarak verilere erişimi daha anlaşılabilir şekle getirdik. Bu örnekde kullanılan ?char *değişken ismi? komutu ile bir kelime tanımladık. Bunun ayrıntılarını pointer ( işaretçiler ) bölümünde ele alacağız. Ayrıca string?ler bölümünde de bu konu detaylı olarak incelenecektir.
?char *değişken ismi? deyimiyle tanımlanan bir kelimeyi ekrana printf komutuyla yazdırmak için %s operatörü kullanılır.

CODEprintf(?%s?,değişken ismi);

scanf ile klavyeden kelime almak için yine %s operatörü kullanılır ve diğerlerinden farklı olarak atama operatörü kullanılmaz. Bunun nedenleri pointer bölümünde anlatılacaktır.
 
Üst