13 Eylül 2012 Perşembe

2012 KPSS Güncel Konular



C++ Ders Notları


C++ ile Programlama Ders Notları

1.Hafta (21.02.2012)

C++’ın Programlama Dilleri Arasındaki Yeri

Bilgisayar dünyası 1960’lardan bu yana pek çok dille tanıştı. Başlangıçta herşey 1’lerden ve 0’lardan meydana geliyordu. O zamanlar “komut” kavramı bile gelişmemişti. Bilgisayara komut vermek için daha önceden belirlenmiş sayılar kullanılıyordu. O zamandan bu zamana temel programlama mantığında çok fazla bir değişim olmadı. Değişen ve gelişen programlama dilleri oldu. Bu programlama dilleri yakın bir zamana kadar teknolojiden bağımsızken günümüzde tek başlarına pek bir anlam ifade etmiyorlar. Yeni çıkan bir programlama dili genellikle başka bir dilden hareketle yazılmış oluyor. “Makine Dili” hariç bütün diller başka bir dil temel alınarak yazılmıştır ve hepsinin temeli “Makine Dili”ne dayanır. Peki C++ bu dillerin içinde nerede ve eğer ana programlama dilimiz makine diliyse, neden yabancı bir dile ihtiyaç duyuyoruz? Şimdi bu sorulara yanıt arayalım...

Makine dili en hızlı, bilgisayar kaynaklarına doğrudan erişimi sağlayan ancak o oranda da ilkel bir dildir. Bu cümledeki zıtlığı yaratan “ilkel” kavramıdır. Ancak burada kullanılan ilkel kelimesi hiçbir şekilde makine dilinin tercih edilmemesi gerektiğini ifade etmez. Hatta mümkün olduğunca makine dili kullanmak çok daha “kaliteli” sonuç verecektir. Ne yazık ki makine dili kullanımı birçok proje için çok zor, zaman zaman işkencedir. Değişken sayısının çok az oluşu, matematik işlemlerinin yetersizliği, komutların kısa ve karmaşık isimlendirilmesi, bazı komutların bazı alanlarca sınırlandırılmaları, ilkelliği oluşturan temel nedenlerdir.

Makine dili kullanılarak, önceleri daha kullanışlı makine dili editörleri programlandı. Bunlarda artık sadece sayılardan oluşan adresler yerine yavaş yavaş “label” yani “etiket” diye isimlendirdiğimiz harflerden oluşan tanımlama satırları eklendi. Zamanla makine dilinden programlanan bazı program parçalarını, tek bir komut halinde kullanan, ileri düzey diller geliştirildi. Şu anda dünyada 100’lerce programlama dili var. Özel amaçlı ve genel amaçlı 10’larca dil büyük kitlelerce kullanılıyor. Bunların hepsinin bir tek ortak özelliği var: yazılan programı makine diline çevirir ya da doğrudan makine dilinden komut komut çalıştırır. Bu işi rakipsiz denebilecek kadar iyi yapan tek dil ise C++. C’ye rakip diller ya yine C kullanarak yazılmıştır, ya da C’nin türevlerinden biridir. Kısaca özetlemek gerekirse, C++ hem ileri düzey kullanım rahatlığına sahip hem de oldukça hızlı bir dildir.

DEĞIŞKENLER
1)İngiliz alfabesindeki
2-) Rakamlar başa gelmez
3-) Derleyici büyük ve küçük harf arasında ayırım yapar
Sayı, SAYI à bu iki tanımlanan değişken aynı değildir
4-) İki alt çizgi veya bir alt çizgi ve sonra gelen büyük harfle başlayan isimler derleyici tarafından özel amaçlar için kullanılır.
5-) Tek bir alt çizgi karakteri ile başlayan isimler uygulamalarda genel belirleyiciler olarak kullanılmak üzere ayrılırlar.
6-) İsimler, istenilen uzunlukta olabilir fakat isimdeki kaç karakterin değerlendirileceği derleyiciye bağlıdır.
7-) Ayrılmış kelimeler belirleyici olarak kullanılamaz. Ayrılmış kelimelerin yerine anahtar kelimeler sözü de kullanılmaktadır.

C++ Programlama Dilinin Genel Yapısı
3.1. Basit Bir C++ Programı

C++’ın temelleri 1960’ların sonları ve 1970’lerin başlarına dayansa da bu dilin C++ adını alması çok daha sonra gerçekleşmiştir. 1970’lerin ve 1980’lerin favori programlama dili C birçok bakımdan ‘kusursuz’ denilebilecek kadar iyi bir dil idi. Ancak insanoğlu doğası gereğince hep daha fazlasını isteyerek sonunda C++’a ulaştı. BASIC gibi düşük seviyeli dillerde bir ‘x’ değişkeninin değerini bir arttırmak için ‘x = x + 1’ yazmak yerine C++’da ‘x++’ yazmamız yeterlidir. C’nin yapısı gereği ‘x += 1’ demek de x’i bir arttırmaktır. Ancak sayıları birer birer saydırmak programcılıkta çok sık karşılaşılan bir durum olduğu için bu ‘++’ ifadesi kullanılmıştır. ‘++’ bir sonraki anlamına geldiği için de C’nin bir üst versiyonu C++ ismini almıştır. Şimdi bir C programının genel yapısını inceleyelim.

1) İçerikler (include)
2) Tanımlamalar (define)
3) Fonksiyonların Tanımlamaları (function prototypes)
    Global Değişkenler (global variables)
4) Ana Fonksiyon (main function)
    Diğer Fonksiyonlar (functions)

Burada 1. ve 2. kısımlar C++ komutları değildir. Bunlar compiler’a (C++ derleyicisine) gönderilen komutlardır. Bu komutların başına ‘#’ işareti konulur. Bu işaret çok önemlidir çünkü ‘if’, ‘else’ gibi hem C++ hem de compiler komutu olan bazı ortak komutlar mevcuttur. Bu komutların kullanım biçimi şu şekildedir:

#include <dosya ismi>
#define tanım kalıp

‘#include’ komutu C++’ın içinde gelen birtakım kütüphanelerin (library) başlık (header) dosyalarını programa ekleyerek bu kütüphanelerde yer alan bilgileri kullanmamızı sağlar. Bu header dosyaları .h uzantısına sahiptir. ‘stdio.h’, ‘conio.h’, ‘math.h’ gibi C++’ın içerisinde gelen birtakım hazır kütüphane başlık dosyaları mevcuttur. Bunun yanısıra C programcısı kendi kütüphanesini kendisi de yaratabilir ya da büyük projelerde programın uzunluğundan dolayı tanımlamalar için başlık dosyalarını kullanmayı tercih edebilir. Dosya isminin iki yanına < ve > işaretleri koyarsak derleyici yalnızca kendi ‘include’ klasöründeki başlık dosyalarını arayacaktır. Eğer <.....> yerine tırnak işareti kullanacak olursak, derleyici öncelikle o anda bulunduğumuz projemize ait klasörün içinde belirttiğimiz dosyayı arayacak, bulamazsa o zaman kendi ‘include’ klasörüne bakacaktır. Kısaca “.....” şeklindeki kullanımı kendi yarattığımız header filelar için kullanıyoruz. Örnek:

#include <stdio.h>
#include <conio.h>
#include “tanimlar.h”
C ve C++ arasındaki farklardan biri de C++’ın içerisinde standart C’de gelenden daha fazla kütüphane fonksiyonu gelmesidir. Örneğin bundan önceki konudaki örnek programda kullandığımız ‘stdio’ kütüphanesi bir C kütüphanesidir. C++, C’nin tüm kütüphanelerini  bulundururken, aynı zamanda onların bazılarına alternatif kütüphaneler de içerir. “Merhaba Dünya!!!” örneğini ‘stdio.h’ yerine bir C++ kütüphanesi olan ‘iostream.h’ kullanarak da yazmamız mümkün. Bu sefer ‘printf’ yerine ‘iostream’in komutu olan cout’u kullanacağız. ‘cout’ ‘printf’e göre daha basit bir kullanım biçimine sahiptir.

cout << “text” << değişken << özel tanımlamalar


‘#define’ ise programın içerisinde defalarca kullandığımız kalıpları kısaltmamıza ve programda bazı terimleri daha anlaşılır biçimde kullanmamıza imkan tanır. Örneğin trigonometrik fonksiyonlarla dolu bir program yazıyorsunuz. Burada π sayısı defalarca tekrarlanacaktır. Her seferinde 3.1415926535 yazmak hem sizi uğraştıracaktır hem de programı daha karışık bir hale sokacaktır. Bunu engellemek için şu şekilde bir tanımlama yapabiliriz:

#define PI 3.1415926535


C++’da ki dosyalar, kaynak dosyalar(.cpp), projeler(.cproj) veya (.cbproj) benzeri uzantıya sahiptir. En kısa program örneği olarak;

int main()
{}


C++’da ki main fonksiyonu, programlama dilinde kullanılan program anahtar kelimesinin yerini alır.

#include <iostream.h>

    void main()
    {
          cout << "Merhaba Dunya!!!";
    }


İo stream başlık dosyası diğer programlama dillerinde ekrana yazdırma ve ekrandan okuma işlemleri için, read, readln, write, writeln prosedürleri vardır. C++ programlama dilinde ise giriş çıkış işlemlerini doğrudan gerçekleştiren özel ifadeler yoktur. Bu yüzden, ister klavye, ekran dosya arasında olsun giriş çıkış işlemleri akış(stream) olarak adlandırılan sınıfların(class) nesneleri(object) aracılığıyla gerçekleştirilir. Örneğin, en basit giriş çıkış işlemleri olan ekrandan okuma ve ekrandan yazdırma işlemleri(console) işlemleri iostream sınıfının cout ve cin isimli nesneleri aracılığıyla gerçekleştirilir. İostream sınıfı iostream isimli başlık dosyasında kayıtlıdır. Bu olmadan derleyici
a-      çıkış için kullanılan cout nesnesini ve << ekleme
b-      giriş için kullanılan cin nesnesini ve >> çıkarma işlemcisini tanımaz.
Bu yüzden, iostream isimli başlık dosyasının programının başına eklenmesi gerekir. #include ön işlemci bildirisi derleyiciye bu dosyaları derlemeden önce bu dosyalara iostream isimli başlık dosyasını eklemesini söyler. İostream gibi bir çok başlık dosyası vardır. Akış(stream), sınıf(class) ve nesne(object) kavramları başlık dosyası olarak kullanılabilir.



main Fonksiyonu

int main()
{
İfadeler
Return 0;
}

1-      int main() fonksiyon başlığıdır. Bu fonksiyonun { ile gövdesi oluşturulur. Bu ifadelerin her birinin sonunda noktalı virgül(;) işareti bulunur. Main fonksiyonundan önce gelen int kelimesi fonksiyon çağırıldığında çağıran programa dönen sonucun tam sayı tipinde olması gerektiğini belirtir. İnt main(void) şeklinde yazıldığında void kelimesi fonksiyonun argümanının olmadığını gösterir.
2-      Cout << “Merhaba Dünya!!! \ n”;
Satırı ekrana Merhaba Dünya!!! Yazar.
Cout teriminden sonra gelen << işareti işlemcisi ekrana yaz anlamındadır.
Cin >> a;  ifadesi de a isimli değişkenin değerini ekrandan okutur. Cin’den sonra gelen >> işlemcisi çıkarma işlemcisidir. Ekrandan oku anlamına gelir.
\n kursörün bir alt satırın başına geçmesini sağlar.
Return 0; ifadesi de fonksiyonun çağıran programa döndüreceği değerin 0 olduğunu gösterir. Dönüş değerinin 0 olması fonksiyonun derlenmesinin, başarılı olduğunu işletim sistemine bildirmesini ifade eder. 0’dan farklı dönüş değeri, hata anlamına gelir.

Örnek 2 ;

#include <iostream>
using namespace std;
int main()
{      cout << " Hosgeldiniz!\n";
        int a; cin >> a;
        return 0;
}

Örnek 3 ;

#include<iostream.h>
int main()
{
      cout << "A E I" << endl;

      cout << "B D F" << endl;
      return 0;
}


ÖDEV 1: Ekrana aşağıdaki çıktıyı veren programı yazınız

  ***   ***
  ***   ***
  ***   ***
      ***
      ***
      ***

ÖDEV 2: Ekrana aşağıdaki çıktıyı veren programı yazınız

  *** ANKARA ***
  *** İSTANBUL ***

Fonksiyonlar

Fonksiyonlar, en önemli bloklardan biridir. Fonksiyonun tanımlandığı bloğa fonksiyon bloğu denir. Fonksiyon bloğunda,
1-      Fonksiyonun adı (main)
2-      Fonksiyonun adından sonra gelen () lerinin içine yerleştirilen argüman listesi
3-      Fonksiyonun adından önce gelen bir dönüş veri tipi (int)
4-      Fonksiyonun gövdesi olarak adlandırılan küme parantezleri arasında yer alan kısım
5-      Fonksiyon gövdesinden sonra noktalı virgül yazılmaz.
. Programa açıklama satırı yazmanın iki yolu vardır.

1) İki tane düz slaş karakteri (//) kullandığımız taktirde bunların sağ tarafında kalan alan compiler tarafından atlanır. Bu yalnızca bulunduğu satır için geçerlidir.
            2) Düz slaştan sonra çarpı kullanırsak (/*) compiler çarpıdan sonra düz slaş (*/) görünceye kadar bloğun tamamını atlar. Bu tek satır için değil bütün program alanı için geçerlidir.


Fonksiyonlar içinde kullanılan ifadeler,  basit ifadeler ve basit olmayan ifadeler olarak ikiye ayrılır.

1-Basit İfadeler:  
int a;
a=12; è atama ifadesi
yıldız yaz (); è fonksiyon çağırma ifadesi
go to son; è go to ifadesi

2-Basit Olmayan İfadeler:  
Birleşik ifadeler
int x;
x=x+10;

Seçme İfadeleri
1-      İki durumdan birini seçme
if (x>0)   y=sqrt(x);

2-      İki şeyden birini seçme
if(x>y)   y=sqrt(x-y);
else   y=sqrt(y-x);




3-      Çok şey arasından birini seçme
Notu=65;
Switch(nout)
{     case 45 : cout << “45”; break;
       case 60 : cout << “60”; break;
       case 85 : cout << “85”; break;
       default  : cout << “??”; break;
}
  SAYI SİSTEMLERİ ve BELLEK YAPISI

Bu bölümde bilgisayarın bellek yapısını inceleyeceğiz. Bu yapıyı kavrayabilmek için öncelikle bazı sayı sistemleri hakkında bilgi edinmemiz gerekiyor.



Daha önce de söylendiği gibi bilgisayar için en uygun sayı sistemi sadece iki rakamı (0 ve 1) olan ikili sayı sistemidir. Aslında bilgisayar 1 ve 0’ın ne olduğunu “bilmez”. En eski yarı mekanik hesap makinelerinden günümüzdeki mikroçip teknolojisinin en üst düzeyde kullanıldığı elektronik bilgisayarlara kadar bütün bilgisayarlar olup bitenleri tek bir sorgulamayla anlar. “Devre açık mı, kapalı mı?” yani “Elektrik akımı geçiyor mu, geçmiyor mu?”. “Devre açık” yani “akım geçmiyor” durumunu “0”; “devre kapalı” yani “akım geçiyor” durumunu da “1” ile temsil ederiz. Burada “0” bilgi yok, “1” ise bilgi var anlamındadır. O halde, örneğin 137 sayısını 1 ve 0’ları kullanarak nasıl ifade edeceğiz.

 Sayı Sistemleri

 İkili Sayı Sistemi, BIT ve BYTE Kavramları

İ. Bizim kullandığımız sayı sistemi on tabanında yani onlu sayı sistemidir.

ikili tabanda bir örnek çözelim ve sonra bu tabanın özelliklerini inceleyelim.

(101011)2 = (1 * 20) + (1 * 21) + (0 * 22) + (1 * 23) + (0 * 24) + (1 * 25)
(101011)2 = (1 * 1) + (1 * 2) + (0 * 4) + (1 * 8) + (0 * 16) + (1 * 32)
(101011)2 = 1 + 2 + 8 + 32
(101011)2 = 43

İkili sayı sisteminde 0 ve 1 harici bir rakam kullanılamayacağı için pratikte işlemlerin ilk iki aşamasını atlamak mümkün. İkili düzende verilen sayının basamaklarını sağdan sola doğru 1’den başlamak suretiyle 2’nin üsleri şeklinde sayıp 0 olanlarını atlar, 1 olanları toplarsak sayıyı onlu olarak elde ederiz.
“Bütün pozitif tamsayılar 2’nin pozitif tamsayı üstlerinin toplamından elde edilebilir.”

Daha önce de belirtildiği gibi bellek byte’lardan oluşmuştur. Ancak byte’ların sayısı arttıkça hesap kolaylığı için üst birimler tanımlanmıştır. Tıpkı gram, kilogram gibi byte da başına kilo (bin), mega (milyon), giga (milyar), tera (trilyon) gibi ekler alır. Ancak byte’lar ikili sistem üzerine kurulduğu için gramda olduğu gibi 1000’er 1000’er değil, bunun yerine 2’nin 1000’e en yakın üssü olan 210 = 1024’er 1024’er artarlar.

1 TeraByte = 1024 GigaByte
1 GigaByte = 1024 MegaByte
1 MegaByte = 1024 KiloByte
1 KiloByte = 1024 Byte

Ara dönüşümler de klasik yöntemle hesaplanabilir.

1 MegaByte = 1024 x 1024 Byte = 1048576 Byte
1 TeraByte = 1024 x 1024 x 1024 KiloByte = 1073741824 KiloByte

Bellek birimleri de ağırılık, uzunluk birimleri gibi kısaltmalara sahiptirler.

TeraByte = TB
GigaByte = GB
MegaByte = MB
KiloByte = KB

Byte genellikle B diye kısaltılmaz ve “byte” şeklinde kullanılır.




TEMEL VERİ TİPLERİ


1-      Tam Sayı Veri Tipleri :  C++’da; bool, char, short, int ve long gibi tam sayı veri tipleri bulunur. Basit veri tipli değişkenler sadece bir değer taşıyabilirler.

int a;
a=4321;

bu tam sayı 4 byte’lık bellek alanına yerleştirilmiştir.
İşaretsiz tam sayılarda, başına unsigned deyimi getirilir. Böylece unsigned char, unsigned short, unsigned int ve unsigned long veri tipleri elde edilir.
Tablo 1 Tam sayı ve Ondalık sayı veri tipleri

Veri Tipi
Alt Sınıf

Üst Sınıf

Duyarlı Basamak Sayısı

Bellek Alanı (byte)

Bool
False
True
yok
1
Char
-128
127
Yok
1
Short
-32768
32767
Yok
2
İnt
-2147483648
2147483647
Yok
4
Long
-2147483648
2147483647
yok
4





Float
3,4x10^-38
3,4x10^38
7
4
Double
1,7x10^-308
1,7x10^308
15
8
Long double
3,4x10^-4932
3,4x10^4932
19
10
Tablo 2 İşaretsiz Tam Sayı Veri Tipleri
Veri Tipi
Alt Sınıf
Üst Sınır
Bellek Alanı (byte)
Unsigned char
0
255
1
Wchar_t
0
32767
2
Unsigned short
0
65535
2
Unsigned int
0
4294967295
4
Unsigned long
0
4294967295
4
Yazacağımız programda, sayıların tiplerini doğru kullanırsak programımız daha hızlı çalışır ve aynı zamanda bellekte bizim kullanmamız için daha çok yer kalır. Yazacağımız syı ondalık sayı ise program yavaş çalışır.

SAYILAR
a) Kayan Noktalı Sayılar (Floating Point Numbers)
a1- long (Uzun kayan noktalı sayılar)
a2- double (Çift Duyarlı kayan noktalı sayı)
b) Tam Sayılar (Integers)
b1- int (Normal Tam sayı)
b2- short( Kısa Tam sayı)
b3- long ( Uzun Tam sayı )
b4- char (Karakter)
b5- İşaretsizler (Unsigned)
b5.1- unsigned int ( İşaretsiz tamsayı)
b5.2- unsigned short (İşaretsiz kısa tamsayı)
b5.3- unsigned long ( İşaretsiz uzun tamsayı)

Örnek: 5000000000 ( Beş milyar )
Bu sayı, unsigned int veya long olarak verilir. Bu sayının büyüklüğü, 4milyar basamağındadır. ( 4 294 467 295)… Yani 5 milyar sayısını tam sayı olarak ifade edemeyiz. Ondalık sayı veri tipi olarak kullanılarak çözülür.
Örneğin, 2.23 à 2,23e+0
1230000 à 1,23e+6
0.00000123 à 1,23e-6

