340 likes | 651 Views
NESNEYE YÖNELİK PROGRAMLAMA C++’a Giriş. Özlem AYDIN Trakya Üniversitesi Bilgisayar Mühendisliği Bölümü. Not: Bu sunumda Doç. Dr. Yılmaz KILIÇASLAN’ın Nesneye Yönelik Programlama dersi sunumlarından faydalanılmıştır. C DİLİNİN BİR ÜST-KÜMESİ OLARAK C++.
E N D
NESNEYE YÖNELİK PROGRAMLAMA C++’a Giriş Özlem AYDIN Trakya Üniversitesi Bilgisayar Mühendisliği Bölümü Not: Bu sunumda Doç. Dr. Yılmaz KILIÇASLAN’ın Nesneye Yönelik Programlama dersi sunumlarından faydalanılmıştır.
C DİLİNİN BİR ÜST-KÜMESİ OLARAK C++ • Genel olarak, C’de mevcut olan her şey C++’da da vardır. • C dilinde yazılmış kodlar herhangi bir C++ derleyicisinde derlenebilir. • C++, eklemiş olduğu yaklaşım değiştirici nitelikte özellikler ile C dilinden daha büyük bir kümeyi kapsar.
INPUT-OUTPUT İÇİN STREAM KULLANILMASI-cout • C++ input (giriş) ve output (çıkış) işlemleri için “stream” (byte’ların dizisi şeklinde veri transferi) olarak bilinen mekanizmalar kullanır. Standart outputstream’icoutismiyle adlandırılır: • Örnekte, C’den farklı olarak; • stdio.h yerine iostream.h • printf yerine cout ve bit-tabanlı sola kaydırma operatörü (<<) kullanılmıştır.
INPUT-OUTPUT İÇİN STREAM KULLANILMASI-cout • C++’da çıktı için format string’ine ihtiyacınız yoktur: #include <iostream> usingnamespacestd; int main() {intmiktar = 123; cout << miktar; return 0; } • C dilinde -> printf(“%d”, miktar); • coutstream’i farklı veri tiplerinin ayırdındadır ve onları doğru olarak yorumlayabilir: cout << “Miktar:” << miktar << “.”;
INPUT-OUTPUT İÇİN STREAM KULLANILMASI-manipülatörler • C++ çıktılarını da “manipulatörler” aracılılığıyla formatlamak mümkündür. Aşağıdaki program manipülatör kullanarak tamsayılar (integers) için varsayılan formatı nasıl değiştirebileceğimizi örneklemektedir: #include <iostream> usingnamespacestd; intmain() { intmiktar = 123; cout<< “decimal değeri:” << dec<< miktar << “\n”; cout << “octal değeri:” << oct << miktar << endl; cout << “hexadecimal değeri:” << hex << miktar << “\n”; return 0; } Program çıktısı nedir?
PROGRAM ÇIKTISI decimal değeri:123 octal değeri:173 hexadecimal değeri:7b
INPUT-OUTPUT İÇİN STREAM KULLANILMASI-cin • C++’ınstandardinputstream’i ise cinolarak adlandırılır. Aşağıdaki program klavyeden bir tamsayının nasıl girdi olarak alınacağını göstermektedir: #include <iostream> usingnamespacestd; intmain() { intmiktar = 123; cout<< “Bir miktar girin...\n”; cin >> miktar; cout<< “Girdiğiniz Miktar: “ << miktar; return0; }
INPUT-OUTPUT İÇİN STREAM KULLANILMASI-cin • cindiğer tipte veri girişleri için de kullanılabilir: #include <iostream> usingnamespacestd; int main() { charisim[20]; cout << “Bir isim girin...\n”; cin >> isim; cout << “Girdiğiniz İsim: “ << isim; return 0; }
AÇIKLAMALAR (COMMENTS) • C++, C’de çoklu satır açıklamasında kullanılan /* ... */ açıklama formatına ek olarak, tek-satır açıklamaları için // işaretinin kullanımına izin vermektedir. // C++’da Açıklama Yazılması #include <iostream> usingnamespacestd; int main() { charisim[20]; // Karakter katarı bildirimi cout << “Bir isim girin...\n”; //İsim giriş isteği cin >> isim; //İsmin okunması cout << “Girdiğiniz İsim: “ << isim; return 0; }
FONKSİYON PROTOTİPLERİ • Fonksiyon prototipi, fonksiyonun ismini, döndüreceği değeri, parametrelerin sayısını ve tipini tanımlar. • C++, eğer çağrılmadan önce tanımlanmamışsa, her fonksiyon için prototip bildirimi ister. #include <iostream> usingnamespacestd; voidgoruntule(char *s); //Fonksiyon prototipi int main() { goruntule(“Merhaba!”); return 0; } voidgoruntule(char *s) { cout << s; }
VARSAYILAN FONKSİYON ARGÜMANLARI-1 • C++’da bir fonksiyon prototipinde bazı parametreler için varsayılan değerler belirlemek mümkündür. • Fonksiyon çağrımı yaparken varsayılan değer almış argümanları belirtmezseniz derleyici otomatik olarak bu argümanlar için varsayılan değerleri kullanır. • Eğer kendi argümanlarınızı kullanırsanız, derleyici varsayılanlar yerine onları kullanır. • Bir argümanı belirtmez iseniz sağındaki diğer argümanları da belirtmemelisiniz: f( , 3.45); // Error
VARSAYILAN FONKSİYON ARGÜMANLARI-1 #include <iostream> usingnamespacestd; void f(int i=5, double d=1.23);//Fonksiyon prototipi intmain () { // Fonksiyon Çağrımları f(12, 3.45); f(3); f(); return 0; }
VARSAYILAN FONKSİYON ARGÜMANLARI-2 • Aşağıdaki programın çıktılarını belirleyiniz: #include <iostream> usingnamespacestd; voidshow( int i=5, floatf=2.3, longl=4 ); intmain() { show(); show(5); show(6,7.8); show(9,10.11,12L); return 0;} voidshow(intfirst, floatsecond, longthird) { cout << “\nfirst = “ << first; cout << “, second = “ << second; cout << “, third = “ << third; }
PROGRAM ÇIKTISI: first :5, second :2.3, third :4 first :5, second :2.3, third :4 first :6, second :7.8, third :4 first :9, second :10.11, third :12
DEĞİŞKEN BİLDİRİMLERİNİN YERİ - 1 • C’de değişken bildirimlerini blok başında yapmanız beklenir. C++’da ise referansta bulunmadan önce olmak koşuluyla bir değişkenin bildirimini kodun herhangi bir yerinde yapabilirsiniz. intmain() { cout << “Bir sayı girin...\n”; intsayı; cin >> sayı; cout << “Girdiğiniz Sayı: “ << sayı; return 0; }
DEĞİŞKEN BİLDİRİMLERİNİN YERİ - 2 • Aşağıdaki ifade doğrudur. for (intctr = 0; ctr < MAXXTR; ctr++) • Fakat, aşağıdaki ifadeler hatalıdır: if( int i == 0 ) // Error while( int i == 0 ) // Error
DEĞİŞKEN BİLDİRİMLERİNİN YERİ - 3 • Aşağıdaki örnekte bir değişken bildirimi bir blok içinde yapılmıştır: intmain() { intsatirNo; for( satirNo = 0; satirNo < 3; satirNo++ ) { inttemp = 22; cout << “\nSatir No:” << satirNo << “–Temp:” << temp; } cout << satirNo; // satirNoerisilebilir // cout << temp; // temperisilemez return 0; } Program çıktısı nedir?
KAPSAM ÇÖZÜMLEYİCİ OPERATÖR • C’de yerel bir değişken aynı isimli global bir değişkene göre önceliklidir. Örneğin, hem bir yerel değişken hem de global bir değişken miktarismiyle adlandırılmışsa ve yerel değişken referans kapsamı içinde ise miktar her kullanıldığında referans yerel değişkene yapılmış olur; yani, global değişken görünmez olmuştur. • C++, bu tür durumlarda, global değişkene de erişime izin verir. Değişkenin önüne kapsam çözümleyici operatör olan :: işaretinin konulması halinde kullanılanın yerel değil global değişken olduğu anlaşılır. • İç içe gömülmüş kapsam alanlarında :: bir üst kapsam alanındaki değişkenlere değil global değişkenlere erişim sağlar.
KAPSAM ÇÖZÜMLEYİCİ OPERATÖR - örnek #include <iostream> usingnamespacestd; int miktar = 23; // Global Degisken intmain() { int miktar = 456; // Yerel Degisken cout << ::miktar; cout << “\n”; cout << miktar; return 0; } Program çıktısı nedir?
INLINE FONKSİYONLAR - 1 • C++’da gerçekte çağrılmayan, fakat her çağrı noktasında satır içerisinde genişleyen fonksiyonlar tanımlanabilir. • C++’dakiinline anahtar sözcüğü beraberinde kullanıldığı fonksiyonun bir kopyasının çağrıldığı her yere eklenmesini sağlar. Eğer, bir inline fonksiyonu programınızda 20 kez çağırıyorsanız, derleyici bu fonksiyonun 20 kopyasını .EXE dosyanıza ekleyecektir. • Fonksiyon kopyalarının bu şekilde eklenmesi fonksiyon çağrımından doğan “overhead” zamanını ortadan kaldırarak programınızı hızlandıracaktır. Fakat, bir fonksiyonun birçok kopyasını yaratmak da program kodunuzun büyümesine yol açacaktır. Bu nedenle, inline niteleyicisi yalnızca fonksiyon çok kısa ise yada az sayıda çağrılıyorsa kullanılmalıdır.
INLINE FONKSİYONLAR – 1 - örnek #include <iostream> usingnamespacestd; inline intmax(int a, int b) { return a>b ? a : b; } intmain() { cout << max(10, 20); cout << " " << max(99, 88); return 0; }
INLINE FONKSİYONLAR - 2 • inline fonksiyonlar #define ile bildirimi yapılmış makrolara benzerler; fakat, makrolar basit bir metin değiştirici ile gerçeklenirken, inline fonksiyonlar derleyici tarafından tanınırlar. • Derleyici tarafından tanınmanın avantajı, derleyicinin inline fonksiyonun parametreleri üzerinde tip kontrolü yapabilmesidir. • Diğer avantajı ise, inline fonksiyonların sıradan fonksiyonlar gibi davranıp makroların neden olabileceği yan etkileri yaratmamasıdır:
INLINE FONKSİYONLAR - örnek #include <iostream> usingnamespacestd; #define MAX( A, B ) ((A) > (B) ? (A) : (B)) inline intmax(int a, int b) { if (a>b) return a; return b; } intmain() { int i, x, y; x = 23; y = 45; i = MAX(x++, y++); // buyuk deger iki kez arttırıldı cout << "x = " << x << " y = " << y << "\n"; x = 23; y = 45; i = max(x++, y++); cout << "x = " << x << " y = " << y << "\n"; return 0;} Program çıktısı nedir?
PROGRAM ÇIKTISI x = 24 y = 47 x = 24 y = 46
constNİTELEYİCİSİ - 1 • C gibi, C++ da değişkenleri sabitlere dönüştüren constniteleyicisini destekler. C’deconst niteleyicisi, ilk değer ataması haricinde, değişkenin salt-okunur olduğunu belirtir. C++, bir adım daha ileri gider ve sabit bir ifade kullanılan her yerde bir const ifadesi kullanmanıza izin verir: #include <iostream> usingnamespacestd; intmain() { constint boyut = 5; charcs[boyut]; cout << “ cs dizininin buyuklugu: “ << sizeofcs; return 0;} • Fakat, C++’da bile bir constdeğişkeninin ilk değerini sabit bir ifade haricinde bir şeyle belirleyemezsiniz. Örneğin, boyut değişkeni bir fonksiyon içinde bildirilmiş bile olsa, ilk değerini fonksiyonun bir parametresi üzerinden alamaz.
constNİTELEYİCİSİ - 2 • constniteleyicisi işaretçi bildirimlerinde de kullanılabilir. Bu tür bildirimlerde niteleyicinin yeri önemlidir: char *constptr = buf; // const işaretleyici *ptr = ‘a’; // legal ptr = buf2; // error • Aşağıdaki bildirimlerin anlamı ise farklıdır: constchar *ptr = buf; // const’a işaretleyici ptr = buf2; // legal *ptr = ‘a’; // error
constNİTELEYİCİSİ - 3 • const niteleyicisi bir fonksiyonun parametrelerinden birinin değerini değiştirmesine engel olmak için de kullanılabilir: int salt_okur( conststructNode *nodeptr ); Bu prototip salt_okur fonksiyonunun parametresinin işaret etmiş olduğu Node topluluğunu değiştiremeyeceğini bildirmektedir. Fonksiyon içinde (sıradan) bir işaretçi bildirimi yapılmış bile olsa, parametre güvenceli olarak kalır; çünkü, salt-okur bir işaretçiyi sıradan bir işaretçiye atayamazsınız: int salt_okur( conststructNode *nodeptr ) { structNode *writeptr; // sıradan işaretçi writeptr = nodeptr; // error }
STRUCTURES, UNIONS, ENUMERATIONS • C++’da, structure, union yada enumeration olan bir veri tipinde değişken bildirirken struct, union ve enum anahtar sözcüklerinin kullanılmasını zorunlu değildir: C Formatı: structaddraddr_info; union u_type dönüştürücü; enum renk favori; C++ Formatı: addraddr_info; u_type dönüştürücü; renk favori;
intİÇİN VARSAYILAN DEĞER KULLANIMI • C++’a son zamanlarda yapılan bir değişiklik de, veri tipi belirtilmemiş bildirimlerde veri tipinin int olması varsayımına izin verilmemesidir. • C’de ve geleneksel C++’da varsayılan-int kuralının en yaygın kullanımını fonksiyonların döndürdükleri değer tiplerinin belirlenmesinde görüyoruz: func(int i) { return i*i; } Standart C++’da yukarıdaki fonksiyonun döndürdüğü değer tipinin int olacağı açıkça belirtilmelidir: intfunc(int i) { return i*i; } • Fakat, neredeyse bütün C++ derleyicileri varsayılan-int kuralını halen desteklemektedir.
BoolVERİ TİPİ • C++ bool adlı bir boolean veri tipini desteklemektedir. • booltipinde nesneler yalnızca C++’nın anahtar sözcükleri içinde yer alan true ve false değerlerini alabilirler. • Gerektiğindebooldeğerlerini tamsayılara ve tamsayıları booldeğerlerine dönüştüren otomatik dönüşümler uygulanmaktadır: sıfır olmayan değerler truedeğerine ve sıfırfalsedeğerine dönüştürülürken true1’e ve false0’a dönüştürülmektedir.
BoolVERİ TİPİ - örnek #include <iostream> usingnamespacestd; boolIsEqual(int x, int y) { return (x == y); } intmain() { cout << "Enter a value: "; int x; cin >> x; cout << "Enteranothervalue: "; int y; cin >> y; boolbEqual = IsEqual(x, y); if (bEqual) cout << x << " and " << y << " areequal“ << endl; else cout << x << " and " << y << " are not equal“ << endl; return 0; }
AŞIRI YÜKLENMİŞ FONKSİYONLAR • C++ aynı isimle birden fazla fonksiyon yaratılmasına izin verir: intkare(int x){ return x*x; } doublekare(double x){ return x*x; } • Değer atanmış parametreler bulunduran fonksiyonlarla aynı isimde farklı fonksiyonlar yaratmak bazen sorunlara yol açabilir: int f(int x); float f(int a, int b = 0); … int y = f(5);
AŞIRI YÜKLENMİŞ FONKSİYONLAR-örnek #include <iostream> usingnamespacestd; void f1(int a); void f1(int a, int b); intmain() { f1(10); f1(10,20); } void f1(int a) { cout << "f1 tek parametre\n"; } void f1(int a, int b) { cout << "f1 cift parametre\n"; }