Örnek:
float deg2;
deg2= 1.6e-19;

Bu sayı 4 byte’lık bellek bölgesine yerleştirilir.


deg2 değişkeni
Bellek alanı




Bellek alanı
Dört byte











Karakter veri tipi ve küçük tamsayılar

Karakter veri tipi, char, harf ve rakamları saklamak için kullanılır. ASCII karakter kodları ve benzer kodlama sistemleri geliştirilmiştir. ASCII kod sisteminde “a” karakteri 97 sayısıyla temsil edilir.

Örnek: char tipindeki karakter değişkeninin bellekteki yerleşimi

Kar = “a”
İfadesindeki “a” karakterinin ASCII karakteri kodu 97’dir.
char değişkeni
Bellek alanı

97


Bellek alanı
Bir byte

Örnek 1: 700 tam sayısını ekrana yazan bir C++ programı yazınız..

#include<iostream.h>
int main()
{
            int a;
            a=700;
            cout<<a;
            return 0;
}

Örnek 2:  Ekrana 3*6=18 yazdıran programı yazdırınız..

#include<iostream.h>
int main()
{
      cout <<"3*6=";
      cout <<3*6;
      return 0;
}

#include<iostream.h>
int main()
{
            int a;
            int b;
            a=3;
            b=6;
            cout<<"3*6=";
            cout<<a*b;
            return 0;
}








Örnek 3: a harfini ASCII kodunu yazan C++ programını yazınız

#include<iostream.h>
int main()
{
         int ch;
         ch='a';
         cout<<"a'nin ASCII kodu ";
         cout<< ch;
         cout<<" dir";
         return 0;
}

Örnek 4: Tek duyarlı kayan noktalı (float) tipi sayılarla ilgili bir örnek program yazınız. Örneğin, a=8.909 olan…

Örnek 5: char veri  tipli bir büyüklüğün int veri tipli bir değişkene atanması, int verip tipli bir büyüklüğün karakter veri tipli bir değişkene atanması örneği


#include<iostream.h>
int main()
{
      char ch1= 'A';
      cout << " ch1= " << ch1 << "\n\n";
      char ch2= '\t';
      cout << "Tab karakterinin etkisine dikkat!"
                  " A nin yazildigi yere bak!\n"
                  <<"\n"<< ch2;
      int i = ch1;
      cout << ch1 << " nin ASCII karakter kodu : " << i;
      i= ch1;
      cout << "\n\n Bir karakter gir : "; cin >> ch1;
      i=ch1;
      cout << " \n Karakterin ASCII kodu : " << i;
      cout << " \n\n Kucuk bir tam sayi gir : "; cin >> i;
      char ch3 = i;
      cout << "\n\n Tam sayinin ASCII karakteri : " <<ch3;
      cin >> ch1;
      return 0;
}
1-)B değişkenine 1000 değerini atayıp,bu sayıyı ekranda görünteleyiniz.

2-)Bir üçgenin taban kenarı 12.8  yüksekliği 2.01 cm’dir,alanını hesaplayınız.

3-)Ekrana ANKARA yazdıran programı yazın(char türü değişken kullanarak)

4-)x=298 olarak verildiğine göre x/60 ve x%60 işlemlerini yapan programı yazınız.

5-) Ekrana ATA yazdıran program yazın(ASCII kodlarını kullanarak).


















2.Hafta

İşaretli ve İşaretsiz Tam Sayılar

Tamsayı işaretli olarak tanımlanmışsa, derleyici sayının en yüksek değerli bitini işaret biti olarak kabul eder. İşaret biti 0 ise sayı artı, 1 ise eksi olarak işlem görür. İşaretsiz kısa tam sayı, bellekte 16 bitlik yer kaplar. 16 bit, onluk sayı sisteminde 65535 sayısal değerine karşılık gelir. 65535 değeri bellekte 16 bitlik bir sayının en büyük değeri olması için en soldaki biti 0, diğer tüm bitlerin 1 olması gerekir. Bu durumda, sayının alacağı en büyük değer 32767 ‘dir.




          0 1 1 1   1 1 1 1   1 1 1 1   1 1 1 1   à +32767        işaretli tamsayı
          1 0 0 0   0 0 0 0   0 0 0 0   0 0 0 0   à -32767         (signed int)

“char” (karakter veri tipi)

Tek bir karakter saklanmak istendiğinde, değişken türü char olarak bildirilir. Karakter veri türü, bellekte 1 byte’lık yer işgal eder.

#include <iostream.h>
int main()
{
         char ch;
         ch='B';
         cout <<"ch'nin degeri "<<ch;
         return 0;
}






Amerikan Ulusal Standartlar Enstitüsü tarafından her bir karakter standart olarak sayısal bir kodla gösterilir ve bu koda ASCII kodu denilir.

ÖRNEK : Bir firma gidiş dönüş otobüs bileti alındığında bilet fiyatı üzerinden %20 indirim yapmaktadır. İndirim uygulanmamış bilet ücreti, 10,000,000 TL olduğuna gör e, yapılan indirimin ve indirim yapılmış bilet ücretini bulunuz. (Çift duyarlı kayan noktalı sayılar “double” sayılara örnek)

#include <iostream.h>
int main()
{
         double bilet,indirim,in_fiyat;
         bilet=10000000;
         indirim=(bilet*.2);
         in_fiyat=bilet-indirim;
         cout << "indirim ";
         cout << indirim<<"Tl'dir";
         cout <<"\n indirilmis fiyat ";
         cout << in_fiyat<<" Tl'dir";
         return 0 ;
}




Değişkenlere değer verilmesi

1-
int a;
a=10;

2-

char harf;
harf=’B’;


C++ programlama dilinde karakterlerin saklanması için özel bir veri türü yoktur. Bunları saklamak için, karakter türü bir boyutlu dizi oluşturulur. Dizi, aynı türdeki veri elemanlarının art arda gelmesinden oluşur. Örneğin, “ANKARA” katarını, bellekte saklamak için maksimum 11 elemanlı bir dizi oluşturulur.
dyer[0]=İ[0]=A
İ[1]=N
İ[2]=K
İ[3]=A
İ[4]=R
İ[5]=A
İ[6]=\0
... İ[10]

ÖRNEK: Doğum yeri giriniz. Girilen doğum yerini ekrana yazan programı yazınız.

#include <iostream.h>
int main()
{
         char dyer[10];
         cout << "Dogum yerini giriniz \n";         cin>>dyer;
         cout<<" dogum yeriniz";
         cout<<dyer;
         return 0;
}












ÖRNEK: Doğum yerinizin ilk harfini yazan programı yazınız.

#include <iostream.h>
int main()
{
         char dyer[10];
         cout<<"Dogum yerini giriniz\n";
         cin>>dyer;
         cout<<" dogum yeriniz"<<dyer;
         cout<<"\n dogum yerinizin ilk harfi..";         cout<<dyer[0];
         return 0;
}

ÖRNEK: “ANKARA” katarını ekrana yazan bir program hazırlayınız
#include <iostream.h>
int main()
{
         char dyer[]="Ankara";
         cout<<" dogum yeriniz " <<dyer<<"dir";
         return 0;
}

ÖRNEK: “strcpy” dizi kopyalama komutunu kullanarak “ANKARA” katarını “dyer” değişkenine kopyalayan programı yazınız.

#include <iostream.h>
#include <cstring>
int main()
{
         char dyer[10];
         strcpy(dyer,"Ankara");
         cout << dyer;
         return 0;
}













ARİTMETİK İŞLEMCİLER

X=10 ve Y=3 değerleri için X’i Y’ye bölmenin sonucun ve artık bölme işleminin (mod) sonucunu veren programı yazınız. - Artık bölme için “%” sembolü kullanılır. -

 #include <iostream.h>
int main()
{
         int x, y;
         x=10;
         y=3;
         cout << "Bolmenin sonucu" << x/y<<endl;
         cout << " Artik bolme isleminin sonucu " << x%y ;
         return 0;
}

ÖRNEK: Çift duyarlı kayan noktalı sayı “double” ya da  tek duyarlı kayan noktalı sayı (float) veri türleri için, “fmod()” fonksiyonunu kullanan bir örnek yazınız. x =18 y=4 için.

#include <iostream.h>
#include <math.h>
int main()
{                                                                      
         double x,y;
         double z;
         x=18;
         y=4;
         z=fmod(x,y);
         cout << "Artik bolme isleminin sonucu bolmenin sonucu " <<z;
         return 0;
}


Bit İlişkili (Bitwise) İşlemciler

SİMGE
İŞLEMCİ
& (ampersand)

VE (AND)
|
VEYA (OR)
^
ÖZEL VEYA (XOR)
!
DEĞİL (NOT)
<< 
Bir bit sola kaydır.
>> 
Bir bit sağa kaydır.
Bunları içeren bir örnek;
#include <iostream.h>
int main()
{
         int a=24, b=12;
         int c,d,e;
         c=a&b;
         d=a^b;
         e=a|b;
         cout <<"a&b="<<c<<endl;
         cout <<"a^b="<<d<<endl;
         cout <<"a|b="<<e<<endl;
         return 0;
}


0001 1000 à 24
0000 1100 à 12

0 1000 a&b=8 AND
1 0100 a^b=20 XOR
1 1100 a|b=28 OR

Sağa (>>) ve Sola (<<) kaydırma işlemleri

a>>4 ç Kaymanın kaç basamak olduğunu gösterir

Örneğin, 1331 sayısını iki basamak sola kaydırma işlemini yapan



8192
4096
2048
1024
512
256

128
64
32
16        

8
4
2
1



=1331
  0   0  0  0
 0   1   0    1
 0   0   1   1
      0   0   1   1

 0    0
0  0      0    1
0    1     0   0
1   1          0   0
1   1     0     0
=5324




    4096

1024
128
64
8
4


İki basamak sol kaydırılmak istenildiğinde, tüm bitler iki basamak sola ötelenecektir. Ve yeni sayıda ötelemeden dolayı ortaya çıkan boşluk iki sıfır eklenerek doldurulacaktır. Böylece, bitlerin konumu değişecektir. Örneğin, önce değerlikleri sırasıyla 1 ve 2 olan bir değerlikli ilk 2 bitin değeri, yeni durumda 4 ve 8 olacaktır. Bu durum, tüm bitler için geçerlidir. Yeni sayı önceki değerden büyük olacaktır. Sola kaydırma işlemi sonucunda, kaydırılan sayının alacağı değer bulunurken 1 bitlik sola kaydırma sayısının 2^1=2, iki bitlik sola kaydırma işleminin tekrar ikiyle çarpılması ile bulunur  2^2=4. Burada ise 1331 * 4 = 5324 olarak bulunmuştur.


ÖRNEK: İki basamak sağ ve sola kaydırma yapınca elde ettiğimiz sonucu yazan bir program.
#include <iostream.h>
int main()
{
         int x,y,z;
         x=1331;
         y=x<<2;
         z=x>>2;
         cout <<"x in iki basamak sola kaydirilmisi"<<y<<endl;
         cout<<"x in iki basamak saga kaydirilmisi"<<z;
         return 0;
}

İlişkisel İşlemciler

= = eşit anlamındadır.
!= eşit değil anlamındadır.

Mantıksal İşlemciler

&&
VE (AND)
||
VEYA (OR)
|
DEĞİL (not)

ÖRNEK : (a<b || x<y) ifadesini yazan programı yazınız.

#include <iostream.h>
int main()
{
         int a=10, b=2;
         int x=1, y=5;
         if(a<b || x<y)
                     cout<<"Karsilastirma dogru";
         return 0;
}




ÖZEL İŞLEMCİLER: C++ birçok özel işlemciye sahiptir;artırım ve eksiltim
,işaretçi (pointer),ilişkili işlemci,virgül,cast ve sizeof dur.

Artırım ve Eksiltim : Artırım(++) ve eksiltim(--) işlemcilerine sahip olmasıdır.Eksiltim işlemcisi değişkenin değerini bir azaltırken artırım işlemcisi de değişkeninin değerini bir çoğaltır.
  
                X++;


                 X=X+1;

                X--;

                 X=X-1;



X++ deyiminde önce x değişkeni kullanılır sonra artırma işlemi yapılır.++X deyiminde ise önce artırma işlemi yapılır,sonra X değişkeni kullanılır.

Örnek

#include<iostream.h>
int main()
{
int a,b;
a=7,b=7;
cout<<"a="<<++a<<endl;
cout<<"b="<<b++;
return 0;
}

Sonuç
a=8:b=7

Virgül  İşlemcisi

Virgül işlemcisi virgül ile ayrılan birden çok deyimin tek bir deyim gibi değerlendirilmesini sağlar.Virgülün sol yanında kalan deyimler kendi başlarına ifade edilebilir.


Örnek

a=(x=15,x+5): bu ifadeyi çalıştıran programı yazınız.

#include<iostream.h>
int main()
{
         int a,x;
         a=(x=15,x+5);
         cout<<"a degiskenin degeri"<<a;
         return 0;
}

a=20

Kalıp(Cast işlemcisi)

Değişkenlerin veri türlerini kalıp(cast işlemcisi) ile değiştirebilirsiniz.İki türlü yapılır ;açık(explicit) veya örtük (implicit).


Bir tamsayı değerini kayan noktalı double(sayı) değerine çevirip,ekranda kayan noktalı değer sonucunu  veren bir örtük kalıbına bir örnek yazınız.

ÇÖZÜM:örtük kalıba örnek

#include<iostream.h>
int main()
{
         int a=6;
         double b=2.4;
         float c;
         c=a+b;
         cout<<c;
         return 0;
}
8.4

Açık kalıp işlemi

Genelde açık kalıp işlemi tercih edilir.Bu tür tanımlamada değişkenden önce tür ismi yazılır.Bununla ilgili bir örnek yazınız.

Örnek;


#include<iostream.h>
int main()
{
         double a=2.5,b=5.2;
         int c;
         c=(int)a+int(b);
         cout<<"c isleminin sonucu"<<c;
         return 0;
}
7
Sizeof()  işlemcisi :

Sizeof işlemcisi herhangi bir değişken türünün bellekte kaç bayt yer kapladığını belirtir.

Kullanım biçimi ;

Sizeof(değişken adı)   , sizeof(veritürü)

Örnek;

Sizeof(a) ifadesi ile a değişken türü olan tamsayı(int) veri türünün sizeof(d) ile d değişken veri türü olan uzun tamsayı(long) veri türünün bellekte kapladığı yer bulan programı yazınız.

#include<iostream.h>
int main()
{
   int a=4;
   double b=6.0;
   short c=2;
   long d=6;
   double e=7.0;
   cout<<"tamsayinin(integer) tuttugu yer"<<sizeof(a);
   cout<<"\n kisa tamsayinin(short) tuttugu yer"<<sizeof(c);
   cout<<"\n uzun tamsayinin(long) tuttugu yer"<<sizeof(d);
   cout<<"\n cift duyarli kayan noktanın sayinin tuttugu yer"<<sizeof(b);
   cout<<"\n cift duyarli kayan noktanın sayinin tuttugu yer"<<sizeof(e);

   return 0;
}
4,2,4,8,8

Örnek;


#include<iostream.h>
int main()
{
   signed long int a=25000;
   int b=3;
   int c;
   c=(a*b)/5;
   cout<<"sonuc"<<c;
  
   return 0;
}




Örnek;
#include<iostream.h>
int main()
{
   int a=9;
int b=0;
int c;
c=a/b;
cout<<”sonuc”<<c;

return 0;
}

Divide = ERROR hatası verir.


Önişlemci Komutları
ANSI C’de bulunan önişlemci komutları şunlardır:

   #define        #if              #pragma
  #endif         #ifdef         #undef
 #elif           #ifndef       #else
#include    #error        #line


   #define    önişlemcisi

    ÖRNEK;

   #define        KUP((a)*(a)*(a))
   #define        ON           10
   #define        PI              3.14
   #define        SABIT       0.55      






Ödev;
 
1-) #define        önişlemcisi kullanarak pi sayısını 3.14 olarak programın başında tanımlayarak dairenin alanı ve çevresini bulan programı yazınız.(r=5)

2-)a=(x=10,x+15) işlemini yaptıran programı yazınız.
3-)a=8 b=3 olarak verildiğinde bu sayılarla ve(&) ,or(|) işlemini gerçekleştiren programı yazınız.
4-)3840 sayısını önce iki basamak sola sonra da iki basamak sağa kaydıran programı yazınız.
5-)a=5,b=4 ise a<b,a<=b,a>b,a>=b,a==b,a!=b işlemlerini gerçekleştiren programı yazınız.


#include ön işlemcisi

Derleyicinin, özel ek dosyaları okumasını ister. Ek dosyalar, kaynak dosyaların bir parçasıdır. Genellikle programın başındaki #define ön işlemcisini, #include dosyasından ayırmamız gerekebilir. #include ile #define dosyasını ayırmamız gerekebilir.

#define RT ( (1/r1) + (1/r2) )
#include <iostream.h>
int main()
{
       float r1,r2,rtp;
       cout<<"r1 direncini girin";
       cin>>r1;
       cout<<"r2 direncini girin";
       cin>>r2;
       rtp=1/RT;
       cout<<"paralel es direnc dir.\n"<<rtp;
       return 0;
}

Not : Bu örnekte kullandığımız program üzerinde değişiklik yaparak bir başlık (header “.h”) dosyası oluşturalım. Bunun için derleyicide NEW seçeneği seçilip “#define RT ( (1/r1) + (1/r2) )” satırını yazdıktan sonra sürücüye “.h” uzantısıyla kaydetmemiz gerekir. Eğer C sürücüsünde çalışıyorsak c:\RT.h olarak satırı kaydederiz. Daha sonra yeni programın içinde #include “C.RT.h” yazmamız gerekir.

#include <iostream.h>
#include <C:\DOCUMENTS AND SETTINGS\OGR\RT.h>
int main()
{
       float r1,r2,rtp,rt;
       cout<<"r1 direncini girin";
       cin>>r1;
       cout<<"r2 direncini girin";
       cin>>r2;
       rtp=1/RT;
       cout<<"paralel es direnc"<<rtp<<" 'dir";
       return 0;
}


Temel Giriş ve Çıkış Fonksiyonları

Ara Bellek ( Buffer ) : Arabellek, giriş ve çıkış fonksiyonlarının etkinliğini arttırmak için kullanılan tekniktir. Herhangi bir bilgisayar sisteminde program işletilirken programın en yavaş çalışan kısmı okuma ve yazma bölümüdür. Arabellek kullanılarak okuma ve yazma hızı arttırmaktadır. Basit olarak arabellek, çıkış cihazı yazıma hazır olana kadar veya bilgisayar bilgi girişine hazır olana kadar verilenin başka bir yerden geçici olarak saklanmasıdır. Özellikle dosya işlemlerinde arabellek çok önemlidir. Şimdilik arabelleğin sadece çıkış ve giriş işlemlerinde kullanıldığının bilinmesi yeterli olacaktır. Bu bölümde kullanılan tüm fonksiyonlarda arabellek kullanılmıştır.







Formatlı Giriş ve Çıkış İşlemleri

Biçim Tanımlayıcıları

Biçim Tanımlayıcı
Anlamı
%d
Onlu (decimal) tam sayı
%c
Tek karakter
%s
Karakter katarı
%f
Ondalıklı sayı
%e
Ondalıklı sayı (üslü gösterimi ile)
%g
%e veya %f hangisi kısa ise
%u
İşaretsiz onlu tamsayı
%o
İşaretsiz sekizli tamsayı
%x
İşaretsiz on altılı tamsayı


Örnek :

#include <iostream.h>
int main()
{
       char il[15];
       cout<<"il ismini girin \n";
       cin>>il;
       cout<<".....Cikis.....\n";
       cout<<"il:  "<<il;
       return 0;
}


Soru : Üç takımın adını ve puanlarını klavyeden girip, girdiğimiz bu bilgileri görüntüleyen bir program yazınız.                          
Programda kullanılan değişkenler
tak 1 I. Takımın Adı ---  p1 I .Takımın Puanı
tak 2 II. Takımın Adı  ---- p2 II .Takımın Puanı
tak 3 III. Takımın Adı ----  p3 III .Takımın Puanı

#include <iostream.h>
int main()
{
       char tak1[20];
       char tak2[20];
       char tak3[20];
       int p1,p2,p3;
       cout<<"Birinci takim adini ve puanini giriniz";
       cin>>tak1>>p1;
       cout<<"Ikinci takim adini ve puanini giriniz";
       cin>>tak2>>p2;
       cout<<"Ucuncu takim adini ve puanini giriniz";
       cin>>tak3>>p3;
       cout<<"TAKIM PUAN  \n";
       cout<<"------ ------ \n";
       cout<<tak1<<"\t\t"<<p1<<endl;
    cout<<tak2<<"\t\t"<<p2<<endl;
    cout<<tak3<<"\t\t"<<p3<<endl;
       return 0;
}

TAKIM         PUAN
----------          ---------   
 GS                          78
FB                           78
BT                            78













IF ve SWITCH İFADELERİNİN YAPISI

İki çeşit denetim yapısı vardır.
1-   Karşılaştırmalı
2-   Tekrarlı ( Döngü)

Karşılaştırmalı denetim Deyimlerinin Türleri

if (denetim ifadesi)
                    deyim ;

1 – “if” ifadesinden sonra parantez içerisinde yazılan ifadeyle karşılaştırma yapılmaktadır.
2 – “if” ifadesinden sonra “;” karakteri yoktur, “;” karakteri sadece deyimin sonunda vardır.
3 – Denetim ifadesi doğru iken (sıfır değilken), denetim ifadesindeki deyim işletilmektedir.

Örnek : Bir öğrencinin notu ekrandan girilmektedir. Notu 50’den büyük eşit ise ekrana başarılı yazan programı yazınız.

#include <iostream.h>
int main()
{
       int not;
       cout<<"Ogrencinin notu nedir";
       cin>>not;
       if (not>=50)
       {
                cout<<"Basarili\n";
                cout<<"Ogrencinin aldigi not"<<not;
       }
       return 0;
}

If – Else İfadeleri ( İki yollu Kontrol )

Bazı programlarda “if” ifadesindeki koşula bağlı olarak, koşul doğru ise bir deyimin, yanlış ise bir diğer deyimin işletilmesi yapılır.

Örnek : Bir öğrencinin notu ekrandan girilmektedir. Notu 50’den büyük eşit ise ekrana “başarılı”,  hayır ise, “başarısız” yazan programı yazınız.

#include <iostream.h>
int main()
{
       int not;
       cout<<"Ogrencinin notu nedir";
       cin>>not;
       if (not>=50)
       {
                cout<<"Basarili\n";
                cout<<"Ogrencinin aldigi not"<<not;
       }
       else
       {
                cout<<"Basarisiz \n";
                cout<<"Daha cok calismaniz gerekmektedir"; }
       return 0;
}













Örnek : Klavyeden girilen iki sayının, azalan ya da artan sıralama olduğunu bulan programı hazırlyınız.

#include <iostream.h>
int main()
{
       int say1,say2;
       cout<< "Iki sayi giriniz";
                cin>>say1>>say2;
       if (say1>say2)
                cout<<"Azalan siralama \n"<<say1
                <<"\t"<<say2;
       else
        cout<<"Artan siralama \n"<<say1
                <<"\t"<<say2;
       return 0;
}

Örnek : Klavyeden girilen iki sayıyı küçükten büyüğe doğru sıralayan programı hazırlayınız.

#include <iostream.h>
int main()
{
       int say1,say2,tut;
       cout<< "Iki sayi giriniz";
                cin>>say1>>say2;
                if (say1>say2)
                {
                         tut=say1;
                          say1=say2;
                          say2=tut;
                }
                cout<<"Artan siralama \n"<<say1
                          <<"\t"<<say2;
                return 0;
}


ÖDEV 1 : Bir banka 100 TL’ye kadar yapılacak havale işlemlerinde %1 komisyon, 100 TL üzerindeki havale işlemlerine %2 komisyon almaktadır. Buna göre havale bedelini girerek ödenmesi gerekli komisyon miktarını bulan programı yazınız.

SORU:Bir sınıftaki örgencilerin girilen notunu harfe çeviren programı hazırlayınız
notu<60  F
notu<74 C
notu<84 B
….A

#include <iostream.h>
using namespace std;
//========================================
int main()
{
         int notu;
         char Kar = 'a';
         cout << "ders kayidi? (e/h) : "; cin >> Kar;
         if (Kar == 'h')
         {
                   cout << "dersi secmeliydin!";
                   goto son;
         };
         cout << "notu gir :"; cin >>notu;
         if (notu<60)
         {
                   cout<< "F";
                   goto son;
         }
         else if (notu <74)
         {
                   cout << "C";
                   goto son;
         }
         else if (notu< 84)
         {
                   cout<< "B";
                   goto son;
         }
         else
                   cout <<"A";
son:
         cin >> notu;
         return 0;
}
Soru: + toplama, -çıkarma,* çarpma, /bölme yapan programı hazırlayınız

#include<iostream.h>
int main()
{
         int a=10,b=5;
         char ara;
         cout<<"İslemciyi girin";
         cin>>ara;
         if(ara=='+')
                   cout<<a<<"+"<<b<<"="<<a+b;
         else if(ara=='-')
                   cout<<a<<"-"<<b<<"="<<a-b;
         else if(ara=='*')
                   cout<<a<<"*"<<b<<"="<<a*b;
         else if(ara=='/')
                   cout<<a<<"/"<<b<<"="<<a/b;
         return 0;
}

Switch İfadeleri:

İkiden çok durum arasında birini seçmek gerektiği zaman switch ifadesi kullanılır. Bu ifade;
Switch(Tam sayı veya karakter tipli değişken)
{
Case 1: ifade;…;ifade;break;
Case 2: ifade;…;ifade;break;
Default: ifade;…;ifade;
}
SORU: Klavyeden üç sayı giriniz. Switch yapısı kullanarak 1 girdiğimizde birinci sayının karesini 2 girdiğimizde ikinci sayının karesini 3 girdiğimizde üçüncü sayının karesini bulan programı yazınız.

#include<iostream.h>
void main()
{
         int a,b,c,d,x;
         cout<<"birinci sayiyi gir";
         cin>>a;
         cout<<"ikinci sayiyi gir";
         cin>>b;
         cout<<"ücüncü sayiyi gir";
         cin>>c;
         cout<<"Tercihinizi giriniz(1/2/3)";
         cin>>x;
         switch(x)
         {
         case 1: d=a*a;
                   cout<<"Birinci sayinin karesi"<<d;
                   break;
         case 2: d=b*b;
                   cout<<"ikinci sayinin karesi"<<d;
                   break;
         case 3: d=c*c;
                   cout<<"ucuncu sayinin karesi"<<d;
                   break;
         default:
                   cout<<"Bilinmeyen islemci\n";
         }
}

SORU: Ekrandan   aldığı derslerin  harf karşılığı girildiğinde sayısal karşılığını veren programı yazın.

#include<iostream.h>
//============================================
int main()
{
         int notu;
         char Kar, harf;
         cout<<"Ders kayidi? (e/h) : "; cin>> Kar;
         if (Kar == 'h')
         {
                   cout<<"Dersi secmeliydin!";
                   goto son;
         }
         cout<<"\nHarfi gir : ";cin>> harf;
         cout<<"\n\n Girilen notun tahmin araligi : ";
         switch(harf)
         {
         case 'F' : cout<<"0...59 arasi."; break;
         case 'C' : cout<<"60...74 arasi.";break;
         case 'B' : cout<<"75...84 arasi.";break;
         case 'A' : cout<<"85...100 arasi.";break;
         default : cout<<"\Hatali Giris!"; break;
         }
son:
         cin>>notu;
         return 0;
}
Break deyimi ile switch blogundan cıkıs sağlanır.

DÖNGÜLER:

1-) for Döngüsü: for döngüsü kullanımı en kolay döngüdür. For ile başlar ardından (birbirinden “;” ile ayrılan) üç deyim gelir.
For(j=0;j<10;j++)

ÖRNEK:j nin değerini birer boşluk ara ile satıra yazdıran dongu

#include<iostream.h>
int main()
{
         int j;
         for(j=0;j<10;j++)
                   cout<<j<<endl;
         for(j=0;j<10;j++)
                   cout<<j<<' ';
         cin>>j;
         return 0;
}












ÖRNEK:

#include<iostream.h>
int main()
{
         static char blg[]="sube";
         int syc;
         for(syc=1;syc<=6;syc++)
                   cout<<blg<<syc<<"\n";
         return 0;
}


NOT: Değişkenler mümkün olduğunca küçük bellek alanı kaplamalıdır. Fonksiyonlarda ana programa değer aktarması yaparken extern anahtar sözcüğü kullanarak dışsal tanımlamalar tercih edilir. Dört tane saklama sınıfı vardır.

Saklama sınıf
Anahtar sözcük
Süreklilik
Alan
Otomatik
auto
geçici
Yerel
Dışsal
extern
kalıcı
Genel
Statik
static
kalıcı
Genel
Yazmaç
register
geçici
Yerel

Static char blg[6]=”sube”;


Faktöriyel Hesaplaması:

#include<iostream.h>
int main()
{
         int faktoriyel=1,i,n;
         cout<<"Bir tamsayi girin";
         cin>>n;
         for(i=1;i<=n;i++)
                   faktoriyel=faktoriyel*i;
         cout<<"\n"<<n<<"!="<<faktoriyel;
         return 0;
}
#include<iostream.h>
int main()
{        unsigned int sayi;
           unsigned  long faktoriyel=1;
         int faktoriyel=1,i,n;
         cout<<"Bir tamsayi girin";
         cin>>n;
         for(int j=n;j>0;j--)
                   faktoriyel=faktoriyel*j;
         cout<<"\n"<<n<<"!="<<faktoriyel;
        cin>>n:
         return 0;
}

get  :Klavyeden tek karekter okuyarak ilgili degiskene aktarir

cin.get(degisken);
getline:Klavyeden belirtilen uzunluga kadar karekter dizisi okur/

cin.getline(degisken,uzunluk);
getline(cin,degisken);

#include <iostream.h>
char a[50] , b[50];
int main()
{
      cout<<"1.cumle:";
       cin.getline(a,50);
        cout<< "2. cumle:";
         cin.getline(b,5);
          cout<< "\n getline ile alinan:"  << a <<endl;
           cout<< "\n getline ile alinan:" << b <<endl;
      
return 0;
}


WHILE DÖNGÜSÜ

Kullanım şekli böyledir

while (denetim ifadesi)
{
Deyim-1;
Deyim-2;
.
.
Deyim-n;
}



Bir işin kaç kere tekrarlanacağını, döngüye girene kadar bilmiyorsak while döngüsü kullanılır. While döngüsünün tercih edilmesinin sebebi, bu döngüde kontrolün döngünün başında yapılmasıdır. While döngüsünün, döngü şartı sağlanmazsa gövdenin hiç işlemeyeceğini ifade eder. Denetim ifadesi doğru ise, deyim işletilir. Bu işlem denetim ifadesi yanlış olana kadar devam eder. Denetim ifadesi yanlış olduğunda program deyimden sonraki satıra gider. Diğer denetim ifadelerinde olduğu gibi birden çok deyim var ise bu deyimler aç, kapa ve küme parantezi arasına alınır.

Örnek: n=0 olana kadar çalışan bir program
#include <iostream.h>
int main()
{
       int n;
       cout<<"sifirdan farkli bir sayi gir:";
       cin>>n;
       while(n!=0)
                cin >>n;
       return 0;
}
Örnek: x>1 şartı sağlanana kadar çalışan programı yazınız
#include <iostream.h>
int main()
{
       int  x;
       x=5;
       while(x>1)
       {
                x=x-1;
                cout<<"x in degeri "<<x<<"\n";
       }
       cout<<"dongu burada bitti";
       return 0;
}
4-3-2-1
DO WHILE DÖNGÜSÜ

do

Deyim

while(kontrol ifadesi);

Bir grup deyimi işlettikten sonra, denetim ifadesini kontrol eder. Denetim ifadesi doğru ise deyim grubu tekrar işletilir. Eğer yanlış ise, program döngüden çıkar. Do while döngüsünün while döngüsünden farklı yanı, denetim ifadesinin döngünün sonunda olmasıdır.
“””
#include <iostream.h>
int main()
{
       int x;
       x=5;
       do
       {
                x=x-1;
                cout<<"x in degeri" << x << "\n";
       }
       while(x>1);
       cout<<"dongu burada bitti";
       return 0;
}








Örnek :

#include <iostream.h>
int main()
{
       int sayac=0;
       float say,ort,top;
       top=0.0;
       cout<<"lutfen ortalamasi bulunacak sayilari giriniz \n";       cout<<"programi bitirmek icin sifir giriniz \n";
       do
       {
                cin>>say;
                top=top+say;
                sayac++;
       }
       while(say!=0.0);
                ort=top/(sayac-1);
       cout<<"ortalama"<<ort;
       return 0;
}

Denetim ve artırım ifadeleri for döngüsünde yazılmazsa, sonsuz döngüye girilir.












Örnek :  z=2*sqrt(x-2)/y

#include <math.h>
int main()
{
       char Kar;
       int x,y;
       double z;
bas:
       cout << "\n Bir tam sayi gir : " ; cin >> x;
       cout << "\n Bir tam sayi gir : " ; cin >> y;
       if ( x>=2 && y !=0)
       {
                z=2*sqrt(x-2)/y;
                cout << "\n z = " << z;
       }
       else
                cout <<" \n Sayilar uygun degilé";
       cout <<" \n\n Devam mi? (e/h) : ";
       cin >> Kar;
       if ( Kar == 'e' && z > 100 )
       {
                goto bas;
       }
       return 0 ;
}


BİR BOYUTLU DİZİLER

Bir boyutlu dizi oluşturmak için
1-   Dizinin elemanlarında saklanan veri tipi
2-   Dizinin ismi
3-   Dizideki elemanların sayısı ( [] parantezlerinin içinde ) belirtilmelidir.


Dizinin eleman sayısı ,10 gibi bir tam  sayı sabiti veya bir const değer veya 3 * sizeof(int) gibi, büyüklüğü derleme sırasında bilinen sabit bir ifade olabilir,fakat değişken olamaz.

Örneğin, 4 elemanlı bir sayı dizisi oluşturunuz.

#include <iostream.h>
#include <conio.h>
int main()
{
       int sayi[5];
       for(int j=1;j<5;j++)
       {
                cin>>sayi[j];
                cout<<"\n sayi[" << j << "] = " << sayi[j];
       }
                return 0;

}
Dizinin 2.elemanını ekranda görüntüleyiniz

#include <iostream.h>
#include <conio.h>
int main()
{
       int sayi[5];
       for(int j=1;j<5;j++)
       {
                cin>>sayi[j];
                cout<<"\n sayi[" << j << "] = " << sayi[j];
       } 
                          cout<<"\n sayi[" << 2 << "] = " << sayi[2];
                return 0;

}

Bir dizinin elemanlarına ilk değerlerinin atanmasını sağlayan örnek ;


#include <iostream.h>
int main()
{
int ay,gun,gunTop;
int AyGunSay[12]={31,28,31,30,31,30,31,31,30,31,30,31};
cout<<"\n 1 ile 12 arasında ayi gir:";
cin>>ay;
cout<<"\n 1 ile 31 arasında gun u gir:";
cin>>gun;
gunTop=gun;
for(int j=0;j<ay - 1;j++)
gunTop=gunTop+AyGunSay[j];
cout<<"Gun sayisi:"<<gunTop; cin>>ay;
return 0;
}



İki Boyutlu Diziler

İki boyutlu bir dizi oluşturmak için;
1-)Dizinin elemanlarında saklanan verinin tipi,
2-)Dizinin ismi
3-)Dizideki satır ve sütunların sayıları [ ] [ ]

Double dizi [i] [j] ;

İki boyutlu bir dizinin ekranda okutulması ve ekranda yazdırılması ;
#include<iostream.h>
const int D=4;
const int M=3;
int main()
{
         int d,m;
         double dizi[D] [M];
         for(d=0;d<D;d++)
                   for(m=0;m<M;m++)
                   {
                            cout<<d+1<<".satir";
                            cout<<m+1<<".sutun icin sayi gir:";
                            cin>>dizi[d] [m];
                           
                   }
                   cout<<"\n\n";
                   cout<<"sutunlar: 1 2 3\n";
                   for(d=0;d<D;d++)
                   {
                            cout<<"\n " <<d+1<<".satir \t";
                            for(m=0;m<M;m++)
                                      cout<<dizi[d] [m] ;
                   }
                   cin>>d;
                   return 0;
}


#include<iostream.h>
const int D=3;
const int M=3;
int main()
{
         int d,m;
         double dizi[D] [M];
         for(d=0;d<D;d++)
                   for(m=0;m<M;m++)
                   {
                            cout<<d+1<<".satir";
                            cout<<m+1<<".sutun icin sayi gir:";
                            cin>>dizi[d] [m];
if  (d==m)  dizi[d] [m] = 1 ;
                                      else  dizi[d] [m] =0;

                           
                   }
                   cout<<"\n\n";
                   cout<<"sutunlar: 1 2 3\n";
                   for(d=0;d<D;d++)
                   {
                            cout<<"\n " <<d+1<<".satir \t";
                            for(m=0;m<M;m++)
                                      cout<<dizi[d] [m] ;
                   }
                   cin>>d;
                   return 0;
}

























3 kişinin boy,yaş, ağırlığını programı yazınız.(tek boyutlu)


#include <iostream.h>
const int I = 3;
struct bilgi
{
         int boyu,yasi;
         float agirligi;
};
int main()
{
         bilgi bil[I];
         for(int n=0;n<I;n++)
         {
                   cout<<"\n Boyu gir:";cin>>bil[n].boyu;
                   cout<<"\nYasi gir:";cin>>bil[n].yasi;
                   cout<<"\n Agirligi gir:";
                   cin>>bil[n].agirligi;
         }
         for(int m=0;m<I;m++)
         {
                   cout<<"\n\n Boyu:"<<bil[m].boyu;
                   cout<<"\n Yasi:"<<bil[m].yasi;
                   cout<<"\n Agirligi:"<<bil[m].agirligi;
         }
         int i; cin>>i;
         return 0;
}









ÖDEV

1-)Tam sayı veri tipli ve 10 elemanlı bir dizi tanımlayınız ve bu dizinin elemanlarına başlangıç değeri olarak 0 atayınız.Bu dizinin sadece ilk elemanına başlangıç değeri olarak 1 atarsanız kalan elemanların başlangıç değerleri ne olur?

2-)1’den 20’ye kadar olan tam sayıların toplamını ; 

a)for b)while ve c)do while yapısını kullanarak bir diziye atayan ve bu dizinin elemanlarını ekrana yazdıran C++ programlarını yazınız.

3-)3 satır 3 sütünlu bir M matrisi oluşturunuz.

a-) Her satırın toplamını
b-)Her sütunun toplamını
c-)Köşegenlerinin toplamını

hesaplayan programı hazırlayınız.

STRING VE KARAKTER TİPLİ DİZİLER

String

Bellekteki ardışık byte lara kaydedilen karakterlerden oluşan bir dizidir.İki tiptir

1-)C- stili string.
2-)String sınıfının bir nesnesi olarak tanımlanan string.

Bellekteki ardışık byte lara karakterlerlerin kaydedilmesi şeklinde oluşan dizi kavramı,bizi; string’in char tipli bir dizi olduğu sonucuna götürür.

C-stili string’in kendine has bir özelliği her string’in son karakterinin ‘\0’ şeklinde yazılan null karakteri olmasıdır. Örnek;
Char kar1[5]={‘a’,’b’,’e’,’d’,’z’); // C-stili string değil !
Char kar2[5]=  {‘c’,’f’,’g’,’u’,’\0’); // String

Bu dizilerin her ikisi de char tipli,fakat sadece ikincisi C-stili string’dir.C-stili string’de null karakteri önemli bir rol oynar.

Soru

Karakter katarı sabitleri.İlk değer atanmış karakteri katarı örneği.

#include<iostream.h>
int main()
{
         char st[]="Bugun hava cok sicak degil.";
         cout<<st<<endl;
         int i;cin>>i;
         return 0;
}



#include<iostream.h>
#include<conio.h>
int main()
{
         const int M=5;
         char st[M];
         cout<<"\n Bir cumle gir:"; cin.get(st,M);
         cout<<"Girdiginiz cumle:"<<st<<endl;
         int i;cin>>i;
         return 0;
}





İki boyutlu karakter dizisi

#include<iostream.h>
#include<conio.h>
int main()
{
        
         const int G=4; 
         const int K=4;
         char dizi [G][K] ={"Sal","Car","Prs","Cum"};
         for (int j=0;j<G;j++)
                   cout<<dizi[j]<<endl;getch();
         return 0;
}



YAPI ve NUMARALAMA VERİ TİPLERİ

Yapı veri tipi bir değişken, tipleri farklı olabilen birden çok veriyi saklar. Bir yapının içinde tanımlanan değişiklikler de olabilir. Bunların bazıları int veri tipinde, bazıları float veri tipinde ya da diğer tiplerden birinde olabilir. Bu bakımdan yapılar, tek tip verileri saklayabilen dizilerden farklıdır.

Yapı Veri Tipi Tanımları
1.struct anahtar kelimesi olması gerekir (blok başlatan bildiri deyimi)
2.bilgi, yapı veri tipinin adı ya da etiketi
3.{…..}, Küme Parantezleri
4.; işareti (noktalı virgül)

Örneğimizde, adı , boyu, yaşı ve ağırlığı yapı veri tipinin elemanları olan değişken isimleridir. Küme parantez kapandıktan sonra gelen noktalı virgül işareti yapı veri tanımının sonunu gösterir. Bilgi isimli yapı veri tanımında değişkenlerin tanımlanmasında sadece bir taslak görevi görür. Yapı değişkeni tanımlanmış olmaz yani bu tanımlama bellekte yer ayırmaz. Bu basit bir değişkenin tanımından farklıdır. Basit bir değişken tanımlandığında bu değişken için bellekte yer de ayrılmış olur.



Örnek: Yapı ve struct (record=kayıt) veri tipi program

#include <iostream.h>
#include <conio.h>
const int M = 80;
struct bilgi
{
         char adi[M];
         int boyu, yasi;
         float agirligi;
};
int main()
{
         bilgi bil;
         cout<< "\n Adini gir : ";
         cin>> bil.adi;
         cout<< "\n Boyunu gir : ";
         cin>> bil.boyu;
         cout<< "\n Yasini gir : ";
         cin>> bil.yasi;
         cout<< "\n Agirligini gir : ";
         cin>> bil.agirligi;
         cout<< "\n Adi : " << bil.adi;
         cout<< " \n Boyu : " << bil.boyu << " cm";
         cout<< ", Yasi : " << bil.yasi;
         cout<< " , Agirligi : " << bil.agirligi << " kg";
         return 0;
}





Yapı Veri Tipi Değişken Tanımlama

bilgi bil ;
Bilgi tipinde bil adında bir değişken tanımlar. Bu tanım bellekte bil için yer ayırır. Yani, adı (80 byte), boyu (4 byte), yasi(4 byte) ve ağırlığı için 4 byte değişkenlerini saklamaya yetecek kadar. Toplam olarak 92 byte bellekte yer ayırır.

Yapının Üyelerine (Elemanlarına) Erişme

Yapı veri tipi bir değişken tanımlandığı andan itibaren, bu değişkenini üyelerinin elamanlarına ( . ) nokta işlemcisi kullanılarak erişilebilir. Bir üyeye değer verme işlemi şöyle olabilir.

bil.boyu= 172;

Bu ifade 3 parçadan oluşur

1. Yapı değişkeninin ismi (örnekte bil)
2. Nokta işlemcisi (Yukarıdaki örnekte : . )
3. Üyenin elemanının ismi ( örnekte : boyu)
Nokta işlemcisinin asıl ismi üyeye erişme işlemcisidir.

Yapı üyelerine ilk değer atanması

#include <iostream.h>
#include <conio.h>
const int M = 80;
struct bilgi
{
         char adi[M];
         int boyu, yasi;
         float agirligi;
};
int main()
{
         bilgi bil = { "Mustafa" , 168, 20, 72.44F};
         cout<< "\n Adi : " << bil.adi;
         cout << "\n Boyu : " << bil.boyu << "cm";
         cout<< " , Yasi : " << bil.yasi;
         cout <<" , Agirligi : " << bil.agirligi << " kg " ;
         bilgi bil2;
         bil2=bil;
         cout<< " \n Adi : " << bil2.adi;
         cout << "\n\nBoyu : " << bil2.boyu << "cm";
                   cout<< " Yasi : " << bil2.yasi ;
         cout << " Agirligi : " << bil2.agirligi << " kg " ;
         return 0;
}

Yapı üyelerine atanacak değerle küme parantezlerinin içine yazılı ve birbirlerinden virgül ile ayrılır. Listedeki ilk değer birinciye ve ikinci ise ikinciye atanır ve böylece devam eder.

YAPI İÇİNDE YAPI

Bir yapı veri tipini de yeni bir yapı veri tanımında kullanmak mümkündür. Aşağıdaki örneğimizde Oda isimli yapı veri tipinin tanımında uzunluk isimli yapı veri tipi kullanılmaktadır.

#include <iostream.h>
#include <conio.h>
struct Uzunluk
{
       int fit;
       float inc;
};
struct Oda
{
       Uzunluk en ;
       Uzunluk boy;
};
int main()
{
       Oda yemekOd;
             yemekOd.en.fit= 13;
       yemekOd.en.inc = 6.5;
       yemekOd.boy.fit = 10;
       yemekOd.boy.inc = 0.0 ;
       float E = yemekOd.en.fit + yemekOd.en.inc / 12;
       float B = yemekOd.boy.fit + yemekOd.boy.inc / 12;
       cout << " Yemek odasinin alani = " << E  * B << " fit kare . \n";
       return 0;
}

Kümelenmiş yapıların üyelerine erişme
Yapılar kümelendiğinde, üyelere erişmek için nokta iki kez kullanılır. 

yemekOd.en.fit = 13;

1.    yemek.Od,Oda tipli değişkenin adıdır.
2.    en, Oda tipli dış yapının Uzunluk yapı tipli bir üyesidir.
3.    fit ise Uzunluk tipli iç yapının int tipli bir üyesidir.
    Dolayısıyla fit’e erişebilmek için önce en dıştaki değişkene (yemekOd), sonra bunun içindekine (en), daha sonra ise onun içindeki (fit)’e erişmek gerekir.
     Yani, yemekOd isimli yapı değişkeninden yola çıkıp Oda yapı tipinde, sonra Oda yapı tipinin en isimli elemanına, daha sonra en elemanının tipi olan Uzunluk tanımında bulun fit isimli alan değişkenine ulaşılır.

AnaDeğişken à AnaTip, Anatip à AlanDeğişkeni, AlanDeğişkeni à İçTip, İçTip à İçDeğişken, vs sırası izlenir

Yemek à Oda, Oda à en, en à Uzunluk , Uzunluk à fit vs. sonuçta  yemekOd.en.fit sırası ortaya çıkar.







Kümelenmiş Yapılara İlk Değer Atama

OdayemekOd = { {13,6.5}, {10,0.0}};

Uzunluk’a {13,6.5}, ikinci Uzunluk’a {10,0.0 } değerleri atanmış daha sonra Oda tipli yemekOd değişkenine atanır.

Kümelenme Derinliği

#include <iostream.h>
#include <conio.h>
const int sinek = 0 ;
const int karo = 1  ;
const int kupa = 2 ;
const int maca = 3 ;
const int vale = 11 ;
const int kiz = 12;
const int papaz = 13 ;
const int as= 14;
struct kart
{
        int rakam;
        int seri;
};
int main()
{
        kart yedek, secilen, tutulan;
        int sira;
        kart kart1 = { 7, sinek };
        cout << " 1.kart sinek 7 li \n";
        kart kart2 = { vale, kupa };
        cout << " 2.kart kupa vale \n";
        kart kart3 = { as, maca };
        cout << " 3.kart maca as \n";
        tutulan = kart3;
        cout<< " 1.kart ile 3.karti degistiriyorum \n";
        yedek = kart3;
        kart3 = kart1;
        kart1= yedek;
        cout<< " 2.kart ile 3.karti degistiriyorum \n";
        yedek = kart3;
        kart3 = kart2;
        kart2=yedek;
        cout<< " 1.kart ile 2.karti degistiriyorum\n";
        yedek=kart2;
        kart2=kart1;
        kart1=yedek;
        cout<< "Uc kagittan birini sec (1, 2, 3) : ";
        cin>> sira;
        switch(sira)
        {
        case 1 : secilen = kart1;break;
        case 2 : secilen = kart2;break;
        case 3 : secilen = kart3;break;
        }
        cout<< "Sectigin karti ac.maca as i mi?";
        if(secilen.rakam == tutulan.rakam &&
                secilen.seri == tutulan.seri)
                cout<< "Evet! Kazandiniz!\n";
        else
                cout<< "Uzgunum! Kaybettiniz \n";
        return 0;
}
NUMARALAMA VERİ TİPLERİ
Yapı struct kullanıcı tarafından çok elemanlı veri tipi tanımlama yollarından biridir. Numaralandırma yani enumeration isimlendiriyoruz
Numaralanma veri tipi bu veri tipinin alabileceği sınırlı değerlerin listesini önceden bildiğimiz durumlarda işimize yarar
enum olarak tanımlanır
Soru: Haftanın günlerini temsil eden enum veri tipinde bir örnek yazınız.

#include <iostream.h>

#include<conio.h>
enum HaftaGun {Pz, Pzt, Sa, Ca, Pe, Cu , Ct};
int main()
{
HaftaGun gun1,gun2;
gun1 = Sa;
gun2 = Cu;
int fark = gun2 - gun1;
cout<<"Fark = "<<fark<<endl;
if (gun1<gun2)
cout<<"1. gun, once gelir. \n";
else
cout<<"1. gun, sonra gelir. \n";
getch();
return 0;
}


Numaralandırma derleyici tarafından tam sayı olarak ele alınır.
Listedeki ilk elemanın degeri 0 dır0,1,2 diye devam eder.

#include <iostream.h>
#include<conio.h>
enum cevap {hayir,evet};
int main()
{
        cevap cev = hayir;
        char ch = 'a';
        int KelimeSayisi = 0;
        cout<<"Bir cumle yaziniz: \n";
        do
        {
                ch = getche();
                if    (ch == ' ' || ch == '\r')
                {      if (cev == evet)
                        {KelimeSayisi++;cev = hayir;}
                }
            else
                        if (cev == hayir) cev = evet;
        }
        while (ch!= '\r');
        cout<<"\n Kelime Sayisi: "<<KelimeSayisi<<"---- \n";
        getche();
        return 0;
}


FONKSİYONLAR
C++ programında bir şey yaptırılacağı zaman, o işi yapacak olan bir fonksiyon çağırılır. Fonksiyon birkaç tane program ifadesini tek bir blok içinde toplar ve buna bir isim verir. Bu blok daha sonra programın diğer blokları tarafından kullanılmak üzere çağırılır. Bir fonksiyon, deklare edilmeden önce çağırılmaz.

Argümansız (Basit) Fonksiyonlar
Bir fonksiyonu bir program içinde kullanabilmek için gerekli 3 işlem vardır.
1.   Fonksiyonun deklarasyonu (the function declaration)
2.   Fonksiyona yapılan çağrılar (the calls to the function)
3.   Fonksiyonun tanımı (the function definition)

Fonksiyonu Deklare Etmek
Bir fonksiyonu derleyiciye bildirmeden kullanamayız. Bunun için farklı 2 yol vardır.
1.   Fonksiyonu çağırmadan önce deklare etme
2.   Fonksiyonu çağırmadan önce tanımlama

Örneğin p1.cpp programında, YildizYaz() fonksiyonu
void YildizYaz();
şeklinde deklare edilmiştir. Bu deklarasyon, derleyiciye daha sonraki bir noktada YildizYaz adında bir fonksiyon kullanacağımızı ve bunun şekli hakkında bize hatırlatma yapmak için söylenir. void anahtar kelimesi, fonksiyonun geri döndüreceği bir değerin olmadığını gösterir. İçi boş parantezler [ () ] fonksiyonun argümanlarının olmadığını gösterir. Ve noktalı virgülle sona erdirilir. Bir fonksiyonu program içinde istediğimiz sayıda çağırabiliriz. Fonksiyonun tanımını yaparken
1.   void YildizYaz(); fonksiyon başlığı ile,
2.   {…} küme parantezleri arasında yer alan fonksiyon gövdesinde oluşur.

Fonksiyon başlığı, fonksiyonun deklarasyonu ile uyuşmak zorundadır. Yani fonksiyon ismini kullanmalı, ve döndürdüğü değer aynı olmalıdır.
Programda kullanılan fonksiyonun ve fonksiyonun denklarasyonu ve tanımı, #include <conio.h> isimli başlık dosyasındadır. getche() fonksiyonunun tanımı ise, derlenip makine diline çevrilmiş olarak programımız çalıştığında programımıza kendiliğinden bağlanan bir kütüphane dosyasının içindedir.

YildizYaz() fonksiyonunu tanımlayan bir program.

#include <iostream.h>
#include<conio.h>
#include <iomanip.h>
void YildizYaz();
int main()
{
       YildizYaz();
       cout<<setw(10)<<"Adi: ";
       cout<<setw(24)<<"Ege UNIVERSITESI \n";
       YildizYaz();
cout<<setw(30)<<"ISTATISTIK "<<endl;
       YildizYaz();
       getch();
       return 0;
}
void YildizYaz()
{
       for (int j=0;j<50;j++)
             cout<<'*';
       cout<<endl;
}

Fonksiyonun Tanımı:
void YildizYaz()
{
       for (int j=0;j<50;j++)
             cout<<'*';
       cout<<endl;
}

<iomanip.h> à Bazı biçimleyicileri kullanmak için kullanılan başlık dosyasıdır.

C++’da bazı kütüphaneler

#include<kutuphane adı>

İostream : Temel işlemler ve ekran komutları
Windows : Windows uygulamaları fonksiyon ve makro
Vectors : dizi işlemleri ile ilgili fonksiyonlar
Limits : sayısal sınıflar
New : dinamik bellek kullanımı ve işlemleri
Complex : karmaşık sayı sistemleri
Algorithms : özellikle eleman dizili fonksiyonlar




SINAVA HAZIRLIK SORULARI

1-      Klavyeden girilen 5 elemanlı bir A dizisindeki pozitif elemanları B dizisine, negatif elemanları da C dizisine yerleştiren programı yazınız.

#include <iostream.h>
int main()
{
     int i;
      int x=0,y=0;
     int A[5],B[5],C[5];
     cout<<"\n A Dizisinin: \n";
     for(i=0;i<5;i++)
     {
            cout<< i+1 <<". elemani=";
            cin>> A[i];
     }
     for(i=0;i<5;i++)
     {
            if(A[i]>0) {x++;B[x-1]=A[i];}
            if(A[i]<0) {y++;C[y-1]=A[i];}
     }
     cout<<"\n B dizisi: \n";
     for(i=0;i<x;i++)
            cout<<B[i]<<"\t";
     cout<<"\n C dizisi:\n";
     for(i=0;i<y;i++)
            cout<<C[i]<<"\t";
     return 0;
}




2-      Klavyeden girilen 3 adet nokta çiftinden, kaç tanesinin
 (x-a)^2+(y-b)^2=r^2 dairesinin içinde kaç tanesinin dışında ve kaç tanesinin üzerinde olduğunu bulan programı yazınız.

#include <iostream.h>
using namespace std;
int i, a, b, r, isay=0, usay=0, dsay=0;
float F;
int main()
{
     cout<<"Daire merkezinin koordinatlari ve yaricapi: \n";
     cout<< " x koordinati => ";
     cin>>a;
     cout<<" y koordinati =>";
     cin>>b;
     cout<<"Yaricapi=>";
            cin>>r;
     int X[3],Y[3];
     cout<<"\n";
     for(i=0;i<3;i++)
     {
            F=(X[i]-a)*(X[i]-a)+(Y[i]-b)*(Y[i]-b);
            if(F<(r*r)) isay++;
            else if(F>(r*r)) dsay++;
           else usay++;
     }
     cout<< "\n Dairenin => \n";
     cout <<" Icindekilerin sayisi => " <<isay<<"\n";
    cout <<" Uzerindekilerin sayisi => " <<usay<<"\n";
    cout <<"  Disindailerin sayisi => " <<dsay<<"\n";
     return 0;
}
X=2
Y=3
r=5
nokta sayısı 3






3-  Klavyeden girilen 3 elemanlı A dizisinin aritmetik, geometrik ve harmonik ortalamasını hesaplayan programı yazınız.

#include <iostream.h>
#include <math.h>
int i;
float T=0,C=1,HT=0,AO,GO,HO;
int main()
{
     float A[3];
     cout << "\n";
     for(i=0;i<3;i++)
     {
            cout <<"A("<<i<<")=";
            cin>>A[i];
     }
     for(i=0;i<3;i++)
     {
            T+=A[i];
            C*=A[i];
            HT+=1/A[i];
     }
     AO=T/3;
     GO=pow(C,(1.0/3));
     HO=3/HT;
     cout <<"\n Dizinin aritmetik ortalamasi = "<< AO << endl;    cout << "Dizinin geometrik ortalamasi = "<< GO << endl;
     cout <<" Dizinin harmonik ortalamasi = "<< HO << endl;
     return 0;
}






4-      Sayısal analizde belirli integral hesaplamak için diğer popüler yöntem de yamuklar yöntemidir. Dikdörtgenler yönteminde; fonksiyon ile eksen arasında kalan alan, dikdörtgenlere bölünürken yamuklar yönteminde ise yamuklara bölünmektedir ve sonuç yamuk alanlarının toplamı şeklinde oluşmaktadır.  belirli integrali hesaplanırken [a,b] aralığı n tane parçaya bölünür ve yüksekliği h= (b-a)/n olan yamuklara tamamlanır.
Buna göre klavyeden parça(oluşturacak yamuk) sayısı girilen f(x)=3x^2+2x fonksiyonunun belirli integralini verilen [a
b] aralığında hesaplayan program.

BUNU FİNALDE YAPACAKMIŞIZ

5-      Fibonacci Serisini oluşturan programı yazınız.

#include <iostream.h>
using namespace std;
unsigned N,T1,T2,T3;
int main()
{
     cout<< "Fibonacci Serisi" << endl;
     cout << " Terim sayisi: " ;
     cin>> N;
     T1=1;
     T2=1;
     cout << "\n " << T1 << " \t" << T2 << "\t";
     for(int i=1;i<=N-2;i++)
     {
            T3=T1+T2;
            cout << T3 << "|\t";
            T1=T2;
            T2=T3;
     }
     return 0 ;
}





6-      Cos(x) fonksiyonu, Maclaurin serisine aşağıdaki gibi açılmaktadır. Buna göre klavyeden girilen x değerinin cosinus’unu belirtilen terim sayısına kadar seriye açarak hesaplayan program.

    Cos(x)= 1-(x^2/2!)+ (x^4/4!)+ (x^6/6!)+…..=
     Şeklinde ortaya çıkar.

#include <iostream.h>
#include <math.h>
int aci,N,is;
float X,F,T=1;
const float PI=3.14;
int main()
{
  cout<<" Aci degeri: " ;
  cin>> aci;
  cout << " Terim sayisi: " ;
  cin>> N;
  X=aci * PI/180;
  is=1;
  for(int i=1;i<N;i++)
  {
            F=1;
            for(int j=1;j<2*i;j++) F*=j;
           is*=(-1);
            T+=is*pow(X,2*i)/F;
  }
  cout << " \n Seri acilimi ile hesaplanan deger: " << T<< endl;
  cout << " Komutla hesaplanan deger: " << cos(X) << endl;
  return 0;
}




7-      Klavyeden katsayıları girilen ikinci dereceden fonksiyonun
köklerini bulan programı hazırlayınız?

#include <iostream.h>
#include <math.h>
float a,b,c,d,x1,x2;
int main()
{
     cout<< "A=";
     cin>>a;
     cout<<"B=";
     cin>>b;
     cout<<"C=";
     cin>>c;
     d=b*b-4*a*c;
     cout<<"\n";
     if(d>0)
     {
              cout<<"Gercel koklervardir: "<<endl;
              x1=(-b-sqrt(d))/(2*a);
              x2=(-b+sqrt(d))/(2*a);
              cout<<"Kokler:" <<x1<<"\t"<<x2<<endl;
     }
     else if(d==0)
     {
              cout<< "Katli kok vardir : " << endl;
              x1=-b/(2*a);
              cout<<"Katli kok: " <<x1<<endl;
     }
     else cout <<"Sanal kokler vardir. " << endl;
     return 0;
}



8-  Klavyeden girilen bir sayının tamsayı olup olmadığını test eden programı hazırlayınız.


#include <iostream.h>
int main()
{
     float s;
     cout<< "Bir sayi giriniz: " ;
     cin>>s;
     if(s-(int) s ==0) cout << " Tamsayi";
     else cout << " Tamsayi degil " ;
     return 0 ;
}


9 - Bir ve kendisinden başka tamsayıya bölünmeyen sayılara asal sayı denir. Buna göre klavyeden girilen üst sınıra kadar olan asal sayıları yazdıran programı yazınız.
#include <iostream.h>
int N,s;
int main()
{
       cout << " Belirtilen araliktaki ASAL sayilar \n";
       cout << " \n Ust sinir => " ;
                cin >> N;
       cout << " \n+++ ASAL SAYILAR +++\n " << endl;
       for(int i=2;i<=N;i++)
       {
                s=0;
                for(int j=1;j<=i;j++)
                          if(i%j==0) s++;
                          if(s==2) cout << i << "\t";
       }
       return 0 ;
}



10-     1 ile 5 arasında girilen notlara göre başarıyı yazan program.

#include <iostream.h>
int a;
int main()
{
       cout << " Notunuzu giriniz< (1-5) => ";
       cin>>a;
       switch(a)
       {
       case 1: { cout << " Cok zayif " << endl ; break; }
       case 2: { cout << " Zayif " << endl ; break; }
       case 3: { cout << " Orta " << endl ; break; }
       case 4: { cout << " Iyi " << endl ; break; }
       case 5: { cout << " Cok iyi " << endl ; break; }
         default: { cout << " Gecersiz not " << endl; break; }
       }
       return 0 ;
}

11-     NxN tipinde 2 matrisinin elemanlarını ekrana yazdırınız

#include <iostream.h>
int A[100][100];
int main()
{
         int A[3][3];
         cout << " \n A Matrisi : \n";
         for (int i=0;i<3;i++)
         { for(int j=0;j<3;j++)
         {
                   cout << "A("<<i<<","<<j<<")=";
                   cin>> A[i][j];
         }
         }
         {
                   cout << " A matrisi : \n ";
         for(int i=0;i<3;i++)
                   for(int j=0;j<3;j++)
                            cout << A[i][j] << " \t";
                   cout << " \n";
         }
return 0 ;
}

1-   Bir struct yapılardan soru
2-   Tek boyutlu diziler
3-   İki boyutlu diziler
4-   Ardı ardına döngü ile soru
5-   While case kullanımı switch
6-   Enum ile ilgili kullanım
Fonksiyon tanımını kutuphane fonksiyonu ile karşılaştırma
Kütaphane fonksiyonlarının  deklerasyonunun ve tanımını örneğin getche() fonksiyonu deklerSYONU
#İNCLUDE<CONİO.H>
Başlık dosyasındadır.
Program derlenip çalıştığında fonksiyonun tanımı derlenip makına diline çevrilmiş olarak kendiliğinden baglanan kutuphane dosyasının içindedir.
Fonksiyonların Deklerasyonundan kurtulma
Fonksiyonun deklerasyonunu yazmadan fonksiyona yapılacak ilk cagrıdan once fonksiyonun tanımını programın listesının ıcıne yerleştırmek gerekır.
Void YıldızYaz();

Argumanlı Fonksiyonlar
Fonksıyonları tanımlarken ( ) içi daha once bostu bunlar argumansız fonksıyonlardı. Arguman cagıran program tarafından bir fonksiyona gonderılen verıdır.
Ornegın Yıldızyaz() fonksıyonunda herhangi bir karekteri herhangı bır sayıda yazan bir fonksıyon olarak tanımlayabılırız.

#include <iostream.h>
#include <iomanip.h>
using namespace std;
#include <conio.h>

int main()
{
     KarakterYaz('+',60);
     cout<< setw(10) <<"Adi :";
     cout<< setw(24) <<"Prof. Dr. Mustafa Dkici\n";
     KarakterYaz('+',65);
     cout<< setw(30) <<"IslemTamam!" <<endl;
     KarakterYaz('+',70);
     getch();
     return 0;
}

Not: Bu fonksiyonun deklarasyonu void karakter (char,int); şeklindedir. Buradaki, parantez içindeki char ve int, KarakterYaz() fonksiyonuna çağıran program tarafından gönderilecek argümanların veri tipleridir. Örnekte, KarakterYaz(‘+’,60) fonksiyon içinde uygun yerlere yerleştirilmiştir. Ekrana 60 tane ‘+’ işareti yazması gerekir.

Fonksiyonu çağıran program, fonksiyona gerekli argümanları sağlar. Fonksiyonun içinde bu argümanları saklamak için kullanılan değişkenlere parametre denir. KarakterYaz() fonksiyonunun tanımında bu parametreler, ‘k’ ve ‘n’ ile gösterilir. void KarakterYaz(char k, int n); fonksiyon başlığı argümanların veri tiplerini bu parametrelere atamıştır.

Fonksiyonlara değişkenleri gönderme örneğinde,

#include <iostream.h>
int main()
{
     char kar;
     int tam;
     cout << "Bir karakter gir: "; cin >> kar;
     cout << "Tekrar sayisini gir: "; cin >> tam;
     cout << endl;
     YildizYaz(kar,tam); cin >> tam;
     return 0;
}

Not: Bu programdaki, main fonksiyonunda tanımlanan ‘kar’ ve ‘tam’ isimli değişkenler YıldızYaz() fonksiyonuna gönderilen argümanlar olarak kullanılır. ‘kar’ ve ‘tam’ argümanlarının değerleri ekrandan okutulduktan sonra bu değerler YıldızYaz(kar,tam) fonksiyon çağırma ifadesi tarafından gereği yapılmak üzere, YıldızYaz() fonksiyonuna gönderilmektedir.

Argümanların bu şekilde gönderilmesini, yani fonksiyonun kendisine gelen argümanların kopyalarını çıkardığı bu gönderme şekline ‘değer olarak gönderme’ denir. Bu sayede, çağıran programda fonksiyon çağırılırken kullanılan ‘kar’ ve ‘tam’ değişkenlerini sakladığı değerler korunmuş olur.

Fonksiyona yapı tipli argümanı değer olarak göndermek için daha önceki bilgi yapı tipli b1 değişkeni BilYaz() fonksiyonuna değer argümanı olarak gönderilmiştir. Fonsiyona değer olarak gönderilen argümanlar geri değer döndürmezler.

#include <iostream.h>
#include <conio.h>
struct bilgi
{
         int boyu, yasi;
         float agirligi;
};
int main()
{
         bilgi b1;
         cout << "\nBoyu : " ; cin>> b1.boyu;
         cout<< " \nYasi : "; cin >> b1.yasi;
         cout <<" \nAgirligi : "; cin >> b1.agirligi;
         cout << “\n\nFonksiyonun icinde : \n\n”;
         BilYaz(b1);
cout <<”\n\nCagiran programin icinde : \n”;
         cout <<” Boyu : “ << b1.boyu << “ cm/n”;
cout << “Yasi : “ << b1.yasi << “\n”;
         cout << “Agirligi : “ << b1.agirligi<< “ kg”;
getch();
return 0;
}

Fonksiyona dizi tipli argümanı değer olarak göndermek için, fonksiyon çağırma ifadesinde dizi fonksiyona gönderilen dizinin ilk elemanının adresini int toplam=dizitopla(dizi,D); fonksiyonunda ‘D’ fonksiyona gönderilen dizinin boyutunu gösterir. Bu büyülükler dizitopla() fonksiyonuna değer argümanı olarak gönderilmiştir.

int dizitopla(int diz[], int n);

Burada diz[] dizisinin boyutu verilmemiştir. Ayrıca dizitopla  fonksiyonunun dönüş tipi ‘int’ olduğundan ‘return’ deyimi kullanılmamıştır. Programdaki ‘return’ deyimisadece ’topla()’ fonksiyonunu döndürür.

#include <iostream.h>
int DiziTopla(int Diz[], int n);
const int D = 8;
//================
int main()
{
       int Diz[D] = {0, 1, 2, 3, 4, 5, 6, 7 };
       cout<< "\nDizi nin adresi : "<< Diz << endl;
       int Toplam = DiziTopla(Diz,D);
       cout << "\n\nDondukten sonraki dizi: \n";
             cout  << "\nDizi nin adresi : " << Diz << endl;
       for(int i= 0; i<D; i++)
             cout << Diz[i] <<'  ';
       cout << "\nDizi elemanlarinin toplami : " << Toplam;
       cin >> Toplam;
       return 0;
}
//================

int DiziTopla(int Diz[], int n)
{
       int Topla = 0;
       for (int i=0; i<n; i++)
             Topla = Topla + Diz[i];
       cout << "\nFonksiyon icinde: \n";
       cout << "\nDiz in adresi : " << Diz << endl;
       for(i=0; i<n; i++)
       {
             Diz[i] = 2 * i;
             cout << Diz[i] << ' ';
       }
       return Topla;
}

Fonksiyondan Değer Döndürme
Bir fonksiyon çalışmasını tamamladıktan sonra, kendisini çağıran programa değer döndürebilir. Genellikle döndürülen bu değer, fonksiyonun çözdüğü problemin sonucudur. Çağıran program bir fonksiyona ‘()’ parantezlerinin içinde birçok argüman gönderebilir. Fakat fonksiyon, çağıran programa ‘return’ deyimi aracılığı ile sadece bir değer döndürür.
1-Fonksiyondan yapı tipli bir argümanı döndürme
2-Fonksiyona argümanları referans olarak gönderme ve fonksiyondan argümanları referans olarak döndürme
3-Fonksiyon argümanları olarak pointerları kullanma

Fonksiyondan dizi tipli bir argüman döndürme şeklinde yöntemlerle bir fonksiyondan birden çok değer döndürme amacıyla bu işlemler yapılır.

Eğer fonksiyon bir değer döndürmüyorsa, ‘void’ anahtar kelimesi kullanılır. Programdaki gereksiz değişkenlerden kurtulmak için, ‘return’ ifadesi farklı tipte yazılır.

Örnek:

#include <iostream.h>
const int D=7;
void DiziArtir(int*, int);
int main()
{
       int Dizi[D] = {1, 2, 3, 4, 5, 6, 7 };
       int* dg = &Dizi[0];
       cout << "\nDizinin ilk elemani: "<< *dg << endl;
       cout << "\n\nFonksiyonda: \n";
       DiziArtir(dg, D);
       cout << "\nCagiran programda: ";
       cout << "\nYeni dizinin elemanlari: \n";
       for(int i=0;i<D;i++)
             cout << i << " -> " << *(dg++) <<endl;
       cin >> i;
       return 0;
}
void DiziArtir(int* Diz, int n)
{
       for(int i=0;i<n;i++)
       {
             Diz[i] = 10 + *(Diz + i);
             cout << "\n = " << i << " -> Diz[" << i << "] = " << Diz[i] << endl;
       }
}

FONKSİYONLARDA ARGÜMANLARI REFERANS OLARAK DÖNDÜRME
Referans, bir değişkene takma isim, yani farklı bir isim vermeye denir.
Referans veri tipinin ismi ile değişken isminin arasına & karakteri yazılarak tanımlanan ve basit olmayan veri tipidir. Basit olmayan bir veri tipi, bir başka veri tipi yardımıyla tanımlanır. Örnek:
Float& OndSay; // OndSay değişkeni referans olarak tanımlanmış.
Referans olarak tanımlanan bir değişkene başlangıç değeri verilmelidir.

int intDeg = 1024;
int &RefDeg = intDeg;

int &RefDeg1; //Yanlış, çünkü başlangıç değeri verilmemiş.

int &RefDeg2=10 //Yanlış, çünkü başlangıç değeri bir sayı verilemez. Başlangıç değeri bir değişken olmalıdır.

Referans bir değişkene verilen takma isim olduğu için ve esas değişkenin her ikisi de aynı değere sahiptir ve bunların her ikisi aynı bellek alanını kullanır.

Örneğin;
RefDeg += 2;

Bu değişkenin referans olduğu tam sayı tipi ve intDeg isimli değişkene RefDeg+2 değerini atar. Bu değişken, intDeg değişkenine doğrudan eriştiği gibi, RefDeg değişkeni aracılığıyla da erişebilir.

RefDeg = 5;

İfadesinde intDeg’e de 5 atanmıştır.

~Örnekler~
int il = 1024, i2 = 2048;
int &r1 = il, r2 = i2;

int i3 = 1024, &ri = i3;Y
int &r3 = i3, &r4 = i2;Y
const int intDeg = 1024;
const int &RefDeg = intDeg; // Referans ve değişkenin her ikisi de sabit

int &Ref2 = intDeg; //Hatalı, bir sabit, değişkene referans olamaz.

NOT: const olmayan referanslara başlangıç değeri verilemez.
double dDeg = 3.14;
const int &ri = dDeg;

ifadeleri yazılırsa, derleyici bunları

int deg = dDeg;
const int &ri = deg; //deg’i ri’ye bağlar.

Referansları fonksiyonlara argüman olarak gönderebiliriz. Fonksiyon çağırma ifadesindeki argümanların veri tipleri ile çağrılan fonksiyonun argümanlarının veri tipleri aynı; fakat fonksiyonların çağırma ifadesindeki parametre isimleriyle çağrılan fonksiyonların parametrelerinin isimleri farklıdır. Bu yüzden fonksiyon kendisini çağıran programdaki orijinal değişkenlere ulaşamaz. Bu, fonksiyonun kendisini çağıran programdaki değişkene zarar vermesini önler. Bu durum Pascal’daki procedure ve function tanımlarında parametre tanımından önce yazılan var anahtar kelimesinin yaptığı iş ile aynıdır.

Yukarıda yaptığımız Topla() fonksiyonuna tam sayı tipli bir büyüklük referans olarak gönderilmekte ve fonksiyondan dönen büyüklük ekrana yazdırılmaktadır. Topla() fonksiyonun deklarasyonu
void Topla(int n, int& top)

#include <iostream>
using namespace std;
#include <conio.h>
int main()
{
         void Topla(int, int&);
         int tam1, tam2 = 10;
         char kar;
         do
         {
                   cout<<"\n \t \t Cagiran programda : \n";
                   cout<<"\n \t \t Tam sayi gir: ";cin>>tam1;
                   Topla(tam1,tam2);
                   cout<<"\n \n \t \t Cagiran programda: \n";
                   cout<<"\n \t \t Girilen sayi = "<<tam1;
                   cout<<"\n \n \t \t Donen sayi ="<<tam2;
                   cout<<"\n \n \t \t Devam mi (e/h)?";cin>>kar;
         }
         while (kar == 'e');
         return 0;
}
void Topla(int n, int& top)
{
         cout<<"\n \n Fonksiyonun icinde: ";
         cout<<"\n \n n = "<<n<<endl;
         cout<<"top = "<<top<<endl;
         top+= n;
         cout<<"\n \n n + top = "<<top<<endl;
         char a; cin>>a;
}

NOT:  10 MAYIS à QUIZ/8.mayıs quiz
17 MAYIS à ÖDEV SUNUMLARI/15.mayıs

ÖDEV KONULARI:
1-   search algoritması ve uygulamaları
2-   find algoritması ve uygulamaları
3-   sort algoritması ve uygulamaları
4-   transform algoritması ve uygulamaları
5-   count algoritması ve uygulamaları
6-   istatistiksel rastgele sayı simulasyonları, zar atma simulasyonu
7-   Monte Carlo yöntemlerinin C++ üzerinde örneklenmesi

Örnek: Ondalık bir sayının tam ve ondalık kısımlarının ayrılması işlemini Ayir() isimli bir fonksiyonla gerçekleştiren tam sayı ve ondalık sayı olarak ayrılan bu değerler, çağıran program olan main() fonksiyonuna döndüren programı referans argümanlar kullanarak hazırlayan programı hazırlayınız.

#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
         void Ayir(float, float&, float&);
         float sayi, tam, kesir;
         do
         {
                   cout<<"\n \t \t Cagiran programda : \n";
                   cout<<"\n \t \t Ondalik sayi gir:";
                   cin>>sayi;
                   Ayir(sayi, tam, kesir);
                   cout<<"\n \n \t \t Cagiran programda: \n";
                   cout<<"\n \t \t Tam kismi = "<<tam;
                   cout<<"\n \t \t Kesir kismi ="<<kesir;
                   cin>>sayi;
         }
         while (sayi != 0.0);
         getch();
         return 0;
}
void Ayir(float f, float& t, float& k)
{
         int yedek = static_cast<int>(f);
         cout<<"\n \n Fonksiyonun icinde :";
         cout<<"\n \n Yedek = "<<yedek<<endl;
         t = static_cast<float>(yedek);
         cout<<"Tam = "<<t<<endl;
         k=f-t;
         cout<<"Kesir = "<<k<<endl;
}

Programda fonksiyon çağırma ifadesinde & referans işlemcisinin yer almadığını görüyoruz.

Soru: Sırala fonksiyonuna gönderilen n1 ve n2 Sirala() fonksiyonunda & referans olarak tanimlanan say1 ve say2 parametrelerine atayan ve Sirala() fonksiyonunda referans olarak tanımlanan say1 ve say2 parametrelerinde meydana gelen değişiklikleri aynen çağıran bir program örneği yazınız.

#include <iostream>
using namespace std;
int main()
{
         void Sirala(int&, int&);
         int n1=99, n2 = 11, n3=222, n4=88;
         Sirala(n1, n2);
         cout<<"n1= "<<n1<<endl;
         cout<<"n2= "<<n2<<endl;
         Sirala(n3, n4);
         cout<<"n3= "<<n3<<endl;
         cout<<"n4= "<<n4<<endl; cin>>n1;
         return 0;
}
void Sirala(int& sayi1, int& sayi2)
{
         if (sayi1>sayi2)
         {
                   int yedek = sayi1;
                   sayi1=sayi2;
                   sayi2=yedek;
         }
}

Örnek: Yapı tipli verileri referans olarak gönderen bir program örneği hazırlayınız.
#include <iostream>
#include <conio.h>
using namespace std;
struct Uzunluk
{
         int fit;
         float inc;
};
void Degistir( Uzunluk&, float );
void Yaz( Uzunluk );
int main()
{
         Uzunluk u1={12, 6.5};
         cout<<"\n u1= "; Yaz(u1);
         Degistir(u1, 0.5);
         cout<<"\n u1= "; Yaz(u1);
         Uzunluk u2 = {10, 5.5};
         cout<<"\n \n u2= "; Yaz(u2);
         Degistir(u2, 0.25);
         cout<<"\n u2= "; Yaz(u2); getch();
         return 0;
}
void Degistir( Uzunluk& uu, float carpan)
{
         float inc = (uu.fit * 12 + uu.inc) * carpan;
         uu.fit = static_cast<int>(inc / 12);
         uu.inc = inc - uu.fit * 12;
}
void Yaz(Uzunluk uu)
{
         cout<<uu.fit<<" fit, " <<uu.inc<< " inc";
}


Fonksiyonların kendi kendini çagırması



Örnek…
#include<iostream>
using namespace std;
unsigned long fakt(unsigned long);
int main()
{
int n;
unsigned long faktoryel;
cout<<”\n bir tamsayı gir:”;cin>>n;
faktoryel=fakt(n);
cout<<n<<”nin faktoryeli=”<<faktoryel;
cin>>n;
return 0;
}
unsigned long fakt(unsigned long m)
{
if (m>1)
return m * fakt(m-1);
else
return 0;
}


Yerel ve genel degıskenler
Yerel(local) genel(global) degıskenler

#include <iostream>
#include <conio.h>
using namespace std;
void KarakterYaz( char = '*', int = 45);
int main()
{
        KarakterYaz();
        KarakterYaz( '=');
        KarakterYaz('+', 30);
        getch();
        return 0;
}
void KarakterYaz(char k, int n)
{
        for (int j=0; j<n; j++) cout<<k;
        cout<<endl;
}

Soru: Aşağıdaki çerçeveyi oluşturan bir program örneği yazınız.
Sol alt köşe à 192
Sol üst köşe à 218
Sağ üst köşe à191
Sağ alt köşe à217
Düz çizgi à 240

#include <iostream>
#include <conio.h>
using namespace std;

void KarakterYaz( int = 218, int = 1);
void KarakterOku( int = 192, int = 1);
int main()
{
        
         KarakterYaz();
    KarakterYaz( 45, 20);
    KarakterYaz( 191,1);
         KarakterOku(192,1);

         getch();
         return 0;
}



void KarakterYaz(int k, int n)
{
char ch = k;

         for (int j=0; j<n; j++) cout<<ch;
        
}

void KarakterOku(int l, int m)
{
         char ch = l;
         for(int x=m; x<0; x--) cout<<ch;
}

Bu programı tamamlayınız.

Sınıf ve Veri Tipi ve Nesne – Yapısal Programlamaya Geçiş
Değişik tipteki verileri bir bütünlük içinde, bir arada tutmak için struct veri tipi geliştirilmiştir. C++ programlama dili günlük hayatta gerçekten var olan sistemleri temsil etmek üzere bilgisayar modelleri kurmaya yarayan doğal bir imkan sağlar. Sınıf (class) bu işin esasını oluşturur. Bir otomobil sınıfı, otomobilin argümanlarını ve bu veriler üzerinde yapılacak işlemleri çok genel bir tarzda, bir arada ifade eder. Bir sınıftan kalıtım yoluyla yeni sınıflar üretilir. Yani otomobil tanımından spor otomobili, yarış otomobili, jeep, hatta kamyonet oluşturulabilir.
Grafik bir örnek oluşturmak için genellikle ekran üzerindeki fiziksel pikselleri modellemek üzere düzlem geometride nokta tanımı kullanılır. Ekran üzerinde bir noktanın yerini göstermek üzere o noktanın x ve y koordinatları veri elemanı olarak alınıp,
struct nokta
{int x, y;};
Burada “nokta” isimli bir yapı veri tanımlanır x ve y büyüklüklerinin ekran üzerindeki bir noktayı gösterdiğini düşünürsek, o zaman kavramı değiştirmemiz gerekir. Bunun için ekran üzerindeki yeri belirten bir noktayı ışıklı bir nokta haline getirmek isteyelim, budurumda belirlenen noktayı göstermek üzere x ve y koordinatlarına bu noktanın görülebilir olması özelliğini göstermek üzere bool veri tipli parlak elemanına ihtiyaç duyarız. Bu özelliğe sahip nokta isimli yeni bir yapı veri tipi iki şekilde tanımlanır;
1-
struct Nokta
{   int X, Y;
bool Parlak;
};

2-
struct Yer
{   int X, Y;};
struct Nokta
{ YerKonum;
bool Parlak;
};

Nokta tanımının dışında veriler üzerinde gerekli işlemleri yapacak fonksiyonlar belirlenebilir. Bu durumda veri ve işlem ayrı ayrı ele alınır ya da veriler üzerinde yapılacak işlemleri gösteren fonksiyonlar, üye fonksiyonlar olarak Nokta isimli yapı veri tanımının içine katılabilir.
Yapı ve sınıf veri tipleri arasındaki biçimsel tek fark;
1-   bir yapının içindeki üyelerin varsayılan durumda public,
2-   bir sınıfın içindeki üyelerin varsayılan durumda private olmasıdır.

C++ programlama dilinde veriler ve bu veriler üzerinde yapılacak işlemlerin bir bütünlük oluşturacak şekilde bir arada tanımlandığı veri tipi sınıf (class) olarak tanımlanır. Genel kullanımı;
class sınıfın ismi
{
private:
Üye verilerin deklarasyonu
public:
Üye fonksiyonların prototipleri
}

Bir nesne ile sınıf arasında ilişki tıpkı bir değişkenle veri tipi arasındaki ilişki gibidir.
ÖRNEK:
#include <iostream>
using namespace std;
class Ornek
{ private:
int veri;
public:
       void VeriyeAta(int d)
       {veri =d;}
       void VeriyiYaz()
       {cout<<"Veri:"<<veri<<endl;}
};
int main()
{ Ornek o1, o2;
o1.VeriyeAta(55);
o2.VeriyeAta(666);
o1.VeriyiYaz();
o2.VeriyiYaz();
int i; cin>>i;
return 0;
}

Class Ornek isimli sınıfın tanımı:
1-   class ayrılmış kelimesi
2-   sınıfın adı (Ornek)
3-   { … }
4-   “;”
 Den oluşur.
Class ayrılmış kelimesi sınıfın adı; sınıfın başlığını gösterir. { … }, sınıfın gövdesidir. Üye verileri ve üye fonksiyonları burada yer alır. Yapı ve sınıf veri tiplerinin tanımları “;” ile biter. Nesnelerle programlamanın en iyi özelliği, bir veriyi izlemektir. Yani veriye kendi sınıfının dışında, başka fonksiyonlar tarafından istem dışı erişilmesini önlemektir. Veriyi gizlemenin en başta gelen yöntemi, “private” olarak tanımlamaktır. Private olarak tanımlanan veri ya da fonksiyonlara sadece kendi sınıfları içinden erişilebilir. Public olan veri yada fonksiyonlara ise kendi sınıflarının dışından da erişebilmek mümkündür. Amaç, bir sınıfın verisini diğer sınıflardan gizlemek ve programcıları hatalardan korumaktır. Ornek adındaki sınıfta veri adında ve int tipli veri elemanı vardır. Herhangi bir yapıda (struct) istenen sayıda veri elemanı olabildiği gibi, bir sınıfta da istendiği kadar veri elemanı bulunabilir. Üye fonksiyonlar bir sınıfın içinde yer alan fonksiyonlardır. VeriyeAta() ve VeriyiYaz() üye fonksiyonları vardır. Nesnelerin tanımlanmasında main() fonksiyonunda ilk ifade Ornek isimli bir sınıfın o1 ve o2 nesneleri tanımlanmaktadır. Bir sınıfın üye verilerine ulaşma ve üye fonksiyonları çağırma işlemleri, yapı veri tipli değişkenlerde olduğu gibi, “.” Kullanılarak gerçekleştirilir. VeriyeAta() üye fonksiyonunda
o1.VeriyeAta(55);
o2.VeriyeAta(666);
ifadeleriyle ulaşılır ya da VeriyeAta() üye fonksiyonu kullanılır. Bir üye fonksiyon, her zaman bir nesnenin üzerinde işlem yapmak için çağırılır. Burada Ornek sınıfının o1 nesnesinin VeriyeAta() üye fonksiyonu tarafından çağrıldığını ifade eder. o1 nesnesindeki veri değişkenine 55 değerini verir.
Örnek:
#include <iostream>
using namespace std;
#include <string>
class Kimlik
{    private:
string adi;
char cinsiyeti;
int yasi;
float boyu;
public:
       void KimlikAta(string a, char k, int y, float b)
       {
             adi = a;
             cinsiyeti = k;
             yasi = y;
              boyu = b;
       }
       void Yaz()
       { cout<<"Adi: "<<adi<<", Cinsiyeti: "<<cinsiyeti<<
       ", Yasi:"<<yasi<<", Boyu:"<<boyu<<" m \n";
       }
};
int main()
{
       Kimlik kim;
       kim.KimlikAta("Alev Gurtunca", 'b', 50, 1.58F);
       kim.Yaz(); int i; cin>>i;
       return 0;
}

Bu programda kim.KimlikAta( .. ) fonksiyon çağırma ifadesi, kimlik sınıfının kim nesnesine KimlikAta() üye fonksiyonu aracılığıyla adı, cinsiyeti, yaşı ve boyu veri üyelerini atar.
Örnek:
#include <sekilh.h>
class Daire
{
protected:
       int x, y, ycap;
       renk dolgurengi;
       dolgu dolgusitili;
public:
       void ata(int xx, int yy, int r, renk dr, dolgu ds)
       {x=xx;
       y=yy;
       ycap = r;
       dolgurengi=dr;
       dolgusitili=ds;
       }
       void ciz()
       { renk_sec(dolgurengi);
       dolgu_sec(dolgusitili);
       daire_ciz(x, y, ycap);
       }
};
int main()
{
       init_graphics();
       Daire d1, d2, d3;
       d1.ata(15, 7, 5, cMavi, X);
       d2.ata(41, 12, 7, cKirmizi, 0);
       d3.ata(65, 18, 4, cYesil, Ortam);
       d1.ciz(); d2.ciz(); d3.ciz();
       goto xy(1, 25);
       getch();
       return 0;
}

#include <iostream>
using namespace std;
#include <conio.h>
class Uzunluk
{ private:
int fit;
float inc;
public:
       void Ata(int ft, float in)
       { fit = ft; inc = in; }
       void Oku()
       { cout<<"\n fit i gir: "; cin>>fit;
       cout<<"inc i gir: "; cin>>inc;
       }
       void Yaz()
       { cout<<fit<<"fit, "<<inc<<" inc";}
};
int main()
{
       Uzunluk u1, u2;
       u1.Ata(11, 6.25);
       u2.Oku();
       cout<<"\n u1 = "; u1.Yaz();
       cout<<"\n u2 = "; u2.Yaz();
       getch();
       return 0;
}




 “İNDİS” İşlemcisi
Dizinin elemanlarına erişmek için kullanılan indis işlemcisi, “[ ]” aşırı yüklendiğinde güvenli bir dizi oluşturmak için, diziye erişmek için kullandığımız indis numaralarını otomatik olarak kontrol eden bir dizi oluşturabiliriz. Böylece indisin dizi sınırları dışına çıkması önlenmiş olur. Bunun için, dizi sınırlarının yani indis işlemcisinin referans olarak dönmesi gerekir. Güvenli bir dizi oluşturmak için, 3 tane yöntem vardır.
1- get() ve put() fonksiyonları
putel(), diziye bir eleman eklemek için; getel(), bir dizi elemanının değerini bulmak için kullanılır. Her iki fonksiyon da, dizi sınırlarının dışına çıkılmamasını garanti etmek için indis numaralarının değerini kontrol eder.
Örnek:
#include <iostream>
#include <process.h>
#include <conio.h>
using namespace std;
const int L = 12;
class GuvenliDizi
{
private:
       int diz[L];
public:
       void putel(int n, int el)
       {
             if (n<0 || n>=L)
             {
                    cout<<"\n indis siniri asti!";
                    exit(1);
             }
             diz[n] = el;
       }

       int getel( int n) const
       {
             if( n<0 || n>= L)
             {
                    cout<<"\n indis siniri asti!";
                    exit(1);
             }
             return diz[n];
       }
};
       int main()
       {
             GuvenliDizi d1;
              for (int j = 0; j<L; j++)
                    d1.putel(j, j * 10);
             for (j = 0; j<L; j++)
             {
                    int yedek = d1.getel(j);
                    cout<<j<<". eleman: "<<yedek<<endl;
             }
             getch();
             return 0;
       }
2- Referans olarak dönen bir tek access() fonksiyonu
Bir diziye güvenle hem veri eklemek, hem de diziden veri okumak için aynı üye fonksiyonu kullanabiliriz. Bunun için fonksiyondan referans yoluyla değer döndürme işlemi yapılır. Bu, şu anlama gelir: fonksiyonu = işaretinin sol tarafına yerleştirilebilir, böylece sağ taraftaki değer fonksiyonun döndürdüğü değişkene atanır.
Örnek:
#include <iostream>
#include <process.h>
#include <conio.h>
using namespace std;
const int L = 20;
class GuvenliDizi
{
private:
       int diz[L];
public:
       int& access(int n)
       {
             if (n<0 || n>= L)
             {
                    cout<<"\n indis siniri asti!";
                    exit(1);
             }
             return diz[n];
       }
};
int main()
{
       GuvenliDizi d1;
       for (int j=0;j<L;j++)
             d1.access(j) = j*10;
       for (j=0; j<L; j++)
       {
             int yedek = d1.access(j);
             cout<<j<<". eleman: "<<yedek<<endl;
       }
       getch();
       return 0;
}
3. Referans olarak dönen aşırı yüklenmiş [ ] indis işlemcisi
Güvenli bir diziye erişmek için indis işlemcisine GuvenliDizi sınıfı içerisinde yeni bir görev yüklenir, ancak bu işlemci genellikle = işaretinin sol tarafında kullanıldığı için aşırı yüklenmiş işlemci, referans yoluyla değer döndürmelidir.
Örnek:
#include <iostream>
#include <process.h>
#include <conio.h>
using namespace std;
const int L = 20;
class GuvenliDizi
{
private:
       int diz[L];
public:
       int& operator [] (int n)
       {
             if(n<0 || n>= L)
             {
                    cout<<"\n indis siniri asti!";
                    exit(1);
             }
             return diz[n];
       }
};
int main()
{
       GuvenliDizi d1;
       for (int j=0; j<L; j++)
             d1[j] = j*10;
       for (j = 0; j<L; j++)
       {
             int yedek = d1[j];
             cout<<j<<". eleman: "<<yedek<<endl;
       }
       getch();
       return 0;
}

Veri Tipi Dönüşümü
Bir değişkenin sahip olduğu değeri başka bir değişkene atamak için “=” atama işlemcisi kullanılıyordu. Örneğin;
int a = int b;
u3 = u1 + u2;
Örneğin Uzunluk sınıfı tipinde olan toplamanın sonucu u3 nesnesine atanır. Bir nesnenin değeri, aynı tipte bir başka nesneye atandığında üye veri elemanlarının tümünün değerleri, yeni nesneye kopyalanır. = atama işlemcisinin her iki tarafındaki değişkenler farklı tiplere sahipse;
1-   Önce derleyicinin temel veri tiplerini kendiliğinden nasıl dönüştürdüğüne,
2-   Daha sonra derleyicinin kendiliğinden yapmadığı ve derleyiciye ne yapması gerektiğini söylememiz gereken durumları

inceleyeceğiz.

Temel Veri Tipleri Arasındaki Dönüşümler
Örneğin:
intDeg = floatDeg;
Buradaki örnekte intDeg’in tamsayı tipinde, floatDeg’in de ondalık sayı tipinde olduğunu düşünürsek, derleyici floatDeg değişkenini tamsayı değişkenine dönüştürmek için özel bir fonksiyon çağırması gerekir. Böylece floatDeg’de saklanılması gereken değer, intDeg değişkenine aktarılabilir. Bunun için derleyicide float’tan double’a, char’dan float’a döndüren hazır fonksiyonlar vardır. Bu tür dönüşümler kapalıdır, program listesinde açıkça görülmezler. Bu tip dönüşüm yapması için (cast) işlemcisini kullanırız. Örneğin float tipinden int tipine dönüşüm için;
intDeg = static_cast<int>(floatDeg);
yazarız. Bu ifade, floatDeg isimli değişkenin tipini float veri tipinden int veri tipine dönüştürür.

Nesneler ve Temel Veri Tipleri Arasındaki Dönüşümler
Örnek:
#include <iostream>
#include <conio.h>
using namespace std;
class Uzunluk
{
private:
         const float metFit;
         int fit;
         float inc;
public:
         Uzunluk():fit(0),inc(0.0),metFit(3.280833F)
         {  }
         Uzunluk(float metre) : metFit(3.280833F)
         {
                   float fltfit = metFit * metre;
                   fit = int(fltfit);
                   inc = 12 * (fltfit - fit);
         }
         Uzunluk(int ft, float in) : fit(ft), inc(in), metFit(3.280833F)
         {  }
         void Oku()
         {
                   cout<<"\n fit i gir: "; cin>>fit;
                   cout<<"\n inc i gir: "; cin>>inc;
         }
         void Yaz() const
         {
                   cout<<fit<<" fit, "<<inc<<"inctir"; }
         operator float() const
         {
                   float OndalikFit = inc/12;
                   OndalikFit += static_cast<float>(fit);
                   return OndalikFit/metFit;
         }
};
int main()
{
         float met;
         Uzunluk u1 = 2.35F;
         cout<<"\n u1 = "; u1.Yaz();
         met = static_cast<float>(u1);
         cout<<"\n u1 = "<<met<<" metredir. \n";
         Uzunluk u2(5, 10.25);
         met = u2;
         cout<<"\n u2 = "<<met<<" metredir. \n";
         getch();
         return 0;
}
SORULAR (QUIZ VE SINAV İÇİN)
1- C++ programlama dilinde; yapı (struct) veri tipi ile sınıf (class) veri tipi arasındaki temel farkı belirtiniz.
2- Yapı veri tipi varken, sınıf veri tipine neden gerek duyulur?
3- Gerçek dünya ile sınıf (nesne) arasında nasıl bir ilişki var?
4- Üye veri ve üye fonksiyona hangi durumlarda ulaşılabilir?
5- Bir sınıfın üye fonksiyonunun sınıfın içinde veya dışında tanımlanması sırasında ne gibi değişiklikler yapılır?
6- Farklı sınıfların içinde aynı isimli üye fonksiyonların tanımlanmış olması karışıklığa sebep olur mu? Bu üye fonksiyonlar nasıl çağırılmalıdır?
7-  const Uzunluk saha(300,100); // saha nesnesi
...
void Yaz() const
{
         cout<<( (isaret == poz) ? "(+)" : "(-)" );
         Uzunluk::Yaz(); //ft ve i.
}
...
//Topla2() fonksiyonunun deklarasyonu:
Uzunluk Topla2( const Uzunluk& ) const;
Yukarıdaki ifadede const deyiminin ne anlama geldiğini açıklayınız.
8- Sınıftaki öğrencilerin kimlik bilgilerini, seçtiği üç dersi ve bu derslerin arasınav, bitirme ve başarı notlarını kaydeden ve geçme notu ile genel not ortalamasını hesaplamakta kullanılan sınıf (veya sınıfların) tanımlarını yapınız.
9- Yukarıdaki soru için tanımladığınız sınıfların nesnelerini tanımlayınız.
a. İlgili fonksiyon çağırma ifadelerini yazınız.
b. Tanımladığımız sınıfların saklanacağı bir başlık dosyası oluşturunuz.
10- Yukarıda sıralanan işlemleri değişik problemlere uygulamayı deneyiniz.

6. FONKSİYONLAR (özet)

Şu ana kadar verilen örneklerde çeşitli fonksiyonlar kullanıldı ve 3.Bölümde fonksiyonlardan kısaca bahsedildi. Bu bölümde ise fonksiyonlar başlı başına bir konu olarak ele alınacaktır.

6.1. Fonksiyon Nedir?

Fonksiyon, aldığı değerler üzerinden işlem yapabilen, değer geri döndürebilen, programın bir alt parçasıdır. Bütün C++ programları en azından bir fonksiyona sahiptirler. Bu fonksiyon main() fonksiyonudur. Bu fonksiyon otomatik olarak en başta çağırılır. Bu main() fonksiyonundan diğer fonksiyonlar ve onların içinden diğerleri çağırılabilir. Yani istenildiği kadar iç içe fonksiyon kullanmak mümkündür.

Bütün fonksiyonların bir ismi vardır. Bu ismin yazıldığı yerde program fonksiyona gider ve fonksiyonun bitiminde bir değer döndürerek çağırıldığı yerin bir satır altından program çalışmaya devam eder.

İki tip fonksiyon vardır. Birincisi kullanıcı tarafından tanımlanmış ‘user defined’ fonksiyonlar, diğeri ise derleyicinin içerisinde hazır olarak gelen ‘built in’ fonksiyonlardır.

6.2. Fonksiyon Tanımlanması

C++ programlarında fonskiyonları kullanabilmek için onları tanımlamak gerekir. Bu tanımlama fonksiyonlar hakkında üç bilgiyi derleyiciye tanıtır: fonksiyonun ismi, fonksiyonun tipi ve fonksiyonun parametreleri. Fonksiyon tanımlaması fonksiyonun ne şekilde çalışacağını gösterir. Tanımlanmadan önce bir fonksiyon çağırılamaz.

6.2.1. Fonksiyonun Tanımlanışı

Fonksiyonları tanımlamak için iki yöntem vardır. Birincisi başka bir fonksiyon tarafından çağırılmadan önce, yani programın başlarında yazılması durumunda fonksiyon çağırılabilir. Eğer ‘x’ fonksiyonuna gelmeden önce bir ‘y’ fonksiyonu ‘x’ fonksiyonunu çağıracak ise önceden ‘x’ fonksiyonunun bir prototipinin bulunması gerekir. Prototip en güzel ve tercih edilmesi gereken çözümdür. Bunun üç nedeni vardır:

1)  Fonksiyonları prototip kullanmadan programın içine sıralı bir şekilde dizmek her zaman güzel bir çözüm değildir. Programa yeni eklemeler yapıldıkça sorunlarla karşılaşılabilir.
2)  Her fonksiyon tek işlevli değildir. Dolayısıyla bir ‘x’ fonksiyonu içerisinden bir ‘y’ fonksiyonu çağırılırken, aynı anda bu ‘y’ fonksiyonu da farklı bir amaçla ‘x’ fonksiyonunu çağırıyor olabilir. Dolayısıyla prototip kullanmaksızın programda hangi fonksiyon önce
yazılırsa yazılsın çalışmayacaktır.
            3)  Prototip kullanıldığı taktirde derleyici programı çalıştırmadan da fonksiyon tipinde ya da parametrelerinde hata olduğu taktirde bunu farkedebilir.


6.2.2. Fonksiyonun Prototipi

Derleyicinin fonksiyonlar hakkında bilmesi gereken üç temel bilgi vardır. Fonksiyonun tipi, adı ve parametreleri. Prototip fonksiyon yazılmadan önce sadece bu üç özelliği tanımlamak amacı ile kullanılır ve bir tanımlama biçiminde yazılarak sonuna (;) işareti konulur.

int hacimHesapla(int, int, int);

Burada derleyiciye fonksiyonun ‘int’ tipinden olduğu, isminin ‘hacimHesapla’ olduğu ve üç tane ‘int’ tipi parametresi olduğu veriliyor. Ancak parametreleri bu şekilde kullanmak çok akıllıca değildir. Çünkü kaçıncı parametrenin neyi ifade ettiği bir süre sonra unutulabilir. Bunun için tiplerin yanına sembolik değişken isimleri girmek daha kullanışlı olacaktır.

int hacimHesapla(int en, int boy, int yukseklik);

Burada kullanılan değişken isimlerinin hiçbir önemi yoktur. Yalnızca hangi parametrenin ne olduğunu hatırlatma amaçlıdır.

Fonksiyon prototipinin kullanımına bir örnek verelim:odec c++ cevırın..

#include <stdio.h>
#include <conio.h>

int hacimHesapla(int en, int boy, int yukseklik);

void main()
{
    int e, b, y, hacim;
    char kareKarakteri = 253;
    printf("prizmanin eni: ");
    scanf("%d", &e);
    printf("prizmanin boyu: ");
    scanf("%d", &b);
    printf("prizmanin yuksekligi: ");
    scanf("%d", &y);
    hacim = hacimHesapla(e, b, y);
    printf("\nprizmanin hacmi = %d br%c\n", hacim, kareKarakteri);
    printf("\ndevam etmek icin bir tusa basiniz...");
    getch();
}

int hacimHesapla(int x, int y, int z)
{
    return x * y * z;
}
Bu örnekte dikkat edilmesi gereken nokta prototiple fonksiyonun parametrelerinde farklı isimler kullanılmış olmasıdır. Genellikle prototipte ve fonksiyonda aynı isimleri kullanmak adettir. Ancak buna mecbur değiliz. Hatta prototipte isim kullanmama hakkına da sahibiz.

Bu programda ana fonksiyondan önce hacimHesapla() fonksiyonunun prototipi tanımlanıyor. Daha sonra ana fonksiyonda ekran siliniyor ve ‘e’, ‘b’, ‘y’ ve ‘hacim’ isimli dört adet tamsayı değişkeni tanımlanıyor. Bunların hemen altında ise Tablo 4.12’de verilen ASCII karakterlerinden ‘²’ karakteri bir karakter değişkenine atanıyor.

Program çalıştırıldığı zaman bizden üç adet bilgi istiyor, ‘en’, ‘boy’, ‘yükseklik’. Klavyeden bu bilgiler girildiği anda ‘e’, ‘b’ ve ‘y’ değişkenleri hacimHesapla() fonksiyonuna parametre olarak veriliyorlar.
Program hacimHesapla() fonksiyonuna atladığı anda ‘x’ ‘e’nin, ‘y’ ‘b’nin ve ‘z’ ise ‘y’nin değerini alıyor. Burada ‘x’, ‘y’ ve ‘z’ çarpılarak değerleri geri döndürülüyor.
Program geri döndüğü zaman ‘hacim’ bu dönen değeri alıyor ve daha sonra bu değer ekrana yazılarak program sona eriyor.

6.3. Fonksiyonların Çalışma Prensibi

Fonksiyonlar çağırıldıkları anda ‘{‘ parantezini gördükleri yerden ‘}’ parantezinin kapandığı yere kadar olan program parçasını çalıştırırlar. Fonksiyonlar diğer fonksiyonları çağırabildikleri gibi ‘if’ kullanılarak kendilerini de çağırabilirler. Dizi elemanlarını hesaplamada bu tür kendini çağıran (recursive) fonksiyonlar sık sık kullanılır.

#include <stdio.h>
#include <conio.h>

void hesapla(int x, long int y);

void main()
{
      int x;
      long int y;
      clrscr();
      printf("Genel Formul:\nf(x) = [f(x + 1) + 3] / 2\n\n");
      printf("f(x) = y\nx = ");
      scanf("%d", &x);
      printf("y = ");
      scanf("%ld", &y);
      printf("f(%d) = %ld\n", x, y);
      hesapla(x, y);
      getch();
}

void hesapla(int x, long int y)
{
      long int hesap;
      if(x > 1)
      {
            hesap = 2 * y - 3;
            printf("f(%d) = %ld\n", x - 1, hesap);
            hesapla(x - 1, hesap);
      }
}
Bu program f(x) = [f(x – 1) + 3] / 2 şeklinde tanımlanmış bir dizinin 1.elemanını bulmaya yarar.

Program öncelikle dizinin kaçıncı elemanının hangi değere eşit olduğunun girilmesini istiyor. Girilen elemanın 1’den büyük olması gerekiyor (programda bu kontrol edilmiyor). Girilen eleman ve değeri hesapla() fonksiyonuna gidiyor. Burada dizi elemanlarının büyük değerler alabileceği göz önüne alınarak ‘long int’ tanımlama yapılıyor.

‘x’ yani eleman numarası 1’den büyük olduğu sürece fonksiyon bir önceki elemanı başta verilen genel formüle bağlı olarak hesaplayıp ekrana yazarak yeniden kendisini çağırıyor. Ancak bu sefer bir önceki eleman ve değeri parametre olarak veriliyor.

‘if’ kontrolü yapılmadığı taktirde kendisini çağıran bir fonksiyon genellikle sonsuza dek tekrar eder. Ancak burada dizinin 1. elemanına gelindiğinde ‘if’ koşulu gereği hesapla() yeniden çağırılmayarak fonksiyon sona eriyor ve bir tuşa basılana kadar bekledikten sonra program sona eriyor.

Bu örnekte de görüldüğü gibi iterasyon içeren hesaplamalarda kendini çağıran fonksiyonlar kullanmak çok pratik olabilir. Ancak bu kullanımın ‘infinite loop’ yani ‘sonsuz döngü’ gibi programı kilitleyici sonuçlara da yol açabileceği göz önünde bulundurularak dikkatli olmak gerekir.

6.4. Lokal Değişkenler

Bir değişken bir fonksiyonun içerisinde tanımlandığı durumda bu değişkene yalnızca bu fonksiyonun içerisinden ulaşılabilir. Diğer fonksiyonlarda bu değişken herhangi bir değere sahip olmadığı gibi tanımlanmadığı sürece kullanılamaz da. Farklı fonksiyonlar içerisinde aynı isimde lokal değişkenler kullanmak mümkündür.

Bir fonksiyon geri döndüğü andan itibaren o fonksiyonun içerisinde tanımlanmış tüm lokal değişkenler iptal olur. Bunun yanısıra geri döndüğü fonksiyonda bu değişkenlerden birinin adaşı varsa bu değişkenin değerinde, tanımlanışında hiçbir değişim olmaz.

#include <stdio.h>
#include <conio.h>

void sub();

void main()
{
      clrscr();
      int x = 10;
      sub();
      printf(“x = %d\n”, x);
      getch();
}

void sub()
{
      int x = 5;
}

Bu örnekte ana fonksiyonda ‘x’ ana fonksiyona ait bir lokal değişken olarak tanımlanıyor ve 10’a eşitleniyor.
Daha sonra çağırılan sub() fonksiyonunun içerisinde ana fonksiyonda daha önce tanımlamış olduğumuz lokal değişkenle aynı isimde bir lokal değişken tanımlanıyor ve bu sefer ‘x’ 5’e eşitleniyor.

Ana fonksiyona geri dönüldüğü gibi ‘x’in değeri ekrana yazdırılıyor ve bir tuşa basılana kadar beklenerek programdan çıkılıyor.

Bu örneğin sonucunda ekrana ‘x = 10’ yazılacaktır. Aslında sırayla inceleyecek olursak, ‘x’ 10’a eşitlendikten sonra 5’e eşitlenerek değerini değiştiriyor ve ekrana 5 yazılması gerekirdi. Ancak ‘x’ global bir değişken değil, fonksiyonuna özgü lokal bir değişken olarak tanımlandı. Bu yüzden sub’da tanımlanan ‘x’ ana fonksiyondakinden bağımsız ve fonksiyon sona erdiği gibi de yok edildi. Bunun yanısıra ana fonksiyonda tanımlanan ‘x’ de aynı şekilde sub’a gidildiği anda geçerliliğini yitirdi ve geri döndüğünde yeniden aktif oldu.

Bellek yapısı ve değişken isimleri anlatılırken bahsedildiği gibi değişkenlerin isimleri yalnızca programcı için vardır. Bilgisayar için değişkenin ismi değil, değişkenin hafızadaki yeri ve değeri önemlidir. Burada tanımlanan ‘x’leri biz aynı değişken gibi görsek de bilgisayar onları farklı hafıza adreslerinde tuttuğu için başka bir fonksiyonda tanımlanan adaş değişken öncekini silmez.

Eğer başka fonksiyonlarda kullanılmayan ya da kullanılsa da fonksiyona parametre şeklinde aktarılan bir değişken tanımlanması yapılacak olduğunda lokal tanımlama tercih edilmelidir. Ancak program içerisindeki birçok fonksiyon aynı değişkeni kullanıyorsa ya da fonksiyon yüzlerce, binlerce ya da daha fazla çağırılan bir fonksiyonsa global değişken tanımlamak tercih edilebilir. Çok tekrar eden fonksiyonlarda her seferinde tanımlama yapılıp, daha sonra fonksiyonun çıkışında bu değişken iptal edileceğine, bir kez başta global tanımlamak, programın çalışmasını hızlandıracak güzel bir optimizasyondur.

6.5. Global Değişkenler

Fonksiyonların dışında tanımlanan herhangi bir değişken global değişkendir ve ana fonksiyon dahil tüm fonksiyonlarda tekrar tekrar tanımlamadan kullanılabilir. Global değişkenlerin değerleri fonksiyondan fonksiyona değişmez, her zaman en son verilmiş olan değer üzerinden işlem yapılır.

#include <stdio.h>
#include <conio.h>

int x;

void sub();

void main()
{
      clrscr();
      x = 10;
      sub();
      printf("x = %d\n", x);
      getch();
}

void sub()
{
      x = 5;
}

Lokal değişkenler ile ilgili olarak verilen örneğin hemen hemen aynısı olan bu örnekte, sonuç 10 değil 5 olarak ekrana yazılacaktır. Çünkü ‘x’, fonksiyonların içerisinde değil en başta global olarak tanımlanıyor. Ana fonksiyonda 10 değerini aldıktan sonra sub’a gelindiğinde ana fonksiyonda değer verilen bellek adresiyle aynı adrese değer verilerek ‘x’in değeri 5 oluyor. Yeniden ana fonksiyona dönüldüğünde ‘x’in son değeri 5 olarak ekrana yazdırılıyor.

Lokal ve global değişkenler hakkında geriye tek bir soru işareti kaldı. Global tanımlanmış bir değişkenle adaş bir lokal değişken olabilir mi? Evet olabilir. Bu durumda global değişken fonksiyon sona erinceye kadar pasif duruma düşerek lokal değişken kullanılır ve fonksiyon bitiminde yeniden global değişken aktif olur.

#include <stdio.h>
#include <conio.h>

int x;

void sub();

void main()
{
      clrscr();
      x = 10;
      sub();
      printf("x = %d\n", x);
      getch();
}

void sub()
{
      int x = 5;
}

Bu örnekte tek değişen yer sub() fonksiyonunda ‘x’in başına gelen ‘int’ tanımlaması. ‘x’i burada yeniden tanımlamak demek ‘x’i lokal bir değişken olarak kullanmak demektir. Bu fonksiyon sona erdiğinde ana fonksiyonda ‘x’ tanımlanmadığı için yeniden global değişken devreye girecek ve ekrana ‘x = 10’ yazılacaktır.

Global değişkenler, genellikle tüm program boyunca sıkça kullanılacak ya da farklı fonksiyonlar tarafından ortak kullanılacak ise tanımlanırlar. Örneğin ekranın çözünürlüğü en başta “int ekranX = 640, ekranY = 480 şeklinde global tanımlanabilir. Ekran çözünürlüğü değişene kadar bütün fonksiyonlar ekrana basılacak objelerin koordinatlarını bu çözünürlüğe göre hesaplarlar. Eğer ‘#define’ kullanarak bu tür bir tanımlama yapmaya kalkarsak çözünürlük program sona erene kadar değiştirilemez. Halbuki günümüzde pekçok oyun’da çözünürlük programın içerisinden değiştirilebilmektedir.



6.6. Fonksiyon İçerisindeki Lokal Alanlar

Lokal değişkenlerin daha ileri düzeyde kullanımı fonksiyon içerisinde açılan bloklarla sağlanır. Bir fonksiyon açar kapar gibi küme parantezleri fonksiyonun içerisinde açılıp kapandığı taktirde fonksiyon içerisinde bir alt bölge yaratmak ve orada da lokal değişkenler kullanmak mümkündür.

#include <stdio.h>
#include <conio.h>

void sub();

void main()
{
      clrscr();
      int x = 10;
      printf("main'in basinda x = %d\n", x);
      sub();
      printf("main'in sonunda x = %d\n", x);
      getch();
}

void sub()
{
      int x = 5;
      printf("sub'in basinda x = %d\n", x);
      {
            printf("sub'in icindeki blogun basinda x = %d\n", x);
            int x = 1;
            printf("sub'in icindeki blogun sonunda x = %d\n", x);
      }
      printf("sub'in sonunda x = %d\n", x);
}

Bu örnek çalıştırıldığı zaman kendi kendisini açıklayacaktır. Ana fonksiyonda tanımlanan ve 10’a eşitlenen ‘x’, fonksiyonun başında ve sonunda 10 değerini ekrana yazdıracaktır. Arada sub() fonksiyonuna gelen program burada ikinci bir ‘x’ lokal değişkeni tanımlayıp bu değişkeni 5’e eşitler. Bu fonksiyonun başında ve sonunda da yine ekrana başta verilen 5 değeri yazdırılır.

Aradaki bloğa gelindiğinde ise bir tanımlama yapılana kadar hala sub()’daki ‘x’ değişkenini kullanmak mümkündür. Ancak ‘x’ burada tanımlandığı andan itibaren yalnızca bu bloğa ait bir lokal değişken olarak kullanılır. Bloğun başında ‘x’ 5 olarak ekrana yazdırıldıktan sonra lokal bir ‘x’ daha tanımlanıp 1’e eşitlenir ve bu değer bloğun sonunda ekrana yazdırılır. Blok kapandığı anda sub()’ın başında tanımlanan ‘x’ yeniden aktif olur.

6.7. Global Değişkenler Hakkında Uyarı

Global değişkenler gerekli yerlerde düzgün bir biçimde kullanıldıkları taktirde kullanışlı olabildikleri gibi birçok durumda kullanılmaları aslında tehlikelidir. Global değişkenlerde tutulan veriler tüm fonksiyonlar tarafından paylaşıldığından, bir fonksiyon diğer fonksiyondan bağımsız şekilde değişkenin değerini değiştirerek sorunlar çıkmasına neden olabilir. Oluşacak bu tür hataların en kötü yanı, fark edilmesi zor hatalar olmalarıdır. Büyük bir proje söz konusu olduğunda onbinlerce satır arasında değişkenin birinin değerini bozan yeri bulmak saatler alabilir. Aşağıda bunun çok basit bir örneği yer almaktadır.

#include <stdio.h>
#include <conio.h>

int i;

int carp(int a, int b);

void main()
{
      clrscr();
      for(i = 0; i < 10; i++)
            printf("%d * %d = %d\n", i, i, carp(i, i));
      getch();
}

int carp(int a, int b)
{
      i = a * b;
      return i;
}

Bu örnekte 0’dan 9’a kadar olan rakamların kendileriyle çarpımlarını ekrana yazdırmak istiyoruz. Ancak sonuçta 0, 1, 4 ve 25’in kendisiyle çarpımı listeleniyor. Buradaki hata ‘carp’ fonksiyonunda global tanımlı ‘i’ değişkenini kullanmamızdan ileri geliyor. Burada ‘i’nin değeri değiştiği için ‘for’ döngüsü 0’dan 9’a kadar sıralı sayma işlemini gerçekleştiremiyor.

Sorunu çözmek için ya ‘i’leri lokal kullanmak, ya da iki fonksyonda farklı değişkenler kullanmak gerekir.

6.8. Inline Fonksiyonlar

Normalde bir fonksiyon tanımlandığında derleyici bellekte bu fonksiyondan bir tane oluşturur ve fonksiyon her tekrarlanışında bu bölge çağırılır. Daha sonra da program kaldığı yerden devam etmek üzere geri döndürülür. Bu işlem çok zaman kaybettiren bir işlem değildir ancak programın içerisinde zaman zaman yüzbinlerce, milyonlarca kez çağırılan fonksiyonlar bulunur. Örneğin 1280x1024 çözünürlükte ekranı kaplayan bir resmi basmak için pixel basma fonksiyonu 1,310,720 kez çağırılır. Bu tür durumlarda fonksiyonu tanımlarken başına ‘inline’ yazarak tanımlayacak olursak programda fonksiyonun her tekrar ettiği yere fonksiyonun içeriği yazılarak işlemlerin hızlandırılması sağlanır. Ancak herşeyin bir bedeli vardır: ‘inline’ fonksiyon kullanmak programın uzunluğunu arttırır.

#include <stdio.h>
#include <conio.h>

inline int carp(int a, int b);

void main()
{
  
   int sayi1 = 11, sayi2 = 24, sonuc;
   sonuc = carp(sayi1, sayi2);
   sonuc = carp(sonuc, sayi1 + sayi2);
   printf("sonuc = %d\n", sonuc);
   getch();
}

int carp(int a, int b)
{
   return a * b;
}

Sonuç olarak ‘inline’ kullansak da kullanmasak da görünen şey aynı olacaktır. Ancak ‘inline’ kullandığımız fonksiyonlarda mantık olarak farklılık vardır.

sonuc = carp(sayi1, sayi2); satırı normalde carp() fonksiyonuna gider, gerekli işlemleri yapar ve geri döner. Burada ‘inline’ kullandığımız için carp() fonksiyonu görülen yere fonksiyonun içeriği yazılarak, satır “sonuc = sayi1 * sayi2; haline getirilir. Alttaki satır da aynı şekilde “sonuc = sonuc * (sayi1 + sayi2); şeklinde çalışacaktır. Ayrı parametreler halinde verildiğinden parantez otomatik olarak formüle eklenir yani işlem sırası karışmaz.

‘inline’ mutlaka gerçekleşecek bir komut değildir, yalnızca derleyiciye yapılan bir tavsiyedir. Derleyiciler programın yapısına göre çeşitli optimizasyonlar yaparlar. Bu arada ‘inline’ olmadığı halde varmış gibi, olduğu halde yokmuş gibi davranabilirler. Ancak bu tür bir harekette bulunuyorlarsa bu daha iyi bir sonuç almak içindir.


7. SINIFLAR ve YAPILAR

            Belirli bir konu üzerine, sınırlı kavramlar kullanarak, küçük bir uygulama yazılacağı zaman genellikle sınıf veya yapı (class, structre) kullanılmasına gerek yoktur. Ancak projeler büyüdükçe, kavramlar çoğaldıkça, aynı kriterlere sahip objeler ortaya çıktıkça, kullanılacak kavramları sınıflandırmak gerekir. Sınıflandırma, gerçek yaşamda karşılaşılan kavramları program diline dökmek konusunda programcıya üst düzeyde yardım sağlar.

            Bu bölümde sınıflar ve nesnelerin ne olduklarını, nasıl tanımlandıklarını, ne amaçla kullanıldıklarını ve bunlara bağlı üye fonksiyonları göreceğiz.

7.1. Sınıf Nedir? Neden Sınıflandırmaya İhtiyaç Duyulur?

            Sınıf, içerisinde bir konuda kriter teşkil eden değişkenler barındıran, tip belirlemek amacıyla kullanılan, içerisindeki değişkenlere ancak o sınıf tipinde tanımlanmış bir nesnenin üyeleriyle ulaşılabilen bir tanımlamadır. Diğer bir değişle sınıf değişkenler koleksiyonudur. Bu değişkenler tanımlanışları dışında direkt olarak değer almazken, o sınıf tipinde tanımlanmış bir nesnenin özellikleri şeklinde, nesnenin üyeleri biçiminde değerler alabilirler.

            Doğa sınıflandırma konusundaki en iyi örnektir. Doğadaki her varlık eşsizdir ancak benzer kriterlere sahip olanlar aynı kategoriye, aynı sınıfa girerler. İnsanlar, hayvanlar, çiçekler ve böcekler birer sınıftır. Güller ise çiçeklerin bir alt sınıfıdır. Eğer daha fazla detaya ihtiyaç duyulmuyorsa gülleri bir sınıf olarak kabul ettikten sonra bu sınıfın üyeleri olarak renk, boyut ve ülke tanımlanabilir. Geniş yapraklı siyah İngiliz gülü ile küçük kahverengi Türk gülünün ortak özellikleri arandığı zaman, ikisinin de çiçek olması ve ikisinin de aynı tür çiçek yani gül olması ilk olarak göze çarpan belirgin özellikleri. Gül sınıfının üyelerine bakacak olursak renk, boyut ve ülke kriterleri sırasıyla ilkinde ‘siyah’, ‘geniş yapraklı’, ‘İngiliz’, diğerinde ise ‘kahverengi’, ‘küçük’ ve ‘Türk’. Bu şekilde bir sınıf oluşturmuş olduk.

            Örneğin bir bilardo oyunu yapmaya karar verdiğimizi düşünelim. Ekranda 10’u aşkın bilardo topu mevcut olsun. Her biri x, y konumu, ivme vektörü, ivme vektör bileşenleri, spini, top numarası ve top tipi özellikleri ile tanımlanmış olsun. Sınıflandırma kullanmazsak şu şekilde değişkenler tanımlamamız gerekir.

      int beyazTopX, beyazTopY, beyazTopNo, beyazTopTip;
      float beyazTopA, beyazTopAX, beyazTopAY, beyazTopSpin;
      int birinciTopX, birinciTopY, birinciTopNo, birinciTopTip;
      float birinciTopA, birinciTopAX, birinciTopAY, birinciTopSpin;
      int ikinciTopX, ikinciTopY, ikinciTopNo, ikinciTopTip;
      float ikinciTopA, ikinciTopAX, ikinciTopAY, ikinciTopSpin;
      ...
      ...
      int siyahTopX, siyahTopY, siyahTopNo, siyahTopTip;
      float siyahTopA, siyahTopAX, siyahTopAY, siyahTopSpin;
           
            Topların çarpışıp çarpışmadığını kontrol etmek istediğimizde karşımıza büyük bir sorun çıkar. Ekranda 10 adet top olduğunu varsayarsak (n² - n) / 2 formülünden (100 - 10) / 2 = 45 adet çarpışma kontrolü yapmamız gerekir. Sınıflandırma kullansak da kullanmasak da bu 45 çarpışma ihtimalinin test edilmesi şarttır. Bu durumda sınıflandırmanın bir faydası yoktur, fakat sınıflandırma bize iki nesne arasında test fonksiyonu yazmak için büyük kolaylıklar sağlar. Göstergeler (pointer) ve kaynakların (reference) da kullanılmasıyla sınıf ve yapılar bu tür problemlerin basite indirgenmesine yardımcı olurlar.

            7.2. Sınıflar ve Üyeler

            Bir sınıf tanımlamak demek, yeni bir tip yaratmak demektir. Sınıflar çeşitli değişkenler ve onlara bağlı olan fonksiyonlardan ibarettir. Bir konu üzerinde birden fazla yönde kriter belirlenebilir. Örneğin bir arabanın rengi, markası, modeli bir kriter oluşturabileceği gibi hızı, hareket yönü, ivmesi de bir kriter oluşturabilir. Sınıflandırma bütün bu özellikleri tek bir koleksiyonda toplamaya yarar. Bu şekilde oluşturulan değişken koleksiyonlarına nesne (obje) denir.

            Sınıflandırma sayesinde veriye ulaşmak, veriyi işlemek ve kopyalamak daha basit bir  hale gelir. Programın içerisinde sınıfla ilgili işlem yapan program parçaları verinin ne olduğuna aldırmadan kolaylıkla işlem gerçekleştirebilir.

            Kriter olarak bir sınıfın içerisinde tanımlanan her bir değişkene ‘üye değişken’ ya da ‘üye veri’ denir. Arabanın lastiklerinin arabanın bir parçası olduğu gibi, üyeler de sınıfın birer parçasıdır.

            Bir sınıf içerisinde başka bir sınıf da kullanılabilir. Örneğin ‘arabanın lastiği’ bir sınıf olarak tanımlanabilir. Yol tutuşu, çapı, genişliği, dayanıklılığı gibi kriterlerden bir lastik sınıfı oluşturulabilir. Daha sonra, araba sınıfını tanımlarken, lastik tipi arabanın bir alt sınıfı olarak tanımlanabilir. Bu şekilde istenildiği kadar iç içe sınıf tanımlaması yapılabilir.

            Sınıfların içerisinde üye değişkenler tanımlanabildiği gibi üye fonksiyonlar da tanımlamak mümkündür. Bu fonksiyonlar, tanımlanmış olan sınıfla ilişkili olan fonksiyonlardır. Araba için gaz(), fren(), savrulma(), yakıtAzalt() gibi fonksiyonlar araba sınıfının birer üye fonksiyonudur.

Üye fonksiyonlara metotlar da denir. Metotlar, sınıfın nesnelerinin ne yapabileceğini belirlerler.

7.2.1. Sınıf Tanımlama

Sınıf tanımlarken kullanılan komut, sınıfın ingilizcesinden gelen ‘class’ komutudur. Komutun ardından sınıfın ismi yazılmak suretiyle bu isimde bir sınıf yaratılmış olur. Sınıfın üye değişkenleri ve üye fonksiyonları da sınıfın isminin ardından açılıp kapanan küme parantezleri arasında kalan alanda tanımlanırlar. Küme parantezi kapatıldıktan sonra, ‘enum’ komutunda olduğu gibi (;) konularak tanımlama sona erer.

class Insan
{
unsigned int yas;
unsigned int kilo;
Yaslan();
KiloAl();
KiloVer();
};

            Bu örnekte ‘insan’ isminde bir sınıf tanımlanıyor. Yaş ve kilo değişkenleri tanımlandıktan sonra yaşlanmayı sağlayacak olan Yaslan() ve kilo alıp kaybetmeye yarayacak olan KiloAl(), KiloVer() fonksiyonları tanımlanıyor.

            7.2.2.  Sınıfların İsimlendirilmesi

            Bölüm 4.5’de değişken isimlendirmeleriyle ilgili bilgi verilmişti. Sınıflar da isimlendirilirken aynı kurallar geçerlidir. Ancak sınıflar bir ‘tip’ teşkil ettiğinden ayırt edici olması amacıyla ya ilk harfi ya da tamamen büyük harf kullanılarak isimlendirilirler. ‘insan’ yerine ‘Insan’ ya da ‘INSAN’ gibi. Birçok programcının kullandığı bir diğer isimlendirme yöntemi de sınıf isminin başına ‘class’ kelimesini temsilen bir ‘c’ harfi koymaktır. ‘cInsan’, ‘cAraba’, ‘cKedi’ gibi. İlerleyen örneklerde yalnızca ilk harf büyük yazılarak sınıf tanımlaması yapılacaktır. Fakat diğer sınıf isimlendirmelerinin de bilinmesi farklı programcıların yazdığı programları incelerken faydalı olacaktır.

            Metotlar yani üye fonksiyonlar isimlendirilirken de bütün kelimelerin ilk harflerini büyük harf olarak yazmak kullanışlı bir yöntemdir. GazPedalinaBas(), FrenYap() gibi.

         7.2.3. Nesne (Obje) Tanımlama

            Sınıf tanımlama örneği olarak gördüğümüz ‘Insan’ sınıfı, bu sınıfı kullanarak bir nesne tanımlamadığımız sürece programın içerisinde yalnızca yer kaplayacaktır. Sınıflar program içerisinde ‘int’, ‘float’ gibi yalnızca bir tip olarak yer alırlar. Onları işe yarar hale getirmek için bir tanımlama yapmak gerekir.

            int x;
            float m;
            Insan Ali;

            Bu program parçası ‘x’ isimli bir tamsayı, ‘m’ isimli bir ondalıklı sayı ve ‘Ali’ isimli bir insan tanımlar.

            7.2.4. Sınıflarla Nesnelerin Karşılaştırılması

            Gerçek yaşamda arabanın tanımı alınmaz, arabanın kendisi alınır ve kullanılır. Arabanın tanımının benzini bitmez, kullanılmakta olan arabanın benzini biter. Aynı şekilde C++’da da bir ‘Araba’ sınıfı yaratılırken arabaların genel özellikleri ve başlarına gelebilecek olaylar düşünülerek bir sınıf oluşturulur. Ancak asla bu ‘Araba’ sınıfı kullanılmaz, ‘Araba’ sınıfıyla tanımlanan özel bir araba nesnesi kullanılır ve olaylar bu nesnenin üzerinde gelişir.

            7.3. Sınıf Üyelerine Erişim

            Yukarıda teorik olarak gösterdiğimiz eşitliği C++ diline çevirelim.

class Insan
{
unsigned int yas;
unsigned int kilo;
Yaslan();
KiloAl();
KiloVer();
};

Insan Ali;

         Ali.yas = 19;

            Görüldüğü gibi sınıfların üyelerine erişmek için nesneleri kullanmak zorundayız. Nesne’nin tanımlandığı sınıfa ait bir üye değişken ya da üye fonksiyona ulaşmak için nesne tanımlandıktan sonra nesneye verilen ismin arkasına nokta konularak değişken ya da fonksiyonun adı yazılır.

class Insan
{
unsigned int yas;
unsigned int kilo;
Yaslan();
RejimYap();
KiloAl();
KiloVer();
};

Insan Ali;

Ali.yas = 20;
Ali.kilo = 70;
Ali.Yaslan();
      Ali.KiloAl();
      Ali.RejimYap();
      Ali.KiloVer();

            Bu örnekte Ali’nin yaşlandıkça kilo aldığı ve aldığı kiloları rejim yaparak verdiği varsayılmış ve fonksiyonlar buna göre tanımlanmıştır. Sınıfları kullanarak C++’da bu tür gerçek yaşam kompozisyonları yazmak mümkündür. Sınıfların sağladığı en büyük yararlardan biri programın okunabilirlik seviyesini arttırmasıdır. Bu örnekteki gibi düzgün sınıf, değişken ve fonksiyon isimleri seçildiği taktirde programı incelemek kitap okumak kadar kolay bir hal alır.

            7.3.1. Sınıflara Değil, Nesnelere Değer Girmek

Bir insanın yaşı ve ağırlığı ne kadardır? Bu soruya gerçek hayatta cevap aranırsa kesin bir yanıt bulunamaz. Ancak değer aralıkları ve ihtimallerle karşılaşılır. Aynı şekilde C++’da da ‘Insan’ sınıfı kullanılarak bu sınıfın üye değişkenlerine değerler atanamaz. Ancak bu sınıfla tanımlanan bir nesneye, örneğin ‘Ali’ye bağlı olarak bir yaş ve kilo değeri belirlenebilir.

            İnsan’ın yaşı = 20 (Yanlış)
            Ali’nin yaşı = 20 (Doğru)

            Bu eşitlikleri C++’a çevirecek olursak.

      Insan.yas = 20; // Yanlış
      Ali.yas = 20; // Doğru

            ‘Insan.yas’ı bir değere eşitlemeye çalışmak ‘int’i bir değere eşitlemeye çalışmaktan çok daha mantıklı değildir. Sırasıyla önce nesne tanımlanmalı, daha sonra bu nesne kullanılarak bir değer verilmelidir.

      Insan Ali;
      Ali.yas = 20;

            7.3.2. Tanımlanmayan Özelliklerin Sınıfa Dahil Olmaması

            Sınıf içerisinde tanımlanmayan bir özelliğin sınıfa dahil olmaması pek de şaşırılacak bir durum değildir. Ancak özellikle eski derleyicilerde sınıfların üye değişken ve fonksiyonlarını listeleme özelliği bulunmadığı için gerek yazım hatası, gerek dikkatsizlik sonucu tanımlanmayan bazı sınıf üyeleri kullanılmaya çalışılabilir ve sonucunda program hata verir.

            Şimdi, aşağıdaki örneği inceleyelim:

            class Kopek
{
      int saldirganlikDerecesi;
      int boy;
      int agirlik;
      Havla();
      Isir();
      OyunOyna();
};

Kopek Arsiz;
Arsiz.saldirganlikDerecesi = 3;
Arsiz.yas = 4; // Yanlış
Arsiz.Havla();
Arsiz.Konus(); // Yanlış
Burada, ‘Kopek’ isimli bir sınıf yapısı içerisinde, köpekler çeşitli özellikleri ile tanımlanmış, ancak köpekler konuşamaz. Bu durumda Arsız’ı konuşturmaya çalıştığımız anda program hata verecektir. Ancak bundan önce yapılan bir başka hata Arsız’ın yaşını belirlemeye çalışmaktır. Köpekler konuşamaz ancak köpeklerin de yaşı vardır. Yine de sınıfın içerisinde bir yaş özelliği tanımlanmamışsa, bu şekilde Arsız’a herhangi bir yaş değeri verilemez.

7.4. Kullanıma Kapalı ve Açık Üyeler

Bu bölüm içerisinde şu ana kadar verilen program parçalarının her biri temsilidir ve çalışmaz haldedirler. Çünkü aksi söylenmediği sürece sınıf üyeleri kullanıma kapalıdır ve ancak sınıf fonksiyonları tarafından erişilebilirler.

class Kedi()
{
      unsigned short int yas;
      Miyavla();
};

Kedi.yas = 2; // Yanlış
Kedi.Miyavla(); // Yanlış

            Üyelerin erişilebilir veya erişilemez olmasını belirleyen komutlar ‘public’ ve ‘private’dır yani ‘açık’ ve ‘özel’. Eğer hiçbir tanımlama yapılmazsa sınıfın üyeleri otomatik olarak ‘private’ kabul edilir. Bu yüzden üyelere erişmek için ‘public’ tanımlaması yapılması gerekir. ‘public’ ve ‘private’ birer label gibi tanımlanırlar yani sonlarına ‘:’ işareti konulur.

class SinifIsmi()
{
      public:
      ...
      ...
      ...
      private:
      ...
      ...
      ...
};



7.11. Sınıfın Bir Üyesini Başka Bir Sınıfla Tanımlamak

Daha önce de bahsedildiği gibi bir sınıfın üye değişkeni başka bir sınıfla tanımlanmış olabilir. Örneğin bir çember noktalardan oluşmuştur. İki boyutlu bir düzlemde her bir noktanın x ve y gibi iki koordinatı vardır. Bu durumda bir ‘Nokta’ sınıfı tanımlanacak olursa, bu sınıfa ait iki değişken de ‘x’ ve ‘y’ değişkenleri olacaktır. Çember için bir ‘Cember’ sınıfı tanımlanması gerekir. Bu sınıfın da yarıçap ve koordinat değişkenlerine ihtiyacı olacaktır. Bu değişkenlerden yarıçap tamsayı olarak tanımlanırken koordinat daha önce tanımlanmış olan ‘nokta’ sınıfıyla tanımlanır.

Şimdi yukarıda anlatılanları programa dökerek bir çember çizdirelim:

#include <stdio.h>
#include <conio.h>
#include <math.h>

#define PI 3.1415926535

class Nokta
{
      public:
      int x;
      int y;
};

class Cember
{
      public:
      Cember(int yc);
      ~Cember();
      void CemberCiz();
      private:
      Nokta Koordinat;
      int yariCap;
};

Cember::Cember(int yc)
{
      yariCap = yc;
}

Cember::~Cember()
{
}

void Cember::CemberCiz()
{
      for(int i = 0; i < 360; i++)
      {
            Koordinat.x = 40 + (2 * yariCap * cos((float)i / 180 * PI));
            Koordinat.y = 13 + yariCap * sin((float)i / 180 * PI);
            gotoxy(Koordinat.x, Koordinat.y);
            printf("xx");
      }
}

void main()
{
      clrscr();
      Cember Tekerlek(10);
      Tekerlek.CemberCiz();
      getch();
}

Daha önce bir elips çizdirme örneği yapılmış olduğundan (bkz. Bölüm 5.4.3) bu örnek için açıklama yapılmayacaktır. Ancak bu örnekte dikkat edilmesi gereken konu ‘Cember’ sınıfında tanımlanan ‘Koordinat’ değişkeninin ‘Nokta’ sınıfıyla tanımlanması ve daha sonra bu ‘Koordinat’ın CemberCiz() fonksiyonunda ‘Koordinat.x’ ve ‘Koordinat.y’ şeklinde sınıf üye değişkenleriyle sınıf içi sınıf şeklinde kullanılmasıdır.

Sınıf içi sınıf kavramının daha iyi anlaşılması için biraz daha teorik ancak açıklayıcı bir örneği inceleyelim:

#include <stdio.h>
#include <conio.h>

class A
{
      public:
      int x;
};

class B
{
      public:
      A y;
};

void main()
{
      clrscr();
      B Nesne;
      Nesne.y.x = 3;
      printf("Nesnenin ilk degeri = %d\n", Nesne.y.x);
      Nesne.y.x++;
      printf("Nesnenin ikinci degeri = %d\n", Nesne.y.x);
      getch();
}

Bu örnekte A sınıfında bir ‘x’ tamsayı değişkeni tanımlandıktan sonra B sınıfında bir ‘y’ A tipi değişken tanımlanıyor. Daha sonra ana fonksiyonda B tipi bir nesne tanımlanıyor ve bu nesnenin üye değişkeni olan ‘y’ye değer girilmek isteniyor. Ancak ‘y’ bir tamsayı değişken değil, A tipinden bir değişken. A sınıfında tamsayı olan ‘x’ tipi bir değişken tanımlı. Bu durumda A tipiyle tanımlanmış olan ‘y’nin üye değişkeni olan ‘x’e ulaşmak üzere ‘y.x’ yazmak gerekiyor. Sonuçta ‘Nesne’ye bir tamsayı değer vermek gerektiğinde ‘Nesne.y.x’ şeklinde sınıf içi sınıf kullanılmış oluyor.

Bu örnek her ne kadar teorik olması açısından karmaşık görünse de, başka programcılar tarafından yazılmış bu tür anlamsız program parçalarını inceleyip anlamak yönünden iyi bir pratik olacaktır.

7.12. Struct Komutu ile Class Komutu Arasındaki İlişki

Bu bölüme ‘Sınıflar ve Yapılar’ başlığı atıldı. Ancak şu ana kadar hep sınıflardan bahsedildi. Çünkü sınıf ve yapı hemen hemen aynı şeydir. Biri ‘class’ diğeri ise ‘struct’ komutu ile tanımlanır. Aralarındaki asıl fark ise yapı (structure) ‘private’ bölümünü içermez, yalnızca ‘public’den ibarettir. Ayrıca yapılarda ‘public:’ şeklinde bir tanımlamaya da ihtiyaç duyulmaz ve doğrudan küme parantezinden sonra ilgili üyeler girilir.

Yapıların sınıflara göre eksikliği sadece metotlar tarafından erişilebilen gizli üye değişkenler yaratılamamasıdır. Bütün üye değişkenlere nesne üzerinden direkt erişim mümkündür. Bunun yanında, bu tür gizli üye değişkenler kullanılmayacağı taktirde sınıflarda mecburen yaptığımız ‘public:’ tanımlamasını yapmadan yapıları kullanabiliriz.

Geçtiğimiz bölümde verilen çember çizme örneğini mümkün olan yerlerde yapı kullanarak yeniden düzenleyelim:

#include <stdio.h>
#include <conio.h>
#include <math.h>

#define PI 3.1415926535

struct Nokta
{
      int x;
      int y;
};

class Cember
{
      public:
      Cember(int yc);
      ~Cember();
      void CemberCiz();
      private:
      Nokta Koordinat;
      int yariCap;
};

Cember::Cember(int yc)
{
      yariCap = yc;
}

Cember::~Cember()
{
}

void Cember::CemberCiz()
{
      for(int i = 0; i < 360; i++)
      {
            Koordinat.x = 40 + (2 * yariCap * cos((float)i / 180 * PI));
            Koordinat.y = 13 + yariCap * sin((float)i / 180 * PI);
            gotoxy(Koordinat.x, Koordinat.y);
            printf("xx");
      }
}

void main()
{
      clrscr();
      Cember Tekerlek(10);
      Tekerlek.CemberCiz();
      getch();
}

            Bu örneğin daha önceki örnekten tek farkı ‘Nokta’nın sınıf olarak değil yapı olarak tanımlanmış olmasıdır. Bu yapının başında ‘public:’ tanımlamasına da gerek olmadığından program bir satır kısalmıştır.

            ‘Cember’ sınıfı da yapı olarak tanımlanabilirdi ancak bu durumda ‘Koordinat’ ve ‘yariCap’ gizliliklerini yitirir ve direkt erişim iznine sahip olurlardı. Programın temel yapısını bozmamak amacıyla ‘Cember’ sınıf olarak bırakıldı. Bunun yanında ‘Nokta’ ‘private’ içermeyen bir sınıf olduğu için ‘struct’ yani yapı olarak tanımlanabildi.