Kaynak dosyayı yeniden koysanız sizden ricam. Döküman oldukça güzel
Kaynak dosyayı yeniden koysanız sizden ricam. Döküman oldukça güzel
Kaynak dosyamız microsoftun sunduğu drive space üzerinde bulunuyordu. Microsoft hiç beklenmedik şekilde zeet06 space se el koyduğundan, dinamik evrensel zeet06 klasörü kapanmıştır. Bu nedenle kaynak dosyayı yeniden oluşturmamız gerekiyor; oluşturulduğunda yeniden yayınlanacaktır.
delphiyi kullanabilen bu programı kullanbilirmi peki çok zorluk çekermi ben daha önce delpide program geliştiriyodum delphi çok zevkli ve eğlenceliydi bu programıda öğrenmek istiyorum çok zorluk çekermiyim
Medeniyet atmaksa iffet ve arı (utanmayı), Medenidir Afrika Yamyamları.
Cennet ucuz değil, Cehennem dahi luzumsuz değil.
Delphi, pascal tabanından borland firması tarafından geliştirildi ve bildiğimiz gibi pascal ın komutları ile C komutları aşırı bir benzerlik göstermektedir; C yi öğrenen bir kimseye birçok programlama dili yabancı gelmeyecektir.
Detaylı inceleyelim:
Ana konudan önce konu içerisinde sıkça geçecek kısaltmalar hakkında bilgi edinelim:
OWL , MFC VE VCL NEDİR?
Bu yazının temel amacı size framework'leri tanıtmak ve seçiminizi kolaylaştırmaktır. İlk olarak
framework'ün ne olduğu açıklayacağım daha sonrada sırasıyla
Borland 'ın OBJECT WINDOW LIBRARY (OWL) ' ı
Microsoft'un MICROSOFT FOUNDATION CLASS (MFC) 'yi ve son olarakta
Borland'ın VISUAL COMPONENT LIBRARY (VCL) 'i ne olduğunu açıklamaya
çalışalım:
Framework, windows programcılığını kolaylaştırmak amacıyla bir araya getirilmiş class'ların
tümüne verilen isimdir. Bu class'lar bildiğiniz ListBox, EditBox, ScrollBar...vb dir. İşte bunların hepsinin bir araya gelerek oluşturduğu yapıya framework denir. Framework'lerin genel amacı programcıyı gereksiz detaylardan kurtarmak ve program geliştirme süresini minimuma indirmektir. İyi bir framework OOP kurallarına sadık kalmalıdır. Ve kullanıcıyı gereksiz detaylardan uzak tutmalıdır.
Burada en popüler 3 framework hakkında kısa bilgiler edineceğiz.
OBJECT WINDOW LIBRARY (OWL)
Borland, framework yarışına lider olarak başladı. İlk olarak OWL 1.0'ı çıkarttı. Yanlız bu versiyon Borland compiler'larıyla birlikte satılmıyordu. Harici bir paketti. İlk OWL örnekleri Turbo
Pascal'da yazıldı.daha sonra C++'a çevrildi. OWL çok iyi bir framework yapısına sahipti ama çok eksiği vardı. Tabiki ilk framework OWL değildi ama pazar bulan ilk framework diyebiliriz. OWL 1 'den
sonra OWL 2'yi çıkarttılar OWL 2 tam anlamıyla bir başyapıttı. OWL 2'yi Borland C++ 4.0 paketiyle
birlikte pazara sürdüler. Borland daha sonra
OWL 2.5'i çıkarttı. OWL 2.5'te 2.0' daki bazı bug'lar düzeltilmiş ve yeni class'lar eklenmişti. Ama bir açıdan OWL 2.5 sanki eski sürümlerinden biraz farklı idi.Bu fark OLE (OBJECT LINKING and EMBEDDING) desteyidi. Ve son olarakta Borland, OWL 5'i çıkarttı. OWL 5 'in yeni class'ları sayesinde bize windows'un tüm özelliklerini kullanma şansı verdi. OWL, programcılığa yeni başlayanlar için zor bir
framework sayılabilir. Ama bir kere öğrendinmi çorap söküğü gibi gerisi gelir. Bildiğim kadarıyla Borland firması OWL 'yi artık geliştirmiyor. Yeni çıkan ürünleri VCL denilen başka bir framework kullanıyor. OWL'yi ürünlerinde kullanmak mümkün.Son duyduklarıma göre OWL 6'yı çıkartmışlar ama bu tamamen Borland'tan bağımsız bir çalışma. Eski olmasına rağmen bence yinede en iyi framework.
MICROSOFT FOUNDATION CLASS (MFC)
MFC, OWL 1 çıktıktan belli bir süre sonra oluşturuldu. MFC'nin ilk versiyonu Borland'tan farklı olarak Microsoft compiler'larıyla birlikte pazara sürüldü.(hatırlarsanız OWL 1 Borland compiler'larından bağımsız bir paket olarak satılıyordu.). Şunu söyliyebiliriz ki MFC, OWL'dan oldukça farklı bir yapıya sahip. MFC 'nin class'ları API (Application Programming Interface) fonksiyonlarına oldukça yakın. MFC' nin gücü 3 önemli özelliğinden gelir.
Birincisi "izafi olarak" öğrenmesi kolaydır. Eğer daha önce herhangi bir framework deneyimine sahip
değilseniz MFC veya OWL 'ı öğrenmek birbirine eşit sayılabilir. İzafi kelimesini kullanmamın sebebi ise eğer siz sağlam bir win32 C bilgisine sahip iseniz MFC'yi öğrenmek OWL'ı öğrenmekten çok daha kolay gelecektir.
İkincisi ise MFC class'larının çok ince bir yapıya sahip olmasıdır. İnce yapı demekle kastediğim şey kullanılan fonksiyonların API fonksiyonlarına oldukça yakın olmasıdır.Kimine göre bu bir güç kimine göre ise bu bir zayıflıktır. Zayıflıktır çünkü bir framework kullanıcıyı gereksiz detaylarla sıkmamalıdır. Ama dediğim gibi eğer siz bir win32 C programcısı iseniz MFC'yi kullanırken kendinizi evinizde hissedeceksiniz. Bazı programcılar kullandığı class'ların arkada neler yaptığını merak ederler. İşte MFC size bu arkada olanları bütün çıplaklığı ile sunuyor.
Son özelliği ise class'ları üreten firmanın adı yani MICROSOFT. Belkide MFC'nin bu kadar popüler olmasının sebebide budur. Ne zaman Microsoft yeni bir şey üretse bundan ilk etkilenecek olan MS VC++ 'tır. Borland ve diğer compiler üreticileri yeni özellikleri kendi class'larına ilave etmekte ne yazık ki biraz geç kalıyorlar. Yeni bir control çıktıktan sonra bir iki hafta içinde MFC class'ları o özellikleri kullanabiliyor fakat diğer compiler üreticileri bu özellikleri ancak 4-5 ay sonra class'larına ilave edebiliyorlar.
VISUAL COMPONENT LIBRARY (VCL)
VCL son zamanlarda adını iyice duyurmaya başladı. Peki nedir bu VCL ? Borland firması 1995 yılında Delphi denilen yeni bir ürünü tanıttı. Delphi'nin en büyük özelliği RAD (Rapid Application Development) yani hızlı bir biçimde program geliştirme idi. Form dizayn tekniği ilk olarak Visual Basic'te kullanılmaya başlandı. Delphi bu form dizayn tekniği ile component adı verdiği bir takım objeleri kullanarak programcılık dünyasında yeni bir çığır açtı. Temel olarak kullan dil aslında Pascal idi. Fakat Borland, Pascal'ı nesneye dayalı bir hale getirerek Object Pascal 'ı oluşturdu. Borland, Object Pascal'ı kullanarak Visual Component Library (VCL) dediği framework'ü yarattı. İşte bu Delphi'nin kullandığı framework aynı zamanda C++ Builder'ın kullandığı framework'tür. C++ Builder, Delphi'nin C versiyonudur.
VCL, component adı verilen objelerden oluşur. Bu objeleri form üzerine düşürerek istediğiniz control'ü projenize ilave etmiş olursunuz. Aynı işlem OWL ve MFC'de de yapılır fakat tek fark VCL 'de yaparken klavyenin bir tek tuşuna bile dokunmanıza gerek kalmamasıdır. İşte bu Visual Programming olarak bilinir.
VCL program geliştirme aşamasında oldukça avantaj sağlar. Bir MFC 'de veya OWL'de yapmak istediğiniz şeyi VCL'de anında yapabilirsiniz. VCL 'nin popüler olmasının sebeblerinden biride budur. Diğer bir sebebi ise VCL'i öğrenmenin çok kolay olmasıdır.
Peki bu kadar güzel ve hızlı program geliştirmek varken niye MFC veya OWL? Aslında bu sorunun cevabı oldukça basit. VCL programcıya basitlik sağlarken diğer yandan da performansı düşürür ve oluşturulan exe dosyasının büyüklüğünüde oldukça arttırır. Diğer bir sorunu ise program geliştirme sırasında sizinden dolayı kaynaklanmayan hatalar çıkabilir. Bu her framework'te olabilir. Fakat framework ne kadar işlevleri basitleştirirse o kadar bug çıkma olasılığıda artar. Sonuçta bütün framework'ler aynı işletim sistemi üzerinde çalışıyor ve sistem bütün framework'ler için aynı derecede zor. Eğer bir framework işi basitleştiriyorsa o framework bir çok işi
kendi yapıyor demektir. İşte bu da bazen istenmeyen bir durumdur.
Sonuç olarak;
İyi bir programcı yüksek performanslı ve az yer tutan programlar yazmalıdır. Şunu unutmamak gerekir ki ne kadar sistem seviyesine inilirse program o kadar hızlanır ve exe'si az yer tutar, gereksiz dll 'lerden kurutulur. Gerçekte olması gerekende budur.
C, C++, Delphi Hakkında Yorumlar :
C programlama dili, B ve BCPL denen 1970 öncesi AT&T Bell Labratuvarlarında geliştirilmiş dillerin etkin parçalarıyla daha geliştirilmiş yeni bir dildir. Dennis Ritchie tarafından Unix işletim sistemini geliştirmek amacıyla hazırlanmıştır.
C++ programlama dili ise C Programlama dilinin etkin parçalarının daha da geliştirilip genel iyileştirmeler ve "nesne yönelimli tasarım" eklenmiş halidir. Birçok yönden C' den daha iyi olmasına rağmen, performans açısında C++ kodları içerisinde C ve Assembly kullanılır. (Zira C++ kodu, C kodundan daha yavaş çalışmaktadır.)
C++ Builder IDE, C++' ı zamanına göre birçok derleyiciden daha iyi destekleyebilmiş, Delphi görünümlü ama işleri VCL ekseninde C++ diliyle çözen mükemmel bir araçtır. Aynı zamanda diğer genel C/C++ derleyicilerinin işini yapabilmektedir. Örneğin C++ Builder 6'nın c++ derleyicisi, aynı dönemde çıkmış Microsoft Visual C++' nin derleyicisinden daha yenilikçidir. (ANSI/ISO standartları)
Delphi IDE, yapısal programlamayı "object pascal" temelinde VCL kütüphanesiyle çözmüş gerçekten çok güçlü ve güzel bir ortamdır. Birçok masaüstü yazılımı Delphi ile geliştirilmiş halen daha geliştirilmektedir. Temeli pascal programlama diline ve turbo vision kütüphanesine dayanmaktadır.
Pascal programlama dili, akademik çevrelere yapısal programlamayı öğretmek üzere geliştirilmiş güçlü ve kullanımı c/c++ ya göre oldukça kolay bir dildir.
Assembly programlama dili, şimdilerde anladığımız türdeki programlama dili kavramının çok "ilkel" halidir diyebiliriz. Oldukça eskidir. "emirlerin sıralanması ve gerektiğinde dallanması" şeklinde programlar yazılır. Herhangi bir yapısal, fonksiyonel tasarıma sahip değildir ve genelde karmaşık kod yığınlarıyla boğuşmak isteyenler için ilaç gibidirBu dili kullanarak sıfırdan bir donanım sürücüsü yazmak zor olmasada, görsel tasarıma sahip bir Windows Vista programı yazmak ya da yazmaya çalışmak çıldırtıcı olabilir ve zaman kaybıdır aslında. (En azından elinizde C/C++ varken ya da C#, Java) Fakat Assembly ile makine diline en yakın, temiz kodu en hafif çalıştırılabilir programları geliştirebilirsiniz. Aynı zamanda performans iyileştirmeleri ve alt sistem çalışmaları için satıriçi "inline" olarak birçok günümüz programlama dilleri tarafından desteklenmektedir.
IDE Nedir?
Kısaca entegre geliştirme ortamıdır. Kod yazım editörü, derleyici, bağlayıcı ve iyi kodlanmış arabirimlere sahiptirler. Delphi ve C++ Builder'in tutulan tarafı yüzlerce görsel ve görsel olmayan hazır bileşeni(VCL) tek bir çatı (IDE) altında toplayabilmesidir.
DELPHI:
Delphi Programlama Dili
```Delphi programlama dili```, temeli Pascal programlama dili|Pascal dilidir. Özellikle nesne yönelimli programlama anlayışıyla yapılandırılmış Turbo Pascal dilinin görsel sürümü denilebilir. Nesne, sınıf, kalıtım, fonksiyon aşırıyükleme(overloading) gibi temel nyp tekniklerini ve daha fazlasını içeren ve C artı artı|c++ den aşağı kalmayan güçlü ve esnek bir Programlama dilleri|programlama dilidir.
Delphi Programlama Dili hakkında ansiklopedik bilgi
Delphi programlama dili, temeli Pascal dilidir. Özellikle nesne yönelimli programlama anlayışıyla yapılandırılmış Turbo Pascal dilinin görsel sürümü denilebilir. Nesne, sınıf, kalıtım, fonksiyon aşırıyükleme(overloading) gibi temel nyp tekniklerini ve daha fazlasını içeren ve c++ den aşağı kalmayan güçlü ve esnek bir programlama dilidir. Borland tarafından geliştirilmektedir. Win32 ve .NET platformları üzerinde yazılım geliştirmeye olanak sağlar. GNU/Linux platformu üzerinde geliştirme imkanı sağlayan Kylix isimli bir sürümü de bulunmaktadır. Delphi programlama dili nesne yönelimli bir dil olduğu için eklenen bütün nesnelerin (Formlar da dahil) kodlarını oluşturur. Bu kodları "Unit" ler içerisinde barındırır. Aşağıdaki programda programcının oluşturduğu program satırları italik olarak yazılmıştır. end; end. </pre>
Gelişim Süreci
Delphi EEP (Early Experience Program)
İlk hazırlık sürümü 1994 sonbaharında kısıtlı bir geliştirici çevresinde satılmıştır. Yanında verilen kaynak kodları gelecek sürüm olan Delphi 1 e göre önemli farkları olduğunu gösteriyor.
Delphi 1 (Kodadı: Delphi)
Delphi nin ilk sürümü 14 Şubat 1995 de satışa sunuldu. Sadece 16 Bit uygulamalar için kaynak kodları içeriyordu. Bileşenleri son derece kısıtlıydı.
Delphi 2 (Kodadı: Polaris)
Delphi 2, Mart 1996 da satışa sunuldu. 32 Bit uygulamaların geliştirilebildiği ilk sürümdür. Önceki sürüm olan Delphi 1 de birlikte veriliyordu. Delphi 2, 16 Bit ten 32 Bit e geçişte önemli ölçüte geliştirildi. Windows 95 stilinde modern bileşenler içeriyordu. Ayrıca çok daha fazla hafıza kullanımına izin veriyordu. Daha önce tüm veritipleri için 64 KByte ile sınırlıydı. Karakter dizileri (String) 255 karakter olabiliyordu. Delphi 2 ile 2 GByte a kadar kullanım imkanı
Delphi 3 (Kodadı: Ivory)
Delphi 3, Mayıs 1997 de satışa sunuldu. Önceki sürüme göre en önemli fark çok sayıda hatanın düzeltilmesi ve internet uygulamaları ile ilgili bileşenlerin eklenmesi olmuştur.
Delphi 4 (Kodadı: Allegro)
Delphi 4, Temmuz 1998 de satışa sunuldu. Dinamik dizi kullanımını sağladı.
Delphi 5 (Kodadı: Argus)
Delphi 5, Ağustos 1999 da satışa sunuldu. Bu sürüm ile ADO ile veritabanı erişimi başladı. Profesyonel sürümde ise bu özellik ADO Express olarak satın alınması gerekiyordu.
Delphi 6 (Kodadı: Iliad)
Delphi 6, Mayıs 2001 de satışa sunuldu. Delphi 6 ile birlikte gelen Modelmaker modelleme aracı ile UML-Modellerinden Delphi kodları oluşturulabiliyordu. Modelmaker nesne tabanlı sistemleri modelleyen standart bir dil olan Unified Modeling Language UML ile Diagram oluşturmayı sağlıyor. Böylece kod yazımı en aza indiriliyordu. Veritabanı erişimi için yeni bir arabirim olan dbExpress eklendi.
Delphi 7 (Kodadı: Aurora)
Delphi 7, LMLMMMMM í‚satışa sunuldu. Delphi 7 ile artık .NET uygulamaları da geliştirilebiliyordu. Modelleme aracı Modelmaker bu sürümde Delphi ile bütünleştirildi.
Delphi 8 (Kodadı: Octane)
Delphi 8, Aralık 2003 de satışa sunuldu. Bu sürüm ile sadece .NET uygulamaları geliştirilebiliyordu. ...
Delphi 2005 (Kodadı: Diamondback) 12 Ekim 2004 tarihinde satışa sunuldu. .NET 1.1 ve Win32 desteği ile beraber geldi. Delphi 8'in ardından, Delphi kullanıcılarının karşısına gerçekten güçlü bir IDE çıkarıldı. ECO II ile model tabanlı progrmlamaya yeni bir soluk geldi. Özellikle Refactoring desteği, Delphi'nin 8. sürümünde kaybettiği imajını geri kazandırdı.
1. Delphi 2006 (Kodadı: Dexter)
10 Ekim 2005 çıkış tarihidir. Her ne kadar Delphi programcıları .NET 2.0 desteğini bekleseler de, bu sürümün amacı .NET ve Win32 alanında iyileştirmelere gidilmesi idi. Özellikle Win32 kütüphanesindeki bir çok temel rutinde, FastCode kütüphanesi kullanıldı. Yine bu sürümde de .NET 1.1 desteği veren Delphi, bizleri ECO III ile tanıştırdı. Ayrıca Win32 ve .NET ortamları için Together ve Caliber RM destekleri eklendi. Pattern Organizer, Code Templates gibi özelliklerin yanında Refactoring geliştirildi. Ayrıca bu sürümde C# Builder, C++ Builder bütünleşik olarak geldi.
1. Delphi 2007 for Vista (Kodadı: Spacely)
19 Mart 2007 tarihinde çıktı. Bu sürümde esas amaç Windows Vista ve Ajax'tır. Ve bu sürüm sadece Win32 için çıkmıştır. .NET sürümü bulunmamaktadır.
1. Delphi for PHP (Kodadı: Astro)
27 Mart 2007 tarihinde piyasaya sunuldu. Qadram şirketinin uzun süreden beri üzerinde uğraştığı QStudio, CodeGear(Borland'ın alt şirketi) tarafından satın alındı ve ismi Delphi for PHP olarak piyasaya çıktı. Özellikle VCL kütüphanesinin PHP versiyonu ile birlikte Qooxdoo ve Ajax destekleri ile ön plana çıkıyor.
1. Delphi 2008 (Kodadı:Tiburón)
2008'nin ortasında çıkması planlanan 2008 sürümünün en önemli yeniliği VCL in Unicode destekli hale gelecek olmasıdır. Bunun yanında Win32 için Generics desteğinin gelecek olması diğer bir yeni özellik olacak.
1. Delphi 2009 (Kodadı:Commodore)
Delphi 2009 Commodore sürümünün en önemli yeniliği VCL in 64Bit destekli hale getirilmiş olmasıdır.
Delphi 2009 un
Bu sürümlerin ilerisinde ise aşağıdaki özelliklerin dile getirilmesi planlanmaktadır.İŞLETİM SİSTEMLERİNİN DİZAYNINDA HANGİ DİLLER KULLANILDI:
- Unicode karakter seti ile kod yazımı.
- multi-core/multi-threaded development
- Development for PDAs and the Compact Framework
- Language enhancements and standards conformance
- Rich Internet Application (RIA) development
- Cross-compilation to other operating systems
- Continuously improved and frequently updated documentation
MacOS, Unix, Minix, BeOS, *BSD, GNU/Linux, Microsoft Windows işletim sistemleri ve daha birçok işletim sistemi çekirdekleri(kernel), kabukları(shell) ve işletim sistemi üzerinde çalışan birçok uygulama çoğunlukla Assembly, C, C++ dilleriyle geliştirildi.(%99)
Kabuk üzerinde çalışan bir takım sistem uygulamalarının Perl gibi betik(yorumlanan) dilleriyle de yazıldığı görülmüştür. Örneğin linux, bsd gibi unix türevlerinde ve unix in kendisinde script dilleri(bash, tcshshell, perl-active perl, python) yoğun olarak kullanılır. Tabii bunlar genelde kernel-donanım işlemleri için kullanılmaz.
Daha güçlü diye bir kriter mevcut değil. Dünyadaki birçok sistem gün geçtikçe biraz daha iyileşiyor. Bir zamanlar gnu/linux sistemleri herkese hitap etmezken bugün ubuntu işletim sistemi türündeki linux dağıtımları sayesinde herkesin kullanımına hazır hale geldi. Hatta bugün Ubuntu dağıtımı, vista ile kullanıcı arabirimi görselliği ve daha birçok katmanda yarışabilmekte.
İyi derecede C ve Assembly dillerini hakimsen, donanım-yazılım arasındaki bağlardan haberdar biriysen kesinlikle kendi işletim sistemini geliştirebilirsin. Fakat tekerleği tekrar tekrar icad etmene gerek yok.
GNU/Linux' un çekirdeği kernel.org ortamında indirilebilir durumdadır. Ve daha birçok hobi işletim sistemi projesinin kaynak kodlarını internetten bulunabilir.
Programcıların, Program yazmada en fazla kullandıkları programın son sürümünü sunuyoruz:
En büyük özellikleri arasında VCL kütüphanesine dahil edilen tam Unicode desteği sayesinde arapça, çince, rusça gibi latin olmayan alfabelerle çalışan uygulamalar geliştirebilir, tam Vista uyumunun keyfini sürerken Office 2007'de hayran kaldığımız ribbon barı uygulamalarımıza eklemenin tadına varabilirsiniz.
Crack Yöntemi:
keygen ile şifre üretip kurulum sırasında istenen şifreyi girin
kurulum bitince
bds.exe kurulum klasörüne kopyalayın
interbase uygulaması cracki: ibserver.exe
Crack ile ilgili dosyalar Magnitude klasöründedir.
Download
https://downloads.embarcadero.com/free/delphi
Crack :
HAFE-DE3796-MPR5SG-H4CN
http://essenbi.googlepages.com/Delph...ller.v1.54.rar
bilgiler için teşekür ederiz inşallah öğrenebilirim
Medeniyet atmaksa iffet ve arı (utanmayı), Medenidir Afrika Yamyamları.
Cennet ucuz değil, Cehennem dahi luzumsuz değil.
C++ İle Programlamaya Giriş
İlk programımız!
// ilk1.cpp
// Ekrana "Bu benim ilk programım" yazdırıyoruz
#include <iostream.h>
int main()
{
cout << "Bu benim ilk programım";
return 0;
}
Şimdi Yazdığımız programı inceleyelim:
"//" işaretini açıklama satırlarında kullanıyoruz. C++ derleyicisi bu notasyonla başlayan satırı okumaz. Bununla birlikte daha uzun cümlelerimiz olursa bunları da " /* */ " notasyonunun içinde yazıcağız. Bu özellik de C den bize kalma. Demiştik zaten C `nin tüm özelliklerini C++ içerir. Fakat biz genelde " // " yi kullanacağız.
#include <iostream.h> : Bu bizim C++ da bulunan kütüphane dosyamızı çağırmaya yarıyor. Ben size şöyle tarif edeyim. iostream.h kütüphanesindeki hazır olan " cout " fonksiyonunu çağırıyor. Yani buda bizim fazla kod yazmamıza engel oluyor. .h ile biten dosyalar kütüphane dosyalarıdır. Bunu şuna da benzetebiliriz. Farz edelim ki elimizde bir alet çantası var içinden tornavidayı çağırdığımızda vida sıkacağızdır. Bu da ona benziyor. C++ da ki hazır kütüphanelerde bir çok hazır fonksiyonlar vardır. İlerde Bu hazır fonksiyonlar işimizi görmemeye başlayınca kendi kütüphanemizi yapmaya başlayacağız. Tabi bu seviyeye geldiğimizde olayı hemen hemen kavramış olacağız, tabi neden olmasın öyle değil mi?
Daha sonraki satır her C++ programında mutlaka bulunması gereken bir satırdır. Her C++ programında main() fonksiyonu olmak zorundadır; bu fonksiyonumuzun önünde ise o fonksiyonun dönderdiği değişkenin veri tipi olmalıdır. Tabi ki C++ fonksiyonlar ve onların dönderdikleri değerler konusunu da ileride işleyeceğiz.
Bir sonraki satırda ise; C++ fonksiyonlar ve kod blokları " { } " parantezleri arasında bulunmalıdır. main de bir fonksiyon ise onun içindeki kodlar doğal olarak { } parantezleri arasındadır.
Program derlenip çalıştırıldığında ise ( Turbo C++ 3.1 kullanıyorsanız ctrl+f9 kısa yoluyla programı çalıştırabilirsiniz (Run) ) karşımıza "Bu benim ilk programım" yazısı çıkacaktır. İşte bu yazıyı ekrana veren komut da iostream.h kütüphanesindeki cout fonksiyonudur.
Önemli bir nokta ise C++ dilinde her satır ifadenin sonuna " ; " koymak zorundayız. Bundan farklı olarak #include satırlarının ve bir kaç farklı satırın arkasına " ; " gelmez. Bunları ileride göreceğiz.
Return 0 : programımızın (aynı zamanda main fonksiyonumuzun) çıkış noktasıdır. Eğer return ile 0 değeri dönderirsek programımızın güvenle çıktığını işletim sistemine bildirmiş oluruz. Bu sayede güvenle programımızın çalıştığını göreceğiz.
Şimdi size bir örnek daha vereceğim bununla da aynı çıktıyı elde edeceğiz. Arasındaki farkları eminim basit olarak sizlerde göreceksinizdir.
// ilk2.cpp
// Ekrana "Bu benim ilk programım" yazdırıyoruz
#include <stdio.h>
main()
{
printf("Selam bu benim ilk programım.\n");
return 0;
}
Evet şimdi burada çok fark varmış gibi gözüküyor aslında ama öyle değil. Sadece kütüphanemiz stdio.h oldu ve ekrana yazdır fonksiyonumuzda printf oldu. Bu özellik C den kalma. Bunlar diğer program ile aynı işlevi görüyor. Buradaki fark " \n " notasyonu. Bu notasyon bir sonraki satıra geçmek için kullanılır. Bu notasyonlara Escape dizileri denir. Tablo olarak bunları size veriyorum. Son yazdığımız ilk2.cpp de yerlerine koyarsanız çalışacaktır.
Şu an bunları bilmeniz yeterli.
Değişkenler
Şimdi bize yine çok lazım olacak bir özellik de değişken tanımlamak ve atama yapmaktır. Bunu bir örnek üzerinde anlatmak istiyorum. Örneğimiz;
// degisken.cpp
// Burda değişken tanımlamayı göreceğiz.
// Aynı zamanda verilen bir sayıyı kendisi ile carpma 2.2=4 gibi
#include <iostream.h>
#include <stdio.h> // kütüphane dosyamız
main()
{
int i; // Değişken tanımlama
cout << "Bir sayı giriniz: ";
cin >> i;
i=i*i;
cout << "sonuc: " << i ;
return 0;
}
Burada bundan önce yaptığımız programlardan farklı olarak int i kullandık, yani değişken tanımladık.
Değişken Nasıl Tanımlanır?
Değişkenleri tanımlamak için aşağıdaki şema kullanılır.
[Veri Tipi] [Değişken Adı];
Örneğin
int sayi;
Şimdi degisken.cpp örneğindeki int i; kısmını anlamışsınızdır. Burada değişkenlere değinmek istiyorum. Biz yukarda İçinde sayı tutan bir değişkeni tanımladık. Benzer olarak aşağıdaki tanımlamalar da vardır.
char c;
int i;
float f;
double d;
unsigned int ui;
Burada [Veri Tipi] [Değişken Adı]; bu kalıba göre tanımlama yaptığımız için önce Veri Tiplerini inceleyelim
Veri Tipleri
1) İnt tip.
Integer = Tamsayı
Tamsayıları içerir. Bellekte 2 Byte tutar. DOS'ta ve Win3.1'de 16 bit uzunlugunda ama Windows9x, WinNT, Win200 ve WinXP 32 bit uzunluğundadır.
Değer aralıkları Short ve long için değişir.
Örnek: 5, -20, 1 gibi.
2) Sort tip.
Tam sayıları içerir. 16 bit uzunluğundadır.
signed: -32768 ile +32767 arasinda değer alır, unsigned: 0 ile 65535 arasinda değer alır.
3) Long tip.
Tam sayılar içerir. 32 bit uzunluğundadır.
signed: -2147483648 ile +2177483647 arasinda değer alır, unsigned: 0 ile 65535 arasinda değer alır.
4) Gerçel Tipler (Float, Double, Long double)
Gerçel sayıları içerirler.
float : Bellekte 4 Byte yer tutar. 3.4E-38 ile 3.4E+38 aralığında değer alır. Hassasiyet 7-8 basamaktır.
double : Bellekte 8 Byte ter tutar. 1.7E-308 ile 1.7E308 aralığında değer alır. Hassasiyet 15-16 basamaktır.
long double : doublenin tipinin daha genişidir.1.2E-4932 ile 1.2E-4932 aralığında değer alır. Hassasiyet 19-20 basamak.
5) Char Tip
Char : Karakter
Alfanumerik karakterleri içerir. Ve ya 8 bit uzunluğunda tamsayı.
signed: -128 ile 127 arasinda değer alır, unsigned: 0 ile 255 arasında değer alır.
Örneğin: ' 0,1,2,3,4,5,6,7,... ' , ' *,-,+,... ' , 'a,b,c,....,A,B,C,D,,,,, '
6) Bool tip.
true(dogru) = 1 veya false(yanlis) = 0 değerini alır. Eski derleyiciler bu türü desteklemeyebilir. Yeni ANSI C++ standardında eklenmiştir. Bu soyut matematik gördüyseniz. "p V q" ya benzer [IMG]http://www.************/images/smilies/smile.gif[/IMG] ( matematikçiyiz, konuşturalım azıcık). Değer aralığı ise ya 1 dir (doğru) yada 0 dır (yanlış).
7) Enum tip.
enum sıralanmış değerleri tutar. Short int ile aynı değeri taşır.
Başta Fazla Detaya inip sizi bunaltmak istemiyorum. Çünkü C++ dili başlarda karmaşık gelen bir dildir. Bu da zaten kendisini yüksek seviyeli bir dil yapıyor [IMG]http://www.************/images/smilies/smile.gif[/IMG]. Ben size Bu dilin temel özelliklerini anlatarak basit programlar yapmayı göstereceğim.
Bu temel bilgileri aldıktan sonra programlamaya geçebiliriz. Derleyici Olarak ben Turbo C++ 3.1 i tavsiye ederim. Şu an bununla başlar iseniz işiniz daha kolay olacaktır (bence). İlerde Borland a geçeceğiz.
Değişken tanımlama konusunda bir konuya daha değinmek istiyorum. Değişkenlere değer atama ve aynı anda bir çok değişken tanımlamamız C++ da mümkündür.
char c = 'c';
int i = 5;
Daha sonradan değer atama:
char c;
int i;
c = 'c ';
i = 5;
Bir de aynı anda bir çok değişken tanımlayalım.
Örneğin:
int x , y , z;
x = y = z = 5;
x,y,z' nın değeri 5 oldu
Bir sonraki derste ise değişkenlerle birlikte bir de Operatörleri ele alacağız.
Operatörler I
Operatör ve Operand nedir?
Bunu bir örnek üzerinde anlatmak istiyorum. Örneğin; x + y 'de x ve y operand + ise operatördür. Bu bir aritmetiksel operatördür. Matematikte işlemler operatörler ve operandlar ile anlatılır.
Operatörleri öncelikle türlerine göre ayıralım:
1) Aritmetiksel operatörler + , - , * , / , % , ++ , --
2) Karşılaştırma operatörleri < , > , <=, >= , ==, !=
3) Eşitleme operatörleri = , += , -=, *= , /= , %= , <=, >>=, &=, != , ^=
4) Mantıksal Operatörler ! , || , &&
5) Bit bazında işlem yapan operatörler & , ! , ^ , ~ ,
Aritmetiksel (Matematiksel) Operatörler:
Matematiksel ifadeleri günlük hayattaki biçimde bilgisayarda yazamadığımız için belli kurallara uymamız gerekir. Bu kısım önemli olduğu için biraz geniş yer vereceğim. Kullandığımız matematiksel işlemler ve anlamları şöyledir:
Bu operatörle verilen iki veya daha fazla operand toplanabilir. Yazılış şekli Aşağıdaki gibidir.
değişken1 + değişken2
Eğer bu iki değişkeni Sonuç gibi başka bir değişkene atarsak eşitleme operatörüyle aşağıdaki gibi yaparız.
Sonuç = değişken1 + değişken2
Buna bir örnek verelim.
// toplama.cpp
//Vize ve final notlarinindan geçme notunu hesaplama
#include <iostream.h>
#include <math.h>
main()
{
int vize, final, ort;
vize = 10;
final = 80;
ort = vize * 0.4 + final * 0.6;
cout<< "Geçme notunuz: " << ort;
}
Burada çarpma operatörünü de kullandık sanırım, artık diğerlerinin de ne olduğunu kavramış oldunuz. Bir örnekte işi ucuza getirdim [IMG]http://www.************/images/smilies/smile.gif[/IMG]. Fakat bir artma ve bir azalmaya örnek verelim. Bu bana çok lazım olmuştu.
Burada dikkat etmemiz gereken olay " ++ " operatörünü değişkenin önüne yazmanız gerektiğidir. Bu sayede değişken bir arttırılarak işleme konur. Arkasına konursa değişken işlenir, sonra bir arttırılır. " -- " operatöründe ise aynı şekilde de bir azaltma yapılır.
// carpim.cpp
// x i bir arttırıp y yi bir azaltıp çarptık.
#include <iostream.h>
main()
{
int x = 5;
int y = 10;
cout << "x = " <<x << endl;
cout << "y = " << y << endl;
cout <<"++x * --y = " << ++x * --y ;
}
İşte bir fark daha yakaladık bunu da hemen örnek üzerinde anlatalım. Sanırım buraya kadar geldiğimiz yerlerde int i , çarpma işlemini, bir arttırıp azaltmayı gördük, ama diyeceksiniz ki " endl " ne oluyor? Hemen açıklayayım; Satır sonunu belirterek yeni satıra geçmemizi sağlar, bir nevi " \n " Escape operatörü gibi bir işleve sahiptir.
Operatörler II
Karşılaştırma Operatörleri:
Bunların teker teker ne olduğunu söylemeye gerek yok. İfadeler gayet basittir. Burada dikkat etmemiz gereken önemli bir şey var: " >=, <=, ==, !=" notasyonlarını kullanırken iki notasyon arasında boşluk bırakmamalıyız. Buna dikkat edelim!
Eşitleme ( Atama) Operatörleri:
Bunlarıda liste halinda verelim.
Operatörler III
Mantıksal Operatörler (Lojik Operatör Sembolleri) :
Burası biraz Soyut Matematik, biraz değinmek istiyorum. Yukarıda gördüğümüz mantıksal operatörler, Doğru (1) yada Yanlış (0) sonucunu argümanlara bakarak üretirler. Mantıksal Değil (!), değeri tersine çevirir. Ve ( && ) operatörü ise yalnızca her iki ifadede Doğru (1) ise sonuç Doğru (1) ` dur; diğer durumlarda Yanlış (0)` dır. Veya` da ( || ) ise yalnızca iki ifadenin Yanlış (0) durumunda sonuç Yanlış (0) olur diğer durumlarda Doğru (1)`dur.
Bit bazında İşlem Yapan Operatörler :
Bu kısımda Soyut Matematiğin daha da ayrıntılarına girilmesi gerekiyor. Ben size kısaca bunu anlatayım. Çok karışıklık da sizi yoracaktır. Örnekleri yaparken yine üstünde dururuz.
Bit bazında işlem yapan operatörler şunlardır: AND (Ve ( & ) , OR (Veya ( ~ )), XOR ( ^ ).
And (&) operatörü; bitleri karşılaştırır. Eğer her ikisi de Doğru (1) ise sonuç Doğru (1), aksi halde Yanlış (0)`dır.
OR (~) operatörü; iki biti karşılaştırır ve eğer ikisi de Doğru (1) ise yada birisi Doğru (1) ise sonucu Doğru (1) yapar. OR işlemi belirli bir bit i Doğru (1) e çekmek için kullanılabilir.
XOR (^) operatörü; bit düzeyinde EXCLUSIVE OR (dışında tutan veya) (Türkçe'sini çevirince saçma oluyor) işlemi yalnızca karşılaştırılan bitler bir birinden farklı ise Doğru (1) üretir, aksi halde Yanlış (0) üretir.
! işareti ise her bir bit i ters çevirir.
Not: Bunlar yeni başlayanlar için yorucu olabilir. Son iki bölümün fazla üstünde durmayın
< Bir de bize C++ile gelmiş olan operatörlerden bahsetmek istiyorum. Bunlar;
" :: " Erim çözünürlüğü (Scope resolution operatörü).
" * " Dolaylı adresleme (Pointerlerle kullanacağız).
" & " Adres operatörü (Pointerlerle kullanacağız).
" new " Dinamik bellek ayırma .
" sizeof " Nesne Boyutu.
OPERATÖRLERİN DETAYLARI
- Sayı tabanları
- Bit Bazında ( Bitwise ) Operatörler
- AND ( & ) Operatörü
- OR ( | ) Operatörü
- NOT ( ~ ) Operatörü
- XOR ( ^ ) Operatörü
- Kaydırma ( Shift ) Operatörleri
- Operatör Öncelikleri
Sayı Tabanları
Bilgisayar programlamayla, matematik arasında çok güçlü bir ilişki vardır. Geçmişe bakarsanız, bilgisayar alanında önemli adımların, hep matematik kökenli insanlar tarafından atıldığını görürsünüz. Bir bilgisayar programcısı için, matematikten uzak durmak düşünülemez.
Bugün ki dersimizde, biraz matematik içersine gireceğiz ve sayı sistemleriyle, Boole Cebiri (Boolean Algebra) konularını ele alacağız.
Genel kabul görmüş sayı sistemleri vardır ve içlerinde en yaygını, hepimizin gündelik hayatta kullandığı 10'luk sayı sistemidir. Yazması, okunması ve işlem yapması son derece kolay olduğundan bunu daha çocuk yaşta öğrenir ve bu şekilde sürdürürüz. Ancak bilgisayarlar bizim gibi işlem yapabilme yetisine sahip değildir. Onlar için iki ihtimal vardır. Bir şey ya 1'dir ya da 0. Bunu ikilik sayı sistemi olarak adlandırırız. Yani bizim yazdığımız bütün sayılar, bütün harfler ve aklınıza gelen-gelmeyen bütün işaretler, bilgisayar için 0 ve 1'in kombinasyonlarından ibarettir. İşte bu yüzden bizlerin, ikilik sayı sistemine hakim olması gerekir.
Sayı sistemlerini genel olarak aşağıdaki gibi ifade edebiliriz:
Burada, N sayı tabanına göstermektedir. k sayının hangi hanesinde olduğumuzu ifade ederken, dk ise, ilgili sayıdaki rakamı temsil eder. Şimdi basit bir örnek yapalım ve ikilik tabandaki 10011 sayısının, 10 tabanındaki eş değerini bulalım:
( d4d3d2d1d0 )2 = ( d0 . 20 ) + ( d1 . 21 ) + ( d2 . 22 ) + ( d3 . 23 ) + ( d4 . 24 )
( 10011 )2 = ( 1 . 20 ) + ( 1 . 21 ) + ( 0 . 22 ) + ( 0 . 23 ) + ( 1 . 24 ) = 19
ikilik sayı sistemi dışında, 16'lık (Hexadecimal) sayı sistemi de oldukça önemli bir başka tabandır. 16'lık sayı sisteminde, rakamları ifade etmek için 16 adet sembole gereksinim duyarız. Bu yüzden 0 ile 9 arasında olan 10 rakamı kullandıktan sonra, A, B, C, D, E ve F harflerini de rakam olarak değerlendiririz.
Decimal : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hexadecimal : 0 1 2 3 4 5 6 7 8 9 A B C D E F
Hexadecimal/16'lık sayı tabanıyla ilgili aşağıdaki örneklere göz atalım:
( 3FC )16 = ( 3 . 162 ) + ( F . 161 ) + ( C . 160 ) = 768 + 240 + 12 = 1020
( 1FA9 )16 = ( 1 . 163 ) + ( F . 162 ) + ( A . 161 ) + ( 9 . 160 ) = 4096 + 3840 + 160 + 9 = 8105
( 75 )16 = ( 7 . 161 ) + ( 7 . 160 ) = 112 + 5 = 117
16'lık sayı sisteminin diğer bir ismi Hexadecimal olduğundan, bazı yerlerde, bunu ifade etmek için 16 yerine 'H' harfi de kullanılabilir:
( BA3 )16 = ( BA3 )H ; ( A1E )16 = ( A1E )H gibi...
Tabanlar arasında dönüştürme işlemi, üzerinde duracağımız bir başka konudur. Elinizde 16'lık sayı sisteminde bir sayı varsa ve bunu 2'lik sayı sistemiyle yazmak isterseniz önce 10'luk sayı sistemine çevirip daha sonra 2'lik sayı sistemine dönüştürebilirsiniz. Ancak 16'lık ve 2'lik sayı sistemlerini çok daha kolay birbirine dönüştürmeniz mümkündür. Aşağıdaki tabloda 16'lık sayı sistemindeki rakamlar ve bunun 2'lik sayı sistemindeki karşılığı verilmiştir:
Hexadecimal : 0 1 2 3 4 5 6 7 8 9 A B C D E F
Binary ( İkilik ) : 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Bu durumu bir örnekle şöyle gösterebiliriz:
( A3F1 )H : A 3 F 1
: 1010 0011 1111 0001
16'lık tabandaki her rakamın, 2'lik tabandaki karşılığını koyduğumuzda yukardaki eşitliği elde ediyoruz ve buna göre ( A3F1 ) = ( 1010 0011 1111 0001 )2 eşitliğini kurabiliyoruz. (2'lik tabandaki sayıya ait boşluklar, sayının daha rahat okunması için bırakılmıştır.) Bu tarz dönüşümler, 2 ve 2'nin katında olan sayı tabanlarında rahatlıkla yapılabilir.
Hatırlarsanız, değişken tiplerinde, işaretli ve işaretsiz değişken tanımlamalarından bahsetmiştik. Şimdi olayın biraz daha derinine inelim. Bir char, 1 byte alan kaplar ve 1 byte, 8 bit'ten oluşur. Aşağıdaki kutuların her birini bir bit ve kutuların oluşturduğu bütünü bir byte olarak düşünün:
a7 a6 a5 a4 a3 a2 a1 a0
Yukardaki kutuların toplamı olan bir byte, char değişkeninin kapladığı alanı temsil etmektedir. Pozitif sayıları ifade etmeyi zaten öğrenmiştik. Sayının karşılığını, 2'lik tabanda yazarak, gerekli sonuca ulaşırız. Ancak sayımız Negatif değerliyse, işler biraz farklılaşır. Burada devreye işaret biti (sign bit) devreye girer. Yukardaki şekilde, diğer kutulardan farklı renkte olan a7 işaret bitidir. Özetle, a7 0 ise, sayı pozitiftir. Eğer a7 1 ise, sayı negatiftir.
İkilik tabandaki işaretli bir sayının, 10'luk tabandaki karşılığını şu şekilde bulabiliriz:
( a7a6a5a4a3a2a1a0 )2 = ( a7 . -27 ) + ( a6 . 26 ) + ... + ( a1 . 21 ) + ( a0 . 20 )
İkilik tabanda yazılmış ( 10000011 )2 sayısı, işaretsiz olarak düşünülürse, 131'e eşittir. Ancak işaretli bir sayı olduğu düşünülürse, karşılığı, -125 olacaktır. Konunun pekişmesi açısından aşağıdaki örneklere göz atabilirsiniz:
* ( 1011 1011 )2 = -69 (Sayı işaretliyse)
( 1011 1011 )2 = 187 (Sayı işaretsizse)
* ( 1100 1101 )2 = -51 (Sayı işaretliyse)
( 1100 1101 )2 = 205 (Sayı işaretsizse)
* ( 0110 1101 )2 = 109 (Sayı işaretliyse)
( 0110 1101 )2 = 109 (Sayı işaretsizse)
Negatif bir sayının 2'lik tabandaki karşılığını bulmak için, önce (i) sayıyı pozitif olarak ikilik tabanda yazarız. Daha sonra, (ii) ikilik tabanda yazılmış sayının 1 yazan rakamları 0, 0 yazan rakamları 1'e çevrilir. Son olarak (iii) çıkan sayıya, 1 eklenir. Bu size istediğiniz sayının ikilik tabanındaki eşini verecektir. Şimdi bir uygulama yapalım ve -7 sayını ikilik tabana çevirmeye çalışalım:
i ) -7 ==> ( 7 )10 = ( 0000 0111 )2
ii ) ( 0000 0111 ) ==> ( 1111 1000 )
iii ) ( 1111 1000 ) + 1 = ( 1111 1001 ) ==> ( -7 )10 = ( 1111 1001 )2
Bit Bazında ( Bitwise ) Operatörler
Bit bazında operatörlerin, İngilizce'deki karşılığı Bitwise Operators ( yani Bit bit Operatörler ) olarak geçmektedir. Bit bazında operatörler, ikilik sayı tabanında yapabileceğimiz işlemleri temsil eder. Kullanılan operatörleri aşağıda inceleyeceğiz.
AND &( hepsi 1 olmalı)
Karşılaştırma Sonuç
p q p&q
0 0 0
0 1 0
1 0 0
1 1 1
x 0 0
x 1 x
OR |en az 1 olmalı
Karşılaştırma Sonuç
p q p|q
0 0 0
0 1 1
1 0 1
1 11
x 0 x
x 1 1
NOT~ (ters çevirici)
Karşılaştırma Sonuç
p ~p
1 0
0 1
XOR 2si aynı olmamalı
Karşılaştırma Sonuç
p q p^q
0 0 0
0 1 1
1 0 1
1 1 0
x 0 x
x 1 ~x
OPERATÖRLER
AND ( & ) Operatörü
AND operatörü, kendisine verilen iki değişkenin bütün bitleri 1'e eşit olduğu takdirde, geriye 1 döndürür. Aksi halde -yani en ufak bir fark varsa- 0 değeri dönmektedir.
Karşılaştırmanın tüm sonucu 1 olmalıdır. Yoksa 0 rı yersin.
p q p&q
0 0 0
0 1 0
1 0 0
1 1 1
x 0 0
x 1 x
Şimdi, AND ( & ) operatörünü 25 ve 14 sayılarını karşılaştırmak için kullanalım:
25 ==> ( 0001 1001 )2
14 ==> ( 0000 1110 )2
&
----------------------------
8 ==> ( 0000 1000)2
OR ( | ) Operatörü
İki değişkenden herhangi biri 1 içeriyorsa, geriye 1 döner. Eğer her ikisi de 0 içeriyorsa, geriye 0 dönmektedir.
Karşılaştırma Sonuç
p q p|q
0 0 0
0 1 1
1 0 1
1 1 1
x 0 x
x 1 1
P ile q karşılaştı ve karşılaştırmadan her hangi biri 1 olursa sonuç 1 olmazsa 0 döndü.
Daha önce kullandığımız 25 ve 14 sayıları üzerinde OR ( | ) işlemi kullanalım:
25 ==> ( 0001 1001 )2
14 ==> ( 0000 1110 )2
|
----------------------------
31 ==> ( 0001 1111)2
ÖNEMLİ NOT: Bit bazında kullanılan, AND( & ) ve OR ( | ) operatörleri, koşullu ifadelerde kullanılan, AND( && ) ve OR ( || ) ifadelerinden farklıdır. Şayet, & veya | bir koşullu ifade gibi kullanmaya kalkarsanız, işlem yine yapılacaktır. Ancak bunu yapmanız tavsiye edilmez. İlerki konularımızda neden uygun olmadığı, short-circuit ile ilgili bilgi verilirken açıklanacaktır.
NOT ( ~ ) Operatörü
NOT ( ~ ) Operatörü, kendisine verilen sayıya ait bit'leri tam tersine çevirir. Yani 0 gördüğü yeri 1; 1 gördüğü yeri 0 yapar.
p ~p
0 1
1 0
25 ==> ( 0001 1001 )2
~
----------------------------
230 ==> ( 1110 0110 )2
XOR ( ^ ) Operatörü
XOR ( Exclusive OR ) Operatörü,
sadece ve sadece karşılaştırma yapılan bitlerden biri, 1 değerine sahipse, geriye 1 döndürür. Eğer karşılaştırma yapılan bit'lerden her ikisi de 0 veya 1'se, o zaman sonuç 0 olarak çıkar.
Yani her ikisi de aynıysa sonuc kesinlikle 0’dir.
Farklıysa sonuç kesinlikle 1 dir.
p q p^q
0 0 0
0 1 1
1 0 1
1 1 0
x 0 x
x 1 ~x
25 ==> ( 0001 1001 )2
14 ==> ( 0000 1110 )2
^
----------------------------
23 ==> ( 0001 0111 )2
Kaydırma ( Shift ) Operatörleri
Kaydırma operatörleri, özellikle Assembly ile uğraşanlara tanıdık gelecektir. Bunları kullanarak son derece hızlı çarpma ve bölme yapılabilir. C'deyse benzer amaçlarla kullanmanız elbette mümkündür. İki çeşit kaydırma operatörü vardır:
i) Sola Kaydırma - Shift Left ( << )
ii) Sağa Kaydırma - Shift Right ( >> )
Her iki durumda da genel kullanım şekli aşağıdaki gibidir:
[ Tam Sayı ][ Operatör ][ Kaydırma Adım Sayısı ]
Aşağıdaki örnek, sola kaydırma operatörü kullanılarak yapılan bir işlemi göstermektedir. x değişkeni, 10 tabanında 22 sayısını tutmaktadır. 2 adım sola kaydırılması sonucu, sayı 88 olmuş ve y'ye atanmıştır.
x = ( 0001 0110 )2 ==> 22
y = x << 2
y = ( 0101 1000 )2 ==> 88
Operatör Öncelikleri
Hatırlarsanız, aritmetik işlemlerde önceliklerin olduğunu ve örneğin çarpmanın, toplamadan daha önce yapılacağını anlatmıştık. Benzer bir durum, operatörler içinde geçerlidir. Altta bulunan tabloda, hangi operatörün daha önce işleme alındığını bulabilirsiniz:
OPERATÖR ÖNCELİK SIRASI
DÜŞÜK | ^ & << >> + - * / % ! ~ - ++ -- ( ) YÜKSEK
Aşağıda bulunan tablo, ilişkisel ve mantıksal operatörlerde ki öncelik sırasını göstermektedir:
İLİŞKİSEL ve MANTIKSAL OPERATÖR ÖNCELİK SIRASI
DÜŞÜK||&& == != > >= < <= ! YÜKSEK
Yukardaki tablolarda, aynı hücrede olan operatörlerin işlem öncelikleri aynıdır. Önce hangisi yazılmışsa, ilk olarak o dikkate alınır. Ama bunun dışında tanınan bir işlem önceliği bulunmamaktadır.
Aşağıdaki örnek, operatör önceliklerini pekiştirmek açısından incelenebilir:
7 & 13 ^ 11 % 4 * 2 << 14 / 4
==> 7 & 13 ^ 6 << 3
==> 5 ^ 48 = 53
Şimdi de benzer bir örneği, C++ programı yazarak yapalım:
#include<iostream.h>
main( )
{
cout<< "İşlem Sonucu: <<117 & 11 << 2 * 3 );
return 0;
}
Yukardaki program, 64 sonucunu vermektedir. Programı çalıştırdığınızda, ikilik düzeyde işlemler yapılacak ve 64 cevabına ulaşılacaktır. Siz de hesaplayarak, aynı yanıtı bulabilirsiniz.
Bir sonraki dersimizde, konu anlatımı olmayacak. Onun yerine bol bol örnek yapıp, şimdiye kadar işlediğimiz konuların üzerinden geçeceğiz. Görüşmek üzere.
Program Kontrol ve Döngü Komutları
Daha önceki bölümlerde, standart veri tiplerini öğrendik, bununla birlikte diğer dillerde olmayan fakat C/C++`a özgü işlemleri de tanıdık. Şimdi ise C/C++ mantıksal kontrol yapılarını öğreneceğiz. Bu komutların bir çoğu diğer yüksek seviyeli dillerde de mevcuttur. Örneğin; if, if-else, switch, for, while ve do-while döngüleri. Fakat ?:, break, ve continue komutları gibi yalnızca C/C++`a özgü kontrol komutları da vardır. Ne demiştik C++ , C yi kapsar. O halde C de olan tüm mantıksal kontrol yapıları C++ da da mevcuttur.
Programlar (algoritmalar) üç temel blok kullanılarak gerçekleştirilebilirler. Bunlar; artarda, bir koşula bağlı olarak ve sonlu sayıda yineleme (döngü) dür.
Biz şimdi bu Mantıksal ifadeleri teker teker ele alacağız. Hem Bu sayede hepsine daha çok yer vermiş olacağız ve de örneklerle bunu pekiştireceğiz. Şimdiye kadar geldiğimiz bölümleri iyi bilip, Mantıksal ifadelerin yapılarını da öğrendiğimizde, bayağı bir yol kat etmiş olacağız.
If Komutu
if komutu anlaşılması ve yazılımı en basit olanıdır. if komutu, bir grup komutun koşullu olarak yürütülmesi amacıyla kullanılır. Buna bir örnek verecek olursak; düşünün ki bir sınav yapılıyor ve 50 ve üzeri alanlar geçecek. Bunun için if i kullanırsak not 50 ye eşit veya büyükse (büyük eşit) geçer not olacak.
//not.cpp
// 50 ve 50 den yukarsı geçiyor.
#include <iostream.h>
main()
{
int not;
cout << "Notu yazınız:";
cin >> not;
if ( not >= 50 )
cout << "Geçtiniz!";
}
Sanırım bu örnekte ne dediğimi anlamış olacaksınız.
if ( not >= 50 )
cout << "Geçtiniz!";
if (ifade)
{
Komut;
Komut;
...
}
Burda görüldüğü gibi if (ifade) ve sonraki komutlarda { } bloğunun içine yazılır. Şimdi if`e bir de şu açıdan yaklaşalım. if in kelime anlamı "eğer" dir. Mantık şudur: eğer belirtilen parametre doğruysa, if komutu, if ten sonra gelen bloktaki fonksiyonları gerçekleştirir. Doğru değilse, if den sonraki bloğu yok sayar. Burada bir detaya daha inmek istiyorum. Ne demiştik, mantık işlemlerinde olay ya doğrudur (1) ya da yanlıştır (0). Şimdi yukarıdaki if in genel kullanım şekline tekrar bakalım. Bunu, eğer parametre doğru ise kullanabiliriz. Bir de bunun tersini düşünelim. Bit bazında işlemlerde sanırım ( ! ) bunu görmüştük. Her bir biti ters çevirir.
if (!ifade)
{
komut (yanlış (0));
Komut (yanlış (0));
....
}
Derdimi anlamış olduğunuzu ümit ediyorum.
Ama bence buranın üstünde biraz daha duralım.
Çünkü bunu anlarsak diğerlerinde zorlanmayız.
Son yaptığımızda ifadeyi tersine çevirdik.
//pozitif.cpp
// Bunada açıklama yaptırmayın
#include <iostream.h>
main()
{
int x;
cout << "Bir sayı girin:" ;
cin>> x;
if ( x > 0 )
cout << "Pozitif" ;
}
Aynısının negatif ini de siz yapın. Şimdi bir de iç içe if örneğine bakalım:
//gecti.cpp
// Buna açıklama yapmıycam!
#include <iostream.h>
main()
{
int not;
cout << "Notunuzu giriniz:";
cin >> not;
if ( not> 50)
cout << "Geçtiniz!" ;
if (not < 50)
cout << "Kaldınız!" ;
if ( not==50)
cout << "zar zor geçtin”;
}
Anlamış olduğunuzu umut ederek if komutunu burada bitiriyorum.
if-else Komutları
if-else komutu iki işlemden hangisinin uygulanacağına karar verir. Else kısmı seçimlidir, gerekmiyorsa kullanılmayabilir. Yazılım kuralı ile şöyledir;
if ( ifade)
komut1;
else
komut2; daha genel şekliyle
if ( ifade )
{
komut1;
komut2;
...
}
else
{
komut1;
komut2;
...
}
Veya lojik olarak baktığımızda sanırım daha iyi anlayacaksınız
if (ifade)
blok_dogru (1);
else
blok_yanlis (0);
Sanırım artık açıklama yapmama gerek kalmayacak. Şimdi örneklerle bunu pekiştirmeye çalışalım.
//tekcift.cpp
//sayı tekmi çiftmi onu görüceğiz
#include <iostream.h>
main()
{
int sayi;
cout<< "Bir sayı giriniz:";
cin >> sayi;
if (sayi %2==1 )
cout <<"tek";
else
cout << "çift" ;
}
Bir örnek daha verelim:
//ifelse.cpp
#include <iostream.h>
main()
{
int not;
cout<< "Notu giriniz:";
cin >> not;
if (not >= 50)
cout << "Geçti!";
else
cout << "Kaldı!";
}
if kısmından anlatmaya başlayacağım. Eğer notumuz 50 ye eşit veya 50 den büyük ise geçiyoruz aksi halde kalıyoruz.
Bir de bir if-else in altında bir tane daha if-else kullanalım.
//sinav.cpp
// alt alta if-else
#include <iostream.h>
main()
{
int not;
cout<< "Not`u giriniz:";
cin >> not;
if (not >= 50)
cout << "Geçtiniz!";
else
{
cout <<"Bütten alınan not:";
cin >>not;
if( not>=60 )
cout << "Geçtiniz!";
else
cout <<"Kaldınız!";
}
}
Burada da şunu inceledik: diyelim ki sınava girdik ve notumuzu öğrendik, notu giriyoruz 50 nin altındaysa kalıyoruz. ve bütünleme sınavına giriyoruz. Bütte de geçer not en az 60. Sanırım bu basit örneklerle olayı iyice kavramışızdır. if-else i de burada bitiriyoruz.
Switch-case Komutları
Switch Case deyimi işlev bakımından if deyimine çok benzemektedir. Çok sayıda if işlem blokları kullandığımızda programın okunurluğu azalacak ve programı izlemek zorlaşacaktır. Programımızın bir değerini bir çok değerle karşılaştırmak gerektiğinde switch komutunu kullanacağız. Switch seçeneği ile değişkenin durumuna göre bir çok durum içersinden bir tanesi gerçekleştirilir. İstersek de if deyimi ile switch case' yi birlikte kullanabiliriz. Switch in yaptığı iş kısaca, ifadenin değerini sırayla sabitlerle karşılaştırarak ve her satırı işlemektir.
switch( Kontrol Değişkeni )
{
case Sabit1 : komut1;
case Sabit2 : komut2;
.
.
.
default : Komutson;
}
Buna en basit örneğimizi verelim
//switch.cpp
// switch-case yi öğreniyoruz.
#include <iostream.h>
main()
{
int i;
cout<< " 1 ile 4 arası sir sayı giriniz:";
cin>>i;
switch(i)
{
case 1 :cout<<"1 Girdiniz"; break;
case 2 :cout<<"2 Girdiniz"; break;
case 3 :cout<<"3 Girdiniz"; break;
case 4 :cout<<"4 Girdiniz"; break;
default:cout<<"1 ile 4 ten farklı";
}
}
Burada gördüğümüz gibi i değişkenine bağlı olarak program işliyor. Case'lerinin aldığı değere göre kendinden sonra gelen komutları işliyorlar. Burada daha önce görmediğimiz break komutunu gördük. Buna ilerde daha detaylı olarak değineceğim. Fakat biraz bahsetmek istiyorum. Programımızda değişkene 1 değerini verdiğimizi farz edelim. Case 1 adlı satırı geçip ondan sonraki komut dizisini işleme soktuk. Bu işlemin tamamlanması için break komutu kullanılıyor. Yazılımda break komutu goto gibi işlev görür ve derleyiciye switch komutundan çıkması için talimat verir. Sorunu ortadan kaldırmak için her durum için break deyimi eklemeliyiz (tavsiye). Ne demiştik; bir çok karşılaştırma olduğunda switch'e ihtiyaç duyuyoruz. Karşılaştırmaların hiç biri olmadığı anda da ortaya default tan sonraki satırın işlenmesi kalıyor. Sanırım bu örnekte basit olarak anlamış olacağız.
Daha karmaşık bir örnek verecek olursak:
//ucgen.cpp
// Program gireceğimiz ölçülere göre üçgenin Alan, Yükseklik ve Tabanını bulur
// switch-case örneğimiz.
#include <iostream.h>
int main()
{
char secenek;
float alan, yukseklik, taban;
cout << "Program gireceğimiz ölçülere göre üçgen'in Alan,
Yükseklik ve Tabanını bulur!\n" << endl
<< " A ---> Alan : Bulmak için yükseklik ve tabanı gireceğiz:" << endl
<< " h ---> Yükseklik : Bulmak için alan ve tabanı gireceğiz:" << endl
<< " t ---> Taban : Bulmak için alan ve yüksekliği gireceğiz:" << endl
<< endl << endl;
cout<< "Seçeneğiniz? ---> A, h, t :";
cin>> secenek;
switch(secenek)
{
case 'a':
case 'A':
{
cout<< endl <<endl <<"Yükseklik: ";
cin>> yukseklik;
cout<<endl << "Taban: ";
cin >> taban;
alan = 0.5 * taban * yukseklik;
cout<<endl << endl << "Alanı: " << alan << endl;
break;
}
case 'h':
case 'H':
{
cout<< endl << endl <<"Alanı: ";
cin>> alan;
cout<<endl << "Tanabı: ";
cin >> taban;
yukseklik = 2.0 * alan / taban;
cout << endl << endl << "Yükselik: " << yukseklik << endl;
break;
}
case 't':
case 'T':
{
cout << endl <<endl <<"Alanı: ";
cin >> alan;
cout << endl << "Yüksekliği: ";
cin >> yukseklik;
taban = 2.0 * yukseklik / alan;
cout << endl << endl <<"Tabanı: " << taban << endl;
break;
}
}
return 0;
}
Gayet basit bir örnek değişkenleri tanımladık. Caseleri koyduk ve caselerden sonra gelecek komut satırlarını yerleştirdik. Bu program göründüğü gibi zor değildir.
Döngü Komutları
Bir ya da birden fazla deyimin tekrar edilmesini sağlarlar. Döngüler, " belli bir koşul sağlandığı sürece sürekli çalıştırılacak kod parçası " olarak nitelendirilebilir. For döngüsü, while döngüsü, do-while döngüleri, diğer yüksek seviyeli dillerdeki gibidir. Ancak en büyük fark, programın bu tekrar döngüleri istediğinde terk edebilmesidir. C/C++, döngüden çıkmak için beş ayrı yöntem vardır.
C/C++ da ki döngülerin arasındaki fark, beklenen döngü sayıları arasındaki farktan kaynaklanır. Eğer önceden belirli bir döngü sayımız mevcut ise For döngüsü kullanılır. while ve do-while döngülerinde döngü sayısı belli değildir. C++ nın bize vermiş olduğu esneklik sayesinde, döngüleri son derece esnek bir biçimde kullanma şansımız vardır.
While Döngüsü
İçlerinde anlatımı ve anlaşılması en kolay olan döngüdür. While döngüsü, döngü sayısının belli olmadığı zamanlarda kullanılır.
while ( koşul )
Komut; While döngüsü, içinde bulunan ifade doğru olduğu sürece altındaki komut veya komut bloğu yürütülür. Eğer yanlış ise kontrol bir sonraki komut veya komut bloğuna geçer.
While döngüsü daha genel şekliyle:
while ( ifade )
{
komut;
komut;
komut;
.
.
.
} Burada bir şeye dikkat etmenizi istiyorum. Çoklu komutlar kullandığımızda " { } "parantezleri gereklidir.
// while1.cpp
// while döngüsünü kullandık
// girdiğimiz sayıdan 100 e kadar olan sayıları topladık
#include <iostream.h>
main()
{
int x, y;
y= 0;
cout<< " Bir Sayı Giriniz ( Sayı 100 den küçük olucak ) : ";
cin>>x;
while (x< 101)
{
y =y+x;
x =x+1;
}
cout<< "Toplam= "<< y;
}
Burada önce x ve y yi tanımladık. y=0 değerini verdik. Sonra klavyeden girilen değerin x olduğunu yazdık. while (x< 101) işte burada ifademiz x< 101. Şimdi bu koşul sağlanıncaya kadar döngümüz devam edecek. While' den sonraki bloğa geçtiğimizde ise. y` ye x i ekliyoruz ve x in değerini her seferinde 1 arttırıyoruz. Sanırım bu basit örnekte döngünün basit yapısını ve mantığını anlamış oldunuz.
Döngünün verilen ifade veya koşula göre sağlanması döngülerin en önemli konusudur. Eğer bir döngüden çıkılmazsa o döngü sonsuza gider. Buna da "sonsuz döngü" denir. Döngüler konusunda en çok rastlayacağımız hata da budur.Şimdi buna bir örnek verelim. Fakat, şimdiden uyarıyorum, sonsuz döngü yapıldığında bilgisayarınız kilitlenebilir. Onun için buna şimdiden hazır olun. Zaten bir sefer denediğimizde ne demek istediğimi anlayacaksınızdır.
//sonsuz.cpp
//while döngüsü ile sonsuz bir döngü yaptık
#include <iostream.h>
main()
{
int x=1;
while(x)
cout<< "x= "<< x++<< endl;
}
Burada neden sonsuz bir döngü oldu? Evet işte x ifadesini koşula bağlamadık. Şayet while(x<10) demiş olsaydık. 1,2,3,4,5,6,7,8,9 a kadar x sayısı sıralanacaktı.
//klavye.cpp
//while döngüsü ile klavyeden girilen sayı
#include <iostream.h>
main()
{
int x, y = 0;
while (y< 20)
{
cin>>x;
y = y+x;
}
cout<< "Toplam= "<< y ;
}
Bu programda da klavyeden girilen sayıların toplamı 20' den büyük olunca program Toplam olarak söylüyor. Sanırım basit While yapısını anladınız. Şimdi birazda karmaşık programcıklar yapalım[IMG]http://www.************/images/smilies/smile.gif[/IMG].
1. Örnek: Girilen altı not'un ortalamasını alıyor.
//ortalama.cpp
// while döngüsü ile girilen notların ortalamasını aldık.
#include <iostream.h>
int main()
{
int toplam,
sayac,
not,
ortalama;
toplam = 0;
sayac = 1;
while ( sayac <= 6 )
{
cout << "Notu giriniz: ";
cin >>not;
toplam = toplam + not;
sayac = sayac + 1;
}
ortalama = toplam / 6;
cout << "Sınıf ortalaması = " << ortalama << endl;
return 0;
}
Bu örneğimizde yine toplam, sayac, not, ortalama gibi değişkenleri tanımladık. ( toplam =0 ; ve sayac = 1; ) de değişkenlere ilk değerlerini atadık. While döngüsünün içinde sayac değişkenimizi altı defa işlemesini söyledik. Sonra alttaki toplam ve sayac bölümlerinde ise toplam a not' u ekliyoruz, her seferinde de sayac değerini bir arttırıyoruz ve sayac değeri 6' ya gelince while döngümüz duruyor. Program sonra toplamı alıp altıya böler bu sayede ortalamayı alır, sonrada çıktısını gerçekleştirir.
2. Örnek:
//faktoriyel.cpp
// while ile faktoriyel hesaplama
#include <iostream.h>
int main()
{
int sayi;
long int faktoriyel=1;
cout << "Bir sayı giriniz: ";
cin >> sayi;
cout << sayi << " `in Faktöriyeli: ";
while (sayi > 1)
faktoriyel *= sayi--;
cout << faktoriyel << endl;
return 0;
}
Burda while (sayi>1) şeklinde koşulumuzu belirttik. Bir altında ise faktoriyel *= sayi--; evet burda da daha önce gördüğümüz gibi eşitleme operatörü olan ( *= ) i kullandık. Yani faktoriyel'e faktoriyel*sayi-- nin değeri atanır. Matematiğini düşünürseniz; 7 sayısının faktöriyeli 7 *= 7-- gibi. yani 7 ye devamlı 7-- oda 6 demektir. 6 ile carpımı eklenir, bu 6-- ile devam eder. En basit anlatımı bu[IMG]http://www.************/images/smilies/smile.gif[/IMG] Sonrada tüm while döngüsü bittikten sonrada faktoriyel' in sonucu çıktı olarak ekrana gelir. Bu örnekte negatif sayıların faktöriyelini de 1'e eşit tutuyor. Dikkat ediniz. Negatif sayıların faktöriyeli alınmaz şartını koymadık. Şayet siz koymak isterseniz bir if else bloğu yerleştirmelisiniz if(sayi>=0) faktoriyel al yoksa faktoriyel alma gibi.
3. Örnek:
// maas.cpp
// while if-else ile bir maas vergi uygulaması
#include <iostream.h>
int main( )
{
unsigned long maas, net, vergi = 0.0; // maas net vergi bunları tanımladık
cout<< "Lütfen maaşınızı giriniz: "; // maası giriyoruz
cin>> maas; // maası programa alıyoruz
while( maas >= 0.0 ) // maaşın koşlunu yazıyorus döngüye
{
if( maas <= 250000000 ) // maaş 250 milyondan az ise
vergi = 0.0;
else // vergi yok[IMG]http://www.************/images/smilies/smile.gif[/IMG]
if( maas < 500000000 ) // maas 500 den az ise
vergi = maas * 0.10; // vergi %10
else // 500 den fazla ise
vergi = maas * 0.20; // vergi %20
net = maas - vergi; // net maaşımız vergi düşünce çıkar
cout<< "Ödenmesi Gereken vergi " << vergi << endl; // vergi ekranda
cout<< "Net maaşınız: " << net << endl; // geriye kalan maaşımız
cout<< "Lütfen maaşınızı giriniz: "; // bir dahaki ayki yeni maaşımız
cin>> maas; // maaşı program alıyor
}
return 1;
}
Bu örnekte sanırım fazla açıklama yok. Sizden istediğim, üç kişinin maaşını girdikten sonra onların alacağı toplam maaş ve ödemeleri gereken toplam vergiyi bulmanız. Bunu yaparsanız buraya kadar olanlardan bir şeyler anlamışızdır.
Do-while Döngüsü
Do - while Döngüsü:
Bu döngü while döngüsünün biraz değiştirilmiş halidir. Do-while döngüsünde karşılaştırma işlemi, döngünün sonunda gerçekleşir. Bunun sonucu olarak döngünün içine en az bir defa girilmiş olur. Yapısı aşağıdaki gibidir.
do
cümle
while ( koşul ); do' nun altındaki cümle kısmındaki komut satırları birden fazla olursa diğer döngülerde olduğu gibi " { } " içine alıyoruz. Bunu kullanmamız kodları okuma da ve ayırma da daha çok işimize yarayacaktır.
do
{
cümle
cümle
cümle
...
}
while ( koşul );
Şimdi yukarıda demek istediğimizi standart kod satırı üzerinde anlatalım. Kodları yazdığımızda, komut sırası do'ya geldiği zaman, do' dan sonraki komutun döngünün başı olduğunu belirtiyor. Diğerlerinden farklı ( for, While ) olarak döngüye giriş yapıyor, yani hiçbir kontrol yapmadan en az bir defa döngünün içine girmiş oluyoruz. While'e geldiğinde ise koşulu kontrol ediyor, eğer doğru ise döngünün başındaki komuta giderek yeniden komutları işliyor. Eğer koşul kontrolü yanlış ise while'den bir sonra ki komutu veya komutları işleyip döngüden çıkıyor. Şimdi bu söylediklerimizi örnek üzerinde gösterelim.
//do.cpp
// number echoer
//do-while döngüsünü kullandık
#include <iostream.h>
int main ()
{
unsigned long x;
do {
cout<< "Bir sayı giriniz ( Durdurmak için 0 ) : ";
cin>> x;
cout<< "Girdiğiniz sayı: " << x << "\n";
}
while (x != 0);
return 0;
}
Örneğimizde de görüldüğü gibi önce do dan sonraki komutlar işleniyor. Şayet 0 girersek while işlemeye başlıyor. Do-while döngüsü C++ da çok fazla kullanılmaz bunun yerine biz for' u kullanacağız çünkü for döngüsü çok daha güçlüdür.
"O zaman vecd ile bin secde eder -varsa- taşım."
-Vücuda verilen kuvvet, Hak’ka ibadet, halka hizmet içindir.
For Döngüsü
For döngüsünün çalışması, döngünün kontrol değişkenine başlangıç değerinin atanması ile başlar. Aşağıda vereceğimiz ilk değer atama cümlesinden kastımızda budur. Yani bu kısımda başlangıç tanımları yapılır. For döngüsünün başlangıç adımıdır. Bu kısımda yapılan bir değişken tanımındaki değişkenin ömrü, for döngüsünün sonunda biter. Sonra döngü koşul kısmına gelinir ve bu test edilir. Şayet değeri !0, doğru (1) olduğunda döngü içindeki komutlar uygulanır. Arttırma ise for döngüsü işleminin sonunda meydana gelir. for içindeki tüm deyimler meydana geldikten sonra uygulanır.
Genel yapısı:
for ( ilk değer atamalar, koşul, arttırma)
cümle Bunu daha da genellersek, diğerlerinde de olduğu gibi cümleler birden fazla olduğunda komut bloğu arasına alınacaktır.
for ( ilk değer atamalar, koşul, arttırma)
{
cümle1
cümle2
cümle3
...
} Bu söylediklerimizi bir örnek üzerinde izah edelim.
//for.cpp
// for döngüsüyle bir örnek.
#include <iostream.h>
int main ()
{
for (int n=10; n> 0; n--)
{
cout << n << " -> ";
}
cout<< "Bitti!";
return 0;
} Ben sadece for (int n=10; n>0; n--) bu kısmı anlatacağım, diğer kısımlar apaçık gözüküyor zaten. For diyip () imizi açtık. Sonra içine ilk basamağımız olan değişken tanımlamamızı yaptık. İnt n=10; Bu bizim yukarıda bahsettiğimiz ilk değer atamalar kısmı. Daha sonra koşulumuzu yazdık. n>0; bunu test ettik ve !0 yani doğru (1) çıktı. Sonrada n-- yi yazdık. Genel tanımda yazdığımız arttırma kısmı. Aslında buna yenileme komutları desek daha doğru olur. Biz bu örnekte örneğin azaltma yaptık. Neyse umarım bu for örneğini anlamışsınızdır.
C++ da yapacağımız çoğu örnekte for u kullanacağız. C++ 'nın en güçlü yanlarından biriside for döngüsüdür. For döngüsünün başında yani ilk değer atama kısmında birden çok değişken tanımlayıp değer atıyorsak bunları virgül ( , ) ile bir birinden ayırmalıyız. İlk değer atamadan koşul bölümüne geçtiğimizde ve koşul bölümünden arttırma ya geçerken noktalı virgül ( ; ) kullanmalıyız. Tabi kullandığımız bu üç kısım seçimlidir istersek boş bırakabiliriz. Fakat, noktalı virgüller ( ; ) konulması zorunludur.
1.Örneğimiz:
//factoriyel_for.cpp
//for döngüsüyle faktöriyel hesap.
#include <iostream.h>
int main()
{
int fac, sayi;
cout<<"Sayıyı giriniz: ";
cin>>sayi;
fac=1;
for (int j=1; j<=sayi; j++)
{
fac=fac*j;
}
cout<<"Sonuc: \a"<< fac;
return 0;
} Bu örneğimiz oldukça basit. Bildiğimiz matematiksel faktöriyel işlemini C++ kodları olarak yazdık. (\a yı kullandım bip! demesi için[IMG]http://www.************/images/smilies/smile.gif[/IMG] ).
2.Örneğimiz:
//carpim_for.cpp
// iç içe for döngüsüyle çarpım tablosu
#include <iostream.h>
main()
{
cout<<"Çarpım Tablosu! \n"<<endl;
int x,y;
for (x=1; x<=10; x++)
{
for (y =1; y<=10; y++)
cout<<" "<<x*y;
cout<<"";
}
} Görüldüğü gibi ilk for döngüsünde, birinci bileşen olan x i önce 1 e eşitledik sonra birer arttırarak 10' a kadar götürdük. Sonraki for da da aynısını y için yaptık ve bu iki bileşeni çarparak ekrana yazdırdık. Son derece basit bir örnek.
3.Örneğimiz:
//asal_for.cpp
// for , if ve while ile asal sayı bulma
#include <iostream.h>
int main()
{
int sayi;
cout << "Bir sayı girinizr: ";
cin >> sayi;
for (int sayac=1; sayac< sayi; sayac++)
{
int asal, test;
test = sayac;
asal = 1;
while (test--> 2)
if ((sayac % test) == 0)
asal = 0;
if (asal == 1)
cout<< sayac << " bir asal sayıdır!\n";
}
return 0;
} Bu örneğimizde ikinci örneğimize benziyor. İçinde for, while ve if de var. While ve if' in içindeki matematiksel ifadeleri biliyorsak örnek gayet basit gelicektir. Burada bırakmak istiyorum. Bir sonraki ders görüşmek üzere.
Break Komutu
Break komutunu, swtich komutundan çıkmak için önceki derslerimizde görmüştük. Komutun kendine özgü bir kullanımı daha vardır. Break komutu bir döngünün içinde çalıştırılırsa o an o döngü biter. Bir goto gibi işlem gördüğünü de söyleyebiliriz. Break kullanınca program döngüyü bitirir ve döngünün sonundaki satırdan çalışmaya devam eder. Bir örnek verelim.
//break.cpp
//break komutunu kullandik.
#include <iostream.h>
main()
{
for (int x = 1; x <= 10; x++) {
if (x == 7) {
break;
}
cout<< x << " ";
}
} İşte örneğimizde gördüğünüz gibi. X 7'ye eşit olunca break; döngüyü bitiriyor ve döngüden sonraki satırı çalıştırmaya başlıyor.
Continue Komutu
Continue komutu bir döngü içinde çalıştırılırsa , o döngü içinde bulunan tur sona erer ancak döngü devam eder. Diğer bir deyişle, gövdenin içinde bulunan continue komutundan sonra gelen cümleleri atlayarak, döngüyü devam ettirir. Bunu bir örnekle açıklayayım.
//continue.cpp
//continue ve break komutunu kullandik.
#include <iostream.h>
main()
{
for(int i=0; i <= 9; i++)
{
if(i==5)
break;
cout<<i<< endl;
}
for(int x=0; x <= 9; x++)
{
if(x ==3)
continue;
cout<< x;
}
} Bu örnekte break ve continue'yu birlikte kullandım. Hem continue'yu hem de break ve continue karışımını bir arada vermiş oluruz diye düşünüyorum. Örneğimizi inceleyecek olursak. Break olan kısımda görüleceği gibi 5'e kadar döngü devam ediyor, döngü bitiyor ve ondan sonraki cümleye geçiliyor. Sonra yine bir for döngüsü başlıyor ve bu sefer x 3' e eşit olana kadar devam ediyor. 3'e eşit olunca da if içindeki x==3 koşulunu sınıyor ve continue ye olduğu için bunu atlıyor. Zaten ekran çıktısını aldığınızda ne demek istediğimi daha rahat anlayacaksınız.
Benim size tavsiyem break ve continue komutlarını yapmış olduğunuz basit programlarda kullanmanızdır.
__________________
Exit Fonksiyonu
Hayati hata durumlarını ele almak için exit() fonksiyonundan yararlanılır. Bu hatalar main() fonksiyonunu return ile normal olarak sonlandırılmadan önce oluşabilir. Exit() fonksiyonu, durum değerini bir tam sayı parametre olarak döndürür.
Exit() ile özel bir değerin gönderilmesi bazı işlemler yapması için kullanılabilir. Örneğin program komut satırında kullanılıyorsa ve durum değeri bazı hataları gösteriyorsa, işletim sistemi bunları mesaj olarak yazabilir. Exit() fonksiyonu programı sonlandırmanın yanında, tüm bekleyen yazma işlemlerini tamamlar ve açık tüm dosyaları kapatır.
Exit() fonksiyonunu kullanırken kullanmamız gerek kütüphaneler ise process.h ve stdlib.h tır.
Örnekler
Eğer bunları içten gelerek okuyorsanız ve zevk alıyorsanız dikkat etmeniz gereken ve size en zevkli gelecek kısımlar.
1) //ASCII kodu x olan karakteri buluyorus
#include <iostream.h>
#include <stdio.h>
int main()
{
int ch;
ch = 85;
cout<<"ASCII kodu 85 olan karakter :";
putc(ch, stdout);
cin>>"\n";
return (0);
}
2) //Derecenin sin,cos,tan değerlerini bulma
#include <iostream.h>
#include <math.h>
int main()
{
double x; //x i tanımladık
x = 45.0; // 45 derece
x *= 3.141593 / 180.0; // Dereceyi radyal değere döndürme
cout<<"45 derecenin sinusu: "<< sin(x)<<endl;
cout<<"45 derecenin kosinusu: "<< cos(x)<<endl;
cout<<"45 derecenin tanjantı: "<< tan(x)<<endl;
return (0);
}
3) // Haftanın günleri[IMG]http://www.************/images/smilies/smile.gif[/IMG]
//switch ve caseleri kullanıyorus.
#include <iostream.h>
#include <stdio.h>
int main()
{
int gun;
cout<<"Lutfen bir karakter giriniz!\n";
cout<<"(Karakter 1 ile 7 arasında olsun):\n";
gun = getchar();
switch (gun){
case '1':
cout<<"Pazartesi \n";
break;
case '2':
cout<<"Salı \n";
break;
case '3':
cout<<"Çarşamba \n";
break;
case '4':
cout<<"Perşembe \n";
break;
case '5':
cout<<"Cuma \n";
break;
case '6':
cout<<"Cumartesi \n";
break;
case '7':
cout<<"Pazar \n";
break;
default:
cout<<"Girdiginiz karakter 1-7 arasında olsun.\n";
break;
}
return 0;
} 4) //mantıksal operatörler için
#include <iostream.h>
int main()
{
char cocuk, para, araba;
cout << "Çoçuğunuz varmı? (Y/N) ";
cin >> cocuk;
cout << "Çok paranız varmı? (Y/N) ";
cin >> para;
cout << "Spor araba severmisiniz? (Y/N) ";
cin >> araba;
//seçenekleri ben kafadan attım
//maksat burda mantıksal operatörlerin işleyişini görmek
if ((cocuk == 'Y') && (para == 'Y') && (araba == 'N'))
cout << "Sizin için en uygun araba Kamyonet[IMG]http://www.************/images/smilies/smile.gif[/IMG] " << endl;
else if ((cocuk == 'Y') && (para == 'Y') && (araba == 'Y'))
cout << "Sizin için en uygun araba Toros[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
else if ((cocuk == 'Y') && (para == 'N'))
cout << "Sizin için en uygun araba Renault[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
else if ((cocuk == 'N') && (para == 'Y') && (araba == 'N'))
cout << "Sizin için en uygun araba Jeep[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
else if ((cocuk == 'N') && (para == 'Y') && (araba == 'Y'))
cout << "Sizin için en uygun araba Bisiklet[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
else if ((cocuk == 'N') && (para == 'N'))
cout << "Sizin için en uygun araba Subaru İmpreza WRX[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
}
5)//sort.cpp
#include <iostream.h>
#include <iomanip.h>
int main()
{
int x[10] = {1, 37, 3, 7, 4, 9, 2, 33, 19, 5};
int counter;
cout << "S\x{0131}ralamadan önce:\n\n";
cout << "Eleman" << setw(10) << "\x{0130}çerik" <<endl;
// \x{015E}u anki dizinin içeri\x{011F}ini
//gosterir.
for (counter=0; counter<10; counter++)
cout << setw(7) << counter << setw(10) << x[counter] << endl;
// Diziyi s\x{0131}rala
for (int outer=0; outer<10; outer++)
for (int inner=outer+1; inner<10; inner++)
if (x[inner] < x[outer])
{
// De\x{011F}erlerin yerlerini
//de\x{011F}i\x{015F}tir
int temp = x[inner];
x[inner] = x[outer];
x[outer] = temp;
}
cout << "S\x{0131}ralamadan sonra:\n\n";
cout << "Eleman" << setw(10) << "\x{0130}çerik" <<endl;
// S\x{0131}ralanm\x{0131}\x{015F} dizinin
//içeri\x{011F}ini gösterir.
for (counter=0; counter<10; counter++)
cout << setw(7) << counter << setw(10) <<
x[counter] << endl;
return 0;
} 6)//y=aX^n+bx^(n-1)+.....+zX^0 denkleminin bir noktada türevini bulma
#include <stdio.h>
#include <math.h>
void main(void)
{
int max=11,t,i,denklem[11];
float x,r;
while(max>10)
{
printf("En büyük X değerinin üst ünü giriniz:");
scanf("%d",&max);
}
for (i=max;i>=0;i--)
{
printf("X^%d nin katsayını giriniz :",i);
scanf("%d",&denklem[i]);
}
printf ("Türevi hesaplanacak noktayı giriniz :");
scanf("%f",&x);
r= (max*denklem[max]) * pow(x,(max-1));
for (i=(max-1);i>1;i--)
{
r=r + ((i*denklem[i]) * pow(x,(i-1)));
}
r=r + denklem[1];
printf("Sonuc = %f",r);
}
2)
Örnekler 2
7) #include <iostream.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
int idariPersonel=0, yazilimciKadrolu=0, yazilimciProje=0;
double netMaasToplam=0, cesitliKesintiToplam=0, saglikKesintiToplam=0;
//programın en sonunda hesaplayacağı toplamlar.
while(1)
{
cout<<"Personel türü:"<<endl;
cout<<"A-İdari"<<endl;
cout<<"B-Yazılımcı (Kadrolu)"<<endl;
cout<<"C-Yazılımcı (Proje)"<<endl;
cout<<"X-Programdan Çıkış"<<endl;
char tur;
cin>>tur;
tur=toupper(tur);
if(tur=='X') {break;}
switch (tur)
{
case 'A' : {
int saat=0, saatUcreti=0;
const int NORMAL=22*8;
double brut=0, net=0, kesinti=0;
cout<<"Toplam çalışma süresini (saat) giriniz: ";
cin>>saat;
cout<<"Saat ücretini giriniz: ";
cin>>saatUcreti;
brut=(double)(NORMAL + 1.5*(saat-NORMAL))*saatUcreti;
//bu satır hem normal hemde fazlamesai de çalışır
net=brut*0.8; kesinti=brut*0.2;
//artık bordor yazılabilir.
cout<<"Bordor bilgileri:"<<endl;
cout<<"Toplam çalışma sürtesi:"<<saat<<"saat."<<endl;
cout<<"Brüt ücret: \t"<<brut<<"TL."<<endl;
cout<<"Kesintiler: \t"<<kesinti<<"TL."<<endl;
cout<<"Net ücret: \t"<<net<<"TL."<<endl;
//genel hesaplara ilişkin yenilemeler
netMaasToplam+=net; cesitliKesintiToplam+=kesinti;
idariPersonel++;
//switchden çıkıyorus.
break;
}
case'B':{
int saat=0, saatUcreti=0;
const int NORMAL=22*10;
double brut=0, net=0, kesinti=0, saglik=0;
cout<<"Toplam çalışma süresi (saat) giriniz: ";
cin>>saat;
cout<<"Saat ücretini giriniz: ";
cin>>saatUcreti;
brut=(double)(NORMAL+1.5*(saat-NORMAL))*saatUcreti;
//bu satır hem nromal hem de fazla mesai de çalışır.
net=brut*0.65;
kesinti=brut*0.2;
saglik=brut*0.15;
//artik bordro yazılabilir
cout<<"Bordro bilgileri: "<<endl;
cout<<"Toplam çalışma süresi:"<<saat<<"saat."<<endl;
cout<<"Brüt ücret: \t"<<brut<<"TL."<<endl;
cout<<"Kesşntiler: \t"<<kesinti<<"TL."<<endl;
cout<<"Sağlık kesintileri: \t"<<saglik<<"TL."<<endl;
cout<<"Net ücret: \t"<<net<<"TL."<<endl;
//genel hesaplara ilişkin yenilemeler.
netMaasToplam+=net;
cesitliKesintiToplam+=kesinti;
saglikKesintiToplam+=saglik;
yazilimciKadrolu++;
//switch den çıkıyoruz.
break;
}
case'C': {
int modul;
double temel=0, modulBasi=0;
double net=0;
cout<<"Temel ücreti girin: ";
cin>>temel;
cout<<"Teslim edilen modül sayısını girin: ";
cin>>modul;
cout<<"Modül başı ücreti girin: ";
cin>>modulBasi;
net=(double) temel+modul*modulBasi;
//artık bordro yazılabilir.
cout<<"Bordor bilgileri:"<<endl;
cout<<"Bitirilen Modül sayısı: "<<modul<<endl;
cout<<"Net ücret: \t"<<net<<"TL."<<endl;
//genel hesaplara ilişkin yenilemeler
netMaasToplam+=net; yazilimciProje++;
//switch den çıkıyorus
break;
}
default: {
cout<<"Geçersiz personel türü. Yeniden Deneyin."<<endl;
}
}//switch
cout<<"Başka bir personelin maaşını hesaplamak istiyormusunuz?(E/H)";
char secenek;
cin>>secenek;
secenek=toupper(secenek);
if(secenek=='H') {break;} //bu while den çıkartır.
else if (secenek=='E'){} //birşey yapma
else {cout<<"Geçersiz seçenek. Ana menüye dönüyor..."<<endl;
//acaba ekranı nasıl temizlerdik?
//Böylece daha güzel görünümlü olan bir programımız olurdu[IMG]http://www.************/images/smilies/smile.gif[/IMG]
}//while
cout<<"Oturum İçin Genel Bilgiler:"<<endl;
cout<<"--------------------------------------"<<endl;
cout<<"Toplam İdari Personel: \t"<<idariPersonel<<endl;
cout<<"Toplam Yazılımcı (Kadrolu): \t"<<yazilimciKadrolu<<endl;
cout<<"Toplam Yazılımcı (Proje): \t"<<yazilimciProje<<endl;
cout<<"--------------------------------------"<<endl;
cout<<"Toplam Net ödeme: \t\t"<<netMaasToplam<<"TL."<<endl;
cout<<"Toplam Cesitli Kesintiler: \t"<<cesitliKesintiToplam<<"TL."<<endl;
cout<<"Toplam Sağlık Sigortası Kesintisi: \t"<<saglikKesintiToplam<<"TL."<<endl;
cout<<"--------------------------------------"<<endl;
system("PAUSE");
return 0;
} Bu örnek Bora GÜNGÖREN`e ait olan C++ İLE NESNE TABANLI PROGRAMLAMA kitabından alınmıştır.
main( ) Fonksiyonu
Şimdiye kadar yazdığımız bütün kodlarda, main( ) şeklinde bir notasyon kullandık. Bu kullandığımız ifade, aslında main( ) fonksiyonudur. C programlama dilinde, bir kodun çalışması main( ) fonksiyonun içersinde olup olmamasına bağlıdır. Bir nevi başlangıç noktası olarak düşünebiliriz. Her programda sadece bir tane main( ) fonksiyonu bulunur. Başka fonksiyonların, kütüphanelerin, kod parçalarının çalıştırılması main( ) içersinde direkt veya dolaylı refere edilmesiyle alakalıdır.
main( ) fonksiyonuna dair bilgimizi pekiştirmek için bir program yazalım. Aşağıdaki çizimi inceleyip, C programlama diliyle bunu çizen programı oluşturalım.
/\
/ \
/ \
/ \
----------
| |
| |
| |
----------
Ev veya kule benzeri bu şekli aşağıdaki, kod yardımıyla gösterebiliriz:
#include<iostream.h>
main( )
{
cout <<( " /\\ \n" )<< endl;
cout<<( " / \\ \n" )<< endl;
cout<< (" / \\ \n" )<< endl;
cout<< ( " / \\\n" )<< endl;
cout<< ( "----------\n" )<<endl;
cout<< ( "| |\n" )<< endl;
cout<< ( "| |\n" )<< endl;
cout<< ( "| |\n" )<< endl;
cout<< ( "----------\n")<< endl;
getchar ();
return 0;
}
Programın özel bir yanı yok. '\' simgesi özel olduğu için bundan iki tane yazmamız gerekti. Bunu önceki derslerimizde işlemiştik. Bunun dışında kodun herhangi bir zorluğu olmadığı için açıklamaya girmiyorum. Dikkat etmeniz gereken tek şey, kodun main( ) fonksiyonuyla çalışması.
Bilgilerimizi özetleyecek olursak; main( ) fonksiyonu özel bir yapıdır. Hazırladığımız program, main( ) fonksiyonuyla çalışmaya başlar. main( ) fonksiyonu içersinde yer almayan kodlar çalışmaz.
Fonksiyon Oluşturma
Kendinize ait fonksiyonlar oluşturabilirsiniz. Oluşturacağınız fonksiyonlar, vereceğiniz işlemi yapmakla görevlidir ve çağrıldıkça tekrar tekrar çalışır.
Yukardaki ev örneğine geri dönelim. Her şeyi main( ) içinde, tek bir yerde yazacağımıza, çatıyı çizen ayrı, katı çizen ayrı birer fonksiyon yazsaydık daha rahat olmaz mıydı? Ya da birden çok kat çizmemiz gerekirse, tek tek kat çizmekle uğraşmaktansa, fonksiyon adını çağırmak daha akıllıca değil mi? Bu soruların yanıtı, bizi fonksiyon kullanmaya götürüyor. Şimdi yukarda yazdığımız kodu, iki adet fonksiyon kullanarak yapalım:
/* Ev sekli cizen program */
#include<iostream.h>
// Evin catisini cizen fonksiyon.
// Fonksiyonlar programların parçalarıdır. Fonksiyonları trene takılan VAGON lar olarak düşünelim.
void catiyi_ciz( void ) //program parçası VAGON
{
cout << ( " /\\ \n" );
cout << ( " / \\ \n" );
cout << ( " / \\ \n" );
cout << ( " / \\\n" );
cout << ( "----------\n" );
}
// Evin katini cizen fonksiyon. //Program parçası VAGON
void kat_ciz( void )
{
cout <<( "| |\n" );
cout <<( "| |\n" );
cout <<( "| |\n" );
cout <<( "----------\n" );
}
int main( void ) // Ana Program TREN
{
catiyi_ciz(); //Fonksiyon ismi trene takılan kanca gibidir. KANCA
kat_ciz(); //Fonksiyon ismi trene takılan kanca gibidir. KANCA
getchar ();
return 0;
}
Yazdığımız bu kod, ilk başta elde ettiğimiz çıktının aynısını verir. Ama önemli bir fark içerir:. Bu programla birlikte ilk defa fonksiyon kullanmış olduk!
Fonksiyon kullanmanın, aynı şeyleri baştan yazma zahmetinden kurtaracağından bahsetmiştik. Diyelim ki bize birden çok kat gerekiyor. O zaman kat_ciz( ) fonksiyonunu gereken sayıda çağırmamız yeterlidir.
/* Ev sekli cizen program */
#include<iostream.h>
// Evin catisini cizen fonksiyon.
void catiyi_ciz()
{
cout << ( " /\\ \n" );
cout << ( " / \\ \n" );
cout << ( " / \\ \n" );
cout << ( "/ \\\n" );
cout << ( "---------\n" );
}
// Evin katini cizen fonksiyon.
void kat_ciz()
{
cout << ( "| |\n" );
cout << ( "| © © |\n" );
cout << ( "| |\n" );
cout << ( "---------\n" );
}
// Programin calismasini saglayan
// ana fonksiyon.
int main( void )
{
catiyi_ciz( );
// 3 adet kat ciziliyor.
kat_ciz( );
kat_ciz( );
kat_ciz( );
getchar ();
return 0;
}
Yukarda yazılı kod, bir üstekinden pek farklı durmasa bile, bu sefer üç katlı bir evin çıktısını elde etmiş olacaksınız.
Yaptığımız örneklerde, kullanılan void ifadesi dikkatinizi çekmiş olabilir. İngilizce bir kelime olan void, boş/geçersiz anlamındadır. C programlama dilinde de buna benzer bir anlam taşır. kat_ciz( ); fonksiyonuna bakalım. Yapacağı iş için herhangi bir değer alması gerekmiyor. Örneğin verilen sayının asallığını test eden bir fonksiyon yazsaydık, bir değişken almamız gerekirdi. Ancak bu örnekte gördüğümüz kat_ciz( ); fonksiyonu, dışardan bir değere gerek duymaz. Eğer bir fonksiyon, çalışmak için dışardan gelecek bir değere ihtiyaç duymuyorsa, fonksiyon adını yazdıktan sonra parantez içini boş bırakabiliriz. Ya da void yazarak, fonksiyonun bir değer almayacağını belirtiriz. ( Sürekli olarak main( ) fonksiyonuna void koymamızın sebebi de bundandır; fonksiyon argüman almaz. ) İkinci yöntem daha uygun olmakla birlikte, birinci yöntemi kullanmanın bir mahsuru yok. Aşağıda bulunan iki fonksiyon //aynı şekilde çalışır:
// Evin katini cizen fonksiyon.
// void var
void kat_ciz( void )
{
cout <<( "| |\n" )<<endl;
cout <<( "| |\n" )<<endl;
cout <<( "| |\n" )<<endl;
cout <<( "----------\n" )<<endl;
}
// Evin katini cizen fonksiyon.
// void yok
void kat_ciz( )
{
cout <<( "| |\n" )<<endl;
cout <<( "| |\n" )<<endl;
cout <<( "| |\n" )<<endl;
cout <<( "----------\n" )<<endl;
}
void ifadesinin, değer alınmayacağını göstermek için kullanıldığını gördünüz. Bir de fonksiyonun değer döndürme durumu vardır. Yazdığınız fonksiyon yapacağı işlemler sonucunda, çağrıldığı noktaya bir değer gönderebilir. Değer döndürme konusunu, daha sonra işleyeceğiz. Şimdilik değer döndürmeme durumuna bakalım.
Yukarda kullanılan fonksiyonlar, geriye bir değer döndürmemektedir. Bir fonksiyonun geriye değer döndürmeyeceğini belirtmek için, void ifadesini fonksiyon adından önce yazarız. Böyleyece geriye bir değer dönmeyeceği belirtilir.
Argüman Aktarımı
Daha önce ki örneklerimiz de, fonksiyonlar dışardan değer almıyordu. Bu yüzden parantez içlerini boş bırakmayı ya da void ifadesini kullanmayı görmüştük. Her zaman böyle olması gerekmez; fonksiyonlar dışardan değer alabilirler.
Fonksiyonu tanımlarken, fonksiyona nasıl bir değerin gönderileceğini belirtiriz. Gönderilecek değerin hangi değişken tipinde olduğunu ve değişken adını yazarız. Fonksiyonu tanımlarken, yazdığımız bu değişkenlere 'parametre' (parameter) denir. Argüman (argument) ise, parametrelere değer atamasında kullandığımız değerlerdir. Biraz karmaşık mı geldi? O zaman bir örnekle açıklayalım.
Daha önce çizdiğimiz ev örneğini biraz geliştirelim. Bu sefer, evin duvarları düz çizgi olmasın; kullanıcı istediği karakterlerle, evin duvarlarını çizdirsin.
/* Ev sekli cizen program */
#include<iostream.h>
// Evin catisini cizen fonksiyon.
void catiyi_ciz( void )
{
cout << " /\\ \n" ;
cout << " / \\ \n" ;
cout << " / \\ \n" ;
cout << " / \\\n" ;
cout << "----------\n" ;
}
// Evin katini cizen fonksiyon.
// sol ve sag degiskenleri fonksiyon
// parametreleridir.
void kat_ciz( char sol,char sag )
{
cout << sol<< sag << endl;
cout << sol<< sag << endl;
cout << sol<< sag << endl;
cout << "----------\n" ;
}
// Programin calismasini saglayan
// ana fonksiyon.
main()
{
char sol;
char sag;
cout << "Kullanılacak karakterler> " << endl;
cin >> sol >>sag;
getchar ();
catiyi_ciz( );
// sol_duvar ve sag_duvar, fonksiyona
// giden argumanlardir.
kat_ciz( sol, sag) ;
getchar ();
return 0;
}
Argümanların değer olduğunu unutmamak gerekiyor. Yukardaki örneğimizden, değişken olması gerektiği yanılgısına düşebilirsiniz. Ancak bir fonksiyona değer aktarırken, direkt olarak değeri de yazabilirsiniz. Programı değiştirip, sol_duvar ve sag_duvar değişkenleri yerine, '*' simgesini koyun. Şeklin duvarları, yıldız işaretinden oluşacaktır.
Yazdığımız kat_ciz( ) fonksiyonunu incelemek için, aşağıda bulunan grafiğe göz atabilirsiniz:
[Void Function Structure]
Şimdi de başka bir örnek yapalım ve verilen herhangi bir sayının tek mi yoksa çift mi olduğuna karar veren bir fonksiyon oluşturalım:
/* Sayının tek veya çift olmasını
kontrol eder. */
#include<iostream.h>
[IMG]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif[/IMG][IMG]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image002.gif[/IMG]void tek_mi_cift_mi( int sayi )
{
if( sayi%2 == 0 )
cout << ( "çift bir sayıdır.\n", sayi );
else
cout << ("tek bir sayıdır.\n", sayi );
getchar ();
}
main()
{
[IMG]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image003.gif[/IMG]int voidParametresineIntileGirilenSayi;
[IMG]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image004.gif[/IMG]cout << ( "Lütfen bir sayı giriniz> " );
[IMG]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image005.gif[/IMG]cin >> voidParametresineIntileGirilenSayi;
getchar ();
tek_mi_cift_mi(voidParametresineIntileGirilenSayi);
getchar();
return 0;
}
Yerel ( Local ) ve Global Değişkenler
Kendi oluşturacağınız fonksiyon içersinde, main( ) fonksiyonunda ki her şeyi yapabilirsiniz. Değişken tanımlayabilir, fonksiyon içinden başka fonksiyonları çağırabilir veya dilediğiniz operatörü kullanabilirsiniz. Ancak değişken tanımlamalarıyla ilgili göz ardı etmememiz gereken bir konu bulunuyor. Bir fonksiyon içersinde tanımladığınız değişkenler, sadece o fonksiyon içersinde tanımlıdır. main( ) veya kendinize ait fonksiyonlardan bu değişkenlere ulaşmamız mümkün değildir. main( ) içinde tanımladığınız a isimli değişkenle, kendinize özgü tanımladığınız kup_hesapla( ) içersinde tanımlanmış a isimli değişken, bellekte farklı adresleri işaret eder. Dolayısıyla değişkenlerin arasında hiçbir ilişki yoktur. kup_hesapla( ) içersinde geçen a değişkeninde yapacağınız değişiklik, main( ) fonksiyonundakini etkilemez. Keza, tersi de geçerlidir. Şu ana kadar yaptığımız bütün örneklerde, değişkenleri yerel olarak tanımladığımızı belirtelim.
Yerel değişken dışında, bir de global değişken tipi bulunur. Programın herhangi bir noktasından erişebileceğiniz ve nerede olursa olsun aynı bellek adresini işaret eden değişkenler, global değişkenlerdir. Hep aynı bellek adresi söz konusu olduğun için, programın herhangi bir noktasında yapacağınız değişiklik, global değişkenin geçtiği bütün yerleri etkiler. Aşağıdaki örneği inceleyelim:
#include<iostream.h>
// Verilen sayinin karesini hesaplar
void kare_hesapla( int sayi )
{
// kare_hesapla fonksiyonunda
// a degiskeni tanimliyoruz.
int a;
a = sayi * sayi;
cout << "Sayinin karesi:"<< a << endl;
getchar ();
}
// Verilen sayinin kupunu hesaplar
void kup_hesapla( int sayi )
{
// kup_hesapla fonksiyonunda
// a degiskeni tanimliyoruz.
int a;
a = sayi * sayi * sayi;
cout <<"Sayinin kupu:" << a << endl;
getchar ();
}
int main( void )
{
// main( ) fonksiyonunda
// a degiskeni tanimliyoruz.
int a;
cout << "Sayı giriniz:"<< endl;
cin >>a ;
cout << "Girdiğiniz sayi:" << a << endl;
getchar ();
kare_hesapla( a );
// Eger a degiskeni lokal olmasaydi,
// kare_hesapla fonksiyonundan sonra,
// a'nin degeri bozulur ve kup yanlis
// hesaplanirdi.
kup_hesapla( a );
getchar ();
return 0;
}
Kod arasına konulan yorumlarda görebileceğiniz gibi, değişkenler lokal olarak tanımlanmasa, a'nin değeri farklı olurdu. Sayının karesini bulduktan sonra, küpünü yanlış hesaplardık. Değişkenler lokal olduğu için, her aşamada farklı bir değişken tanımlandı ve sorun çıkartacak bir durum olmadı. Benzer bir programı global değişkenler için inceleyelim:
#include<iostream.h>
int sonuc = 0;
// Verilen sayinin karesini hesaplayip,
// global 'sonuc' degiskenine yazar.
void kare_hesapla( int sayi )
{
sonuc = sayi * sayi;
}
main()
{
// main( ) fonksiyonunda
// a degiskeni tanimliyoruz.
int a;
cout << "Sayı giriniz> " << endl;
cin >> a;
cout << "Girdiğiniz sayı\t:"<< a << endl ;
getchar ();
kare_hesapla( a );
cout << "Sayının karesi\t: "<< sonuc << endl ;
getchar ();
return 0;
}
Gördüğünüz gibi, sonuc isimli değişken her iki fonksiyonun dışında bir alanda, programın en başında tanımlanıyor. Bu sayede, fonksiyon bağımsız bir değişken elde ediyoruz.
Global değişkenlerle ilgili dikkat etmemiz gereken bir iki ufak nokta bulunuyor: Global bir değişkeni fonksiyonların dışında bir alanda tanımlarız. Tanımladığımız noktanın altında kalan bütün fonksiyonlar, bu değişkeni tanır. Fakat tanımlanma noktasının üstünde kalan fonksiyonlar, değişkeni görmez. Bu yüzden, bütün programda geçerli olacak gerçek anlamda global bir değişken istiyorsanız, #include ifadelerinin ardından tanımlamayı yapmanız gerekir. Aynı ismi taşıyan yerel ve global değişkenleri aynı anda kullanıyorsak, iş birazcık farklılaşır.
Bir fonksiyon içersinde, Global değişkenle aynı isimde, yerel bir değişken bulunduruyorsanız, bu durumda lokal değişkenle işlem yapılır. Açıkcası, sınırsız sayıda değişken ismi vermek mümkünken, global değişkenle aynı adı vermenin uygun olduğunu düşünmüyorum. Program akışını takip etmeyi zorlaştıracağından, ortak isimlerden kaçınmak daha akıllıca.
Lokal ve global değişkenlere dair son bir not; lokal değişkenlerin sadece fonksiyona özgü olması gerekmez. Bir fonksiyon içersinde 'daha lokal' değişkenleri tanımlayabilirsiniz. Internet'te bulduğum aşağıdaki programı incelerseniz, konuyu anlamanız açısından yardımcı olacaktır.
#include<iostream.h>
main()
{
int i = 4;
int j = 10;
i++;
if( j > 0 ){
cout <<i <<endl; /* 'main' icinde tanımlanmis 'i' degiskeni */
}
if (j > 0){
int i=100; /* 'i' sadece bu if blogunda gecerli
olmak uzere tanimlaniyor. */
cout <<i <<endl;
} /* if blogunda tanimlanan ve 100 degerini
tasiyan 'i' degiskeni burada sonlaniyor. */
cout <<i <<endl; /* En basta tanimlanan ve 5 degerini tasiyan
'i' degiskenine donuyoruz */
getchar ();
}
ORNEK FONKSİYONLAR:
#include <iostream.h>
// Verilen olculere gore, dortgen cizer
void dortgen_ciz( int en, int boy )
{
int i, j;
for( i = 0; i < boy; i++)
{
for( j = 0; j < en; j++ )
{
cout << ".";
}
cout << "\n";
getchar ();
}
}
int main (void)
{
int en;
int boy;
cout<< "en gir"<<endl;
cin >>en ;
cout << "boy gir"<<endl;
cin >> boy;
dortgen_ciz(en,boy);
getchar ();
return 0;
}
Fonksiyonlar (Profesör anlatımıylaJ)
Bundan sonraki bölümlerdeki kullanacagimiz derleyici Borland Turbo C++ 4.5 tir. Fazla zorlanmayacaginizi umut ediyorum. Kolay anladiginiz yerlere lütfen dikkat ediniz. Hata yapma olasiliginiz daha da çok artmaktadir. Yapacaginiz hatalar programin çökmesine, belki de sistemin zarar görmesine sebep olabilir. Lütfen vermis oldugum uyarilara ve tavsiyelere uymaya çalisin. Sizin de tavsiyeniz olursa bana bildiriniz[IMG]http://www.************/images/smilies/smile.gif[/IMG]. Haydi kolay gelsin...
1. Fonksiyonlara Giris:
Fonksiyonlarin programlama hayatina girmesi ile daha büyük boyutta sistemlerin tasarimi mümkün hale gelmistir. Fonksiyonlar ile alakali derslerimizde, fonksiyonlarin tanimlanmasi ve kullanimi hakkinda bilgi edineceksiniz. Fonksiyonlar konusu size her ne kadar ilk bakista "Fonksiyon" adi altinda bir konu gibi gelse de, aslinda bir alt programdir. Hatta programimizin içine, kodlamamizin daha kolay ve gelistirilebilir hale gelmesini saglayan programciklar da diyebiliriz.
Daha önce baska bir programlama dili gördüyseniz (yüksek seviyeli diller), bu konuda fazla zorlanmayacaksinizdir. Diger yüksek seviyeli dillerdeki fonksiyon kullanimina çok benzemektedir. Hiç bilmediginizi farz ederek konuya giris yapalim.
2. Fonksiyon Nedir? Örnegin, y=F(x) fonksiyonu; Bu matematiksel fonksiyon parametre olarak aldinan deger üzerinde bir islem gerçeklestirip, bir sonuç degerini döndürür. Mesela F(x)=x^3+5 seklinde bir fonksiyonumuz olsun, x=2 için F(x)=13 olur. Burada x fonksiyonun parametresi, 13 ise fonksiyonun geri döndürdügü degerdir. Simdi de bu matematiksel ifadeyi kodlarimizla yorumlayalim.
Int x;
x=F(2,5)
//buradan da " int f(2,5) " gibi görebiliriz... Dikkat edersek ikinci satirda, daha önce islemedigimiz bir kod var. Int x, F(2,5) degerine esitlenmistir. Simdi bir fonksiyonun nasil yazildiginin kalibini çikartabiliriz.
3. <Döndürdügü deger> <Fonksiyonun adi> ( <parametre listesi> ) {
<ifadeler>
} Buradaki parantezlere ve küme isaretlerine dikkat ediniz. Simdi yukarda yazdigimiz kalibi biraz açalim.
<Döndürdügü deger> : Fonksiyon her hangi bir tipte deger döndürebilir. Bu bilesen fonksiyonun döndürecegi degerin tipini ifade eder. (örnegin, int, double, float v.s v.s )
4. <Fonksiyonun adi> : Yapmak istedigimiz islemin adidir. Örnegin bir asal sayi fonksiyonu yazacagiz. Burada yazacagimiz fonksiyonun adini belirtiyoruz. Benim size tavsiyem AsalSayi veya asal_sayi seklinde kullanmanizdir. Okunabilirlik açisindan size avantaj saglayacaktir.
5. <parametre listesi> : Fonksiyonun kullanacaga parametrelerin tipleri ile siralanir. Örnegin, FonksiyonAdi(int x, double y) gibi.
6. <ifadeler> : Fonksiyonun kullanacagi tanimlamalar ve kodlardan olusan kisimdir. Nasil biz main() { kodlar } seklinde kullaniyorsak. Bunu da ona benzetebiliriz. Ama main() i bunlarla karistirmayiniz.
Simdi bu fonksiyon kalibina uygun bir kod yazalim. Örnegin, Faktoriyel bulma islemini ele alalim. Biz bir sayinin Faktörüyelini nasil bulurduk?
7.
n!=n(n-1)(n-2)...1 Yani, 1 den n e kadar olan sayilarin çarpimidir.
long Faktoriyel(int n) {
return n*Faktoriyel(n-1);
} Evet, burada fonksiyonumuzu tanimladik. Sanirim yukaridaki blokla karsilastirinca, ne kadar kolay oldugunu sizde görmüssünüzdür. Simdi bu Faktoriyel fonksiyonumuzu nasil bir programda kullanacagiz? Hemen devamini yazayim.
long Faktoriyel(int n) {
return n*Faktoriyel(n-1);
}
void main() {
cout<<"5! (Bes Faktoriyel)= "<<Faktoriyel(5);
} Iste gördügünüz gibi ne kadar basit degil mi? J Fonksiyonumuzu tanimladik. Sonra programimizda n`e 5 degerini verdik. Faktoriyel fonksiyonu hesaplayip bize söyledi.
Biraz da yaygın yapılan hatalardan ve dikkat etmemiz gereken noktalardan bahsedelim. Kodlama yaparken fonksiyon adini belirttigim sekilde yazarsaniz 30-40 sayfalik kodlarda hata bulmaniz ve de fonksiyonlarin yerini belirlemeniz açisindan büyük kolaylik olucaktir. Yukarida verdigimiz x=F(2,5) fonksiyonununu göz önünde tutalim. Görüldügü gibi F(2,5) degeri x e atanmistir. Hiç bir zaman Fonksiyonun aldigi deger sola yazilmaz. Ayrica bir Fonksiyon çagrisi, baska bir fonksiyonun çagrisi olabilir. Örnegin, x=F(a,F(a,5) gibi. Burada F Fonksiyonun iki parametresi vardir a ve F(a,5) dir. Bu durumda öncelikle parametreler hesaplananacagi için F(a,5) in degeri ile a nin degeri F te parametreler olarak kullanilir.
Tanımlayıcının Görünürlüğünün Kontrolü ve Kendini Çağıran Fonksiyonlar
2. Tanımlayıcının Görünürlüğünün Kontrolü ve Kendini Çağıran Fonksiyonlar
Bir değişkenin görünürlüğü değişkenin etki dizinini gösterir. Bir yerel değişken, tamamen, bir fonksiyon içinde kullanılır. Onun görünürlüğü fonksiyonun içi ile sınırlıdır. Değişkenin görünürlüğü ve ulaşılabilirliğinden sadece fonksiyonun içinde bahsedilebilir. Buna "Scope Kuralları" da denir. Şimdi bunu bir örnek ile izah edelim;
#include <iostream.h>
void main(){
int i=5;
{
int i=1;
cout<<"İçerideki i: "<<i<<endl;
cout<<"Dışarıdaki i: "<<::i<<endl;
}
} Görüldüğü gibi İçerdeki i:1, Dışarıdaki i:5 şeklinde bir çıktı verecektir. Main ide bir fonksiyon gibi görürsek (gerçi özel bir fonksiyondur), denilmek isteneni anlayacaksınızdır.
Kendini tekrarlama, bir fonksiyon kendini çağırdığında oluşur. Başlangıçta bu sonsuz döngü gibi gözükür, ancak öyle değildir. C++ kendini çağırmayı destekler. Bunu bir fonksiyonun döndürdüğü değeri bulabilmesi için içindeki bir parametrenin de fonksiyon olması gibi değerlendirebiliriz. Hani başta vermiştik ya: F(x,F(x,y) gibi...
İnline Fonksiyonlar
3. İnline Fonksiyonlar
C++ `ın C ye ek olarak getirmiş olduğu bir özellikte inline fonksiyonlardır. Anlamak için basit bir örnekle başlayalım. Örneğin öyle bir program yazıcağız ki, aşırı miktarda kare alma işlemi yapmamız gerekecek ve bunun için herhangi bir fonksiyon çağırmıyor olalım. Bu durumda define komutu ile derleyiciye şu şekilde bir komut veririz:
#define kare(x) x*x İşlemin sonunda ; olmamasına dikkat ediniz. Kullanımına gelince de,
y=kare(x); bu durumda derleyici derleme aşamasında bütün kare(x) `leri x*x olarak yorumlayacaktır. Burada dikkat edilmesi gereken yer, #define topla(x,y) x+y ve kullanımda da z=topla(x,y)*topla(x,y); işte işlem sırasının vermiş olduğu hatayı görüyorsunuzdur. Tabi bunu da parantezlerle ayıracağız. Şimdi bunu C++ tam uyarlarsak, inline kelimesini, bir direktif olarak yada C++ derleyicisine fonksiyonu tek satıra koyması önerisi olarak düşünebiliriz. Derleyici bir çok nedenden dolayı bunu kabul etmeyebilir. Mesela, Fonksiyon çok uzun olabilir, Döngü içeren bir fonksiyon, değişken tanımı içeren bir fonksiyon, kendini çağıran bir fonksiyon her zaman inline olmaz.
//kup.cpp
//Kupun hacmini bulma
#include <iostream.h>
//inline fonksiyonumuz
//------------------
inline double kup( const double x)
{
return x * x * x;
}
//---------------------
int main()
{
cout << "Kübün bir kenar uzunluğunu giriniz: ";
double kenar;
cin >> kenar;
cout << "Kenar" << kenar << "olan kübün hacmi = "
<< kup (kenar) << endl;
return 0;
}
Fonksiyon Yüklemesi ve Prototipleri
4. Fonksiyon Yüklemesi ve Prototipleri
Şimdi C++ `ın getirmiş olduğu başka bir özellikten daha bahsedeceğiz. Aynı isimli fonksiyonların farklı işlemler yapabilmesi. Aynı şekilde çağrılacaklardır, fakat derleyici bunların farklı fonksiyonlar olduğunu anlayacaktır. Tabi bunun şartları var. Fonksiyonların tipleri yada bunların sıraları farklı olmalıdır. Fonksiyonların başında kalıbın tanımını yaparken, parametre listesinden bahsetmiştik. Bu parametreler belli değerler döndürürler, işte derleyicide bu döndürdüğü değerlere yani imzalarına göre bunların farklı fonksiyonlar olduğunu anlayacaktır. Tabi bunların sıraları da farklı fonksiyonlar gibi gözükmelerini sağlayacaktır. Hemen olayı anlamak için örnek verelim.
double Ortalama(int *dizi, int uzunluk){
//kodlar
}
double Ortalama(double*dizi, int uzunluk){
//kodlar
}
Görüldüğü gibi bu iki fonksiyon da bir birinden farklıdır. Her ne kadar isimleri aynı olsa da...
Fonksiyon tanımlamasının fonksiyon kullanılmadan önce yapılmış olması gerekmektedir. Fonksiyonlarımızı header başlığı altından çağırabiliriz. Mesela ben daha önce bir Faktoriyel fonksiyonu yazip bunu Fakt.h olarak saklıyorum. Programımı yazarken #include <Fakt.h> diyerek bunu çağırıyorum ve programda yazdığım "5'in faktoriyelini al" dediğim zaman direk Fakt.h taki fonksiyonda işlemi yapıp aldığı değeri programa verir. Mümkün olduğunda C++ ın kendi kütüphanelerindeki hazır fonksiyonları kullanmaya çalışacağız. Var olan bir fonksiyonu yeniden yazmanın pek bir anlamı olmaz. İleride kütüphanelerdeki fonksiyonları da mümkün olduğunca göreceğiz.
Fonksiyonları Referans ile Çağırma
5. Fonksiyonları Referans ile Çağırma
Daha önceki örneklerimizde fonksiyona parametre olarak geçilen bir değer olarak çağırmıştık. Şimdi ise onu referanslar ile çağıracağız. Bunu çok uzatmadan direk örnek üzerinde anlatalım.
//referans.cpp
//fonksiyonlarda referans
#include <iostream.h>
void deneme(int &x, int &y);
int main()
{
int x,y;
cout<<" iki sayı giriniz:";
cin>>x>>y;
cout << "Denemeden önceki:\n";
cout << "X: " << x << endl;
cout << "Y: " << y << endl;
deneme(x, y);
cout << "\nDenemeden sonraki:\n";
cout << "X: " << x << endl;
cout << "Y: " << y << endl;
return 0;
}
void deneme(int &x, int &y)
{
int deger = x;
x = y;
y = deger;
}
Bu algoritmayı bir de şöyle görelim:
//referans.cpp
//fonksiyonlarda referans
#include <iostream.h>
void deneme(int &mavi, int &kirmizi);
int main()
{
int mavi,kirmizi;
cout<<" iki sayı giriniz:" << endl;
cin>>mavi>>kirmizi;
cout << "Denemeden önceki" << endl;
cout << "mavi: " << mavi << endl;
cout << "kirmizi: " <<kirmizi << endl;
deneme(mavi, kirmizi);
cout << "Denemeden sonraki" << endl;
cout << "mavi: " << mavi << endl;
cout << "kirmizi: " << kirmizi << endl;
getchar ();
return 0;
}
void deneme(int &mavi, int &kirmizi)
{
int deger = mavi;
mavi = kirmizi;
kirmizi = deger;
getchar ();
}
Referans parametresi (&) dir. Bu sayede fonksiyona argüman yerine o argümanın adresini yolluyoruz. Fonksiyon bu sefer verdiğimiz değere, o adresi kullanarak ulaşır. Bu çok yüksek değerleri fonksiyona gönderdiğimizde kullanacağımız yöntem olmalıdır.
Void Tipi ve Main() Fonksiyonu
6. Void Tipi ve Main() Fonksiyonu
Öncelikle void tipinden bahsedelim, aslında buna tam olarak tip de diyemeyiz. Bir nevi "tipimsi" olarak adlandırabiliriz. Daha önce çoğu programımızda void i kullandık. Fakat ne işe yaradığından pek bahsetmemiştik. Derleyici genelde void i bir tipe ait bir değer olarak görür fakat, void bir tip olmadığından dolayı döndürülemez.
Void x: //bu hatalıdır
Void fonksiyon(); // Şayet fonksiyon geri değer döndürmüyorsa kullanılır
Void *isaretci; //isaretci nesnesi herhangi bir tipe sahip değilse bunu kullanır.
//Burda geri değer döndürmeyen bir fonksiyonu ele alıyoruz. void EkranaYaz(void) {
cout<<"Ekran çıktısı";
}
main() {
EkranaYaz();
return 0;
} Burada EkranaYaz fonksiyonumuzun bir parametresi yoktur, bunu derleyiciye void olarak belirttik ve bir değer döndürmedik. Bunun içindir ki zaten return ifadesini kullanmadık (fonksiyonun içinde). Fakat bazı fonksiyonlarda return`ü kullanabilir, bu return ifadesi de işlevi sonlandırmak amacı taşır.
Main() Fonksiyonu ve Bilgi Geçilmesi:
Main() fonksiyonumuz diğer fonksiyonlardan biraz daha özel bir yapıya sahiptir. İçine bazı özel parametreler alır. Bunlar argc, agrv[], getenv[] adındadır. Bunların yanında env[] parametresi de bulunmaktadır, fakat biz tercihen getenv[] yi kullanacağız. Şimdi main() in parametreler almış halini yazalım.
Main( int agrc, char* agrv[], char* getenv[]) {
//kodlar
} Şeklindedir. Şimdi bunu bir örnek ile pekiştirelim:
#include <iostream.h>
main(int argc, char *argval[],char *getenv[])
{
int i = 0;
while (getenv[i])
{
cout << getenv[i++]<<endl;
}
} Burada main() fonksiyonu içinde agrc girilen parametre sayısını, agrv girilen parametrede tutulan sözcüklerin sayısını tutmaktadır. getenv de işletim sisteminin belli değişkenlerini tutar.
Dizilere Giriş
1. Dizilere Giriş
Diziler, "indisleri olan değişkenler" olarak adlandırılırlar. Diğer bir deyişle, birden fazla tek düze veri tipi içeren değişkenlerdir. Diziler birbirine bitişik bellek gözleri kullanılarak oluşturulurlar. Bunu biraz daha açarsak: farz edelim ki elimizde üç tane kutu var, birinde yeşil kalemler, birinde kırmızı kalemler ve birinde de mavi kalemler olsun. Bu kutucukları 1,2,3 diye adlandırdığımızı düşünelim. Biz diziler ile numarasını bildiğimiz kutucuğun içindeki malzemeyi alabileceğiz. Daha doğrusu numarasını vermiş olduğumuz kutunun içindeki bilgiyi bilgisayar okuyacaktır.
Not: For döngüsü dizi elemanlarına ulaşmak için en çok kullanılan yöntemdir.
Dizilerin indislerden oluştuğunu söylemiştik. Diğer yüksek seviyeli dillerle karşılaştırıldığında arasındaki fark ilk elemanın indisi daima sıfır (0) olmasıdır.
for(int i=0; i<boyut; i++) Burada dikkat etmek istediğimiz "int i=0" kısmıdır. Görüldüğü gibi indisin ilk aldığı değeri sıfır (0)`dan başlatıyoruz. Bu kısmı unutmayınız. Genellikle yapılan en büyük hatalardan biridir.
Bir dizi tanımlayıcısı -adı-, dizinin ilk elemanının adresini tanımlayan adrestir. Bunu şöyle izah edelim; elimizde bir dizi var ve ilk elemanı karakter ise biz "char DiziAdi[boyut]" şeklinde tanımlarız. Tam sayı ise "int DiziAdi[boyut]" şeklinde olur.
Dikkat edilmesi gereken diğer bir konu da: dizi adı hiçbir zaman (=) işaretinin solunda bulunmaz. Bu yukarıda söylediklerimi anlamamış olabilirsiniz. Onun için alt kısmı okuyup bir daha tekrar etmenizi tavsiye ederim.
Dizilerin Tanımlanması ve Değer Atama
2. Dizilerin Tanimlanmasi ve Deger Atama
Int a[10]; Seklinde bir diziyi tanimlayabiliriz. Bunu daha genel bir kaliba dökersek.
<tip> <dizi adi> [<boyut>]; halini alir. Birde boyutlarinin arttirilmis halini verelim.
<tip> <dizi adi> [<boyut1>][<boyut2>][<boyut3>]....[<boyutn>]; n boyutlu dizi[IMG]http://www.************/images/smilies/smile.gif[/IMG].
<tip>: Yukarida söylemis oldugumuz "int DiziAdi[boyut]" olayidir.
<dizi adi>: Kurallara uygun herhangi bir isim olabilir. Genellikle dizilerinizin amacina uygun isimler kullaniniz.
[<boyut>]: Dizinin kaç eleman içerdigini gösterir. 5 elemanli ise [5] seklinde yazariz.
Basta " int a[10]; " almistik. Simdi bunu degisik bir formda yazalim
const int boyut=10;
Int a[boyut]; Önce boyut adinda bir sabiti tanimladik ve deger atadik sonrada bunu dizi içine çagirdik.
Dizilere Deger atama:
Bu yöntemleri madde madde verelim,
1. Duragan ve global (erisilen) dizilerde yaratildiklari anda içerik otomatik olarak belirlenebilir. Programin taniminda erisilen tüm degiskenler, otomatik olarak sifir yapilir.
2. Duyuru sirasinda sabit degerler belirtilerek belirlenebilir.
3. Programin çalismasi sirasinda indisler kullanilarak her elemana tek tek veri kopyalanabilir.
1. maddenin örnegi
#include <iostream.h>
const int boyut=5;
int GlobalDizi[boyut];
main() {
//"satatic" yerel degiskende tanimlanmasina ragmen tüm program boyunca
//geçerlidir. Ancak sadece tanimlandigi fonksiyon tarafindan erisilebilir.
static int DuraganDizi[boyut];
for(int i=0; i<boyut;i++)
cout<<GlobalDizi[i];
return 0;
} Programin çiktisinada göreceginiz gibi, dizi aratilirken indislere ait eleman bloklari temizlenmis ve sifir degerlerini almistir.
Burada bir konuya daha dikkat çekmek istiyorum. Çok yaptigimiz hatalardan biri olarak da, dizi duyurusunu yaparken belirttigimiz degerden fazla sayida deger girmemizdir.
int DiziAdi[5]={1,8,9,5,4,6};Görmüs oldugunuz gibi bes tane dedik ama alti tane yazdik. !!! hata !!!. Bu tür hatalar için elimizde kullanabilecegimiz bir kalip var.
char DiskOkunmuyor[ ] = "Disk okunmuyor";
char DosyaYok[ ]= "Dosya Yok"; Bunu yaptigimizda derleyici, tüm degerleri içerebilecek en büyük diziyi olusturur.
#include<iostream.h>
main()
{
// Aylari temsil etmesi icin
// aylar adinda 12 elemanli
// bir dizi olusturuyoruz.
//PROGRAMIN BIRINCI YARISI - PROGRAM BASLANGICI - BILGI GIRISI
int aylar[12];
int toplam=0;
int i;
for (i=0;i<12;i++){
cout <<(i+1)<<":";/*ekranda for da tanımlanan koşul sayısınca ve dizide
tanımlanan eleman sayısınca bilgi girişi kabul edecek for da 0 (sıfır) olan
"i" ye 1 ekleyerek dizilere bilgi girişi için ekrana mesaj yazar.*/
cin >> aylar[i]; //int te tanımlanan dizi için klavyeden veri gerişi istenecek
}
//PROGRAMIN IKINCI YARISI- ISLEM
cout <<" \n\n GIRDIGINIZ DEGERLER:\n\n"; //Girilen degerler icin genel baslik
for (i=0;i<12;i++){ /* Yukarıdaki blokta girilen değerleri göstermek için ikinci bir döngü
kuruyoruz girilen dizi değerlerini çekip toplamak için*/
cout <<"Girdiginiz deger:\n"<< (i+1)<< aylar[i]<<endl; /*Girilen degerler 1
arttırılıp girilen diziler ekrana yazılacak*/
toplam += aylar[i]; //diziye girilen degerleri toplar
getchar (); //programın kapanmasını önler
}
cout << "Toplam güneşli gün sayısı: "<< toplam <<endl; //toplamı ekrana yazar
getchar ();
return 0; //programın sonlar
}
Dizi Boylarının Dinamik Hesaplanması
3. Dizi Boylarının Dinamik Hesaplanması "sizeof()"
sizeof() fonksiyonu, nesne için bellekte gerekli olan byte`ların sayısını belirtir. Sizeof() fonksiyonu dizilerde kullanılabilir.
#include <iostream.h>
void main() {
int a[5];
float b[10];
cout<<"dizinin boyutu: "<<sizeof(a)<<'\n';
cout<<"dizinin boyutu: "<<sizeof(b);
} Evet burda da görmüş olduğumuz gibi dizinin bellekte kaplayacağı byte`ları hesapladı.
Birde bu konuyla beraber "&" operatörünün bir dizi bile olsa değişkene nasıl uygulandığını görebiliriz.
#include <iostream.h>
void main() {
int a[10];
cout<<"sizeof(int) is"<<sizeof(int)<<endl;
for(int c=0; c<10; c++)
cout<<"&a["<<c<<"]="<<&a[c]<<endl;
} Programı derledikten sonra "sizeof(int) is 2 ya da sizeof(int) is 4" diyecektir. Bu değişiklik int in mikroişlemcilere bağlı olarak 2 veya 4 byte olabilmesinden kaynaklanmaktadır.
Diziler ve Sözcükler (strings)
4. Diziler ve Sözcükler (strings)
C++ da sözcükler için farklı bir tip yoktur. Sözcükler ile ilgili işlemler diziler yardımı ile kolaylıkla yapılabilir. Dikkat edilmesi gereken bir kural vardır. Sözcüklerin (strings) son elemanları "\0" değerini alır (null terminator). Burdan da anlayacağımız gibi son karakter boş dizgiyi belirtiyorsa stringtir. Şuna da dikkat edilmelidir ki string sabitlerinin sonuna "\0" koymamıza gerek yoktur. Derleyici bunu otomatik olarak yapacaktır.
Char sozcuk[7]="Deneme";
Char sozcuk[7]='D', 'e', 'n', 'e', 'm', 'e', '\0'}; Bu dizilerin içerikleri tamamen aynıdır. Hazır söz gelmişken şuna da değinelim. '\n', '\t', '\0' v.s, bunlar birer karakter olarak okunur. Ben önceleri iki diye okurdum[IMG]http://www.************/images/smilies/smile.gif[/IMG]
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string Cevap = "";
cout << "Hazirmisin?";
cin >> Cevap;
if( ( Cevap == "evet" ) || ( Cevap == "Evet" ))
{
cout << "Ee Tamam... ne gec ti eline?[IMG]http://www.************/images/smilies/smile.gif[/IMG] " << endl;
}
else
{
cout << "Zorlamaya devam et!" << endl;
}
cout << "Hazirmisin? " << endl;
cin >> Cevap;
if( ( Cevap[0] == 'e' ) || ( Cevap[0] == 'E' ) )
{
cout << "Ee Tamam... ne geçti eline?[IMG]http://www.************/images/smilies/smile.gif[/IMG]" << endl;
}
else
{
cout << "Zorlamaya devam et!" << endl;
}
system("pause");
return 0;
} Bu, sanırım bu konudaki en zor örneğimiz. Şimdi örnek üzerinde biraz konuyu konuşmaya devam edelim. Zaten diğer if, else bloklarından ve cout, cin gibi komutlardan bahsetmeyeceğim. string Cevap = ""; bir sabitimizle işleme başladık. if( ( Cevap[0] == 'e' ) || ( Cevap[0] == 'E' ) ) burası sanırım tanıdık geldi[IMG]http://www.************/images/smilies/smile.gif[/IMG] Evet şimdi burda Cevap[1] i çağırmış olsaydık 'v' veya 'V' değerlerini alıcaktık. Tabi burada index değerinin yani dizideki ilk değerin 0 ile başladığını bir daha gördük. Şimdi bu örnekle alakalı olarak da Diziler ve Fonksiyonlar konusuna geçelim....
Diziler ve Fonksiyonlar
5. Diziler ve Fonksiyonlar
Öncelikle dizilerin fonksiyonlara gönderilmesi ile başlayalım. Dizilerde değişken önüne adres operatörünün gelmesine gerek yoktur. Nedeni ise dizi isminin zaten bir adres olmasıdır.
İnt dizi[10]; bir dizimiz olsun biz bunu diziye bir değer olarak göndereceksek,
Fonksiyon(dizi, 10); olarak yaparız. Bir diziyi parametre olarak alacaksak bir fonksiyon, o da void fonksiyon( int dizi[], int 10) şeklinde olur.
Karakter Katarları Fonksiyonları ve Karakter Dizileri
6. Karakter Katarları Fonksiyonları ve Karakter Dizileri
İşte buraya biraz dikkat, kafanız gerçekten karışabilir. Daha doğrusu hangisi hangisiydi diye uğraşır durursunuz[IMG]http://www.************/images/smilies/smile.gif[/IMG]
strlen()
Bu fonksiyon bir karakter dizisinin uzunluğunu verir ve "string.h" kitaplığında tanımlıdır. Strlen() fonksiyonu, sözcükler (strings) bölümünde bahsettiğimiz string ifadeleri okumak için kullanılır. Fakat sondaki "nul terminator" diğer şekliyle '\0' değerini okumaz. Örneğimizde de olduğu gibi "Deneme" ve 'd' 'e' 'n' 'e' 'm' 'e' sözcükler kısmında ki biz buna 7 karakter demiştik, "null" ile birliktedir ama strlen() bunu bize 6 diye okuyacaktır.
int boy = strlen(h);
for (int i = 0; i<=boy; i++)
y[i] = h[i] ; strcpy()
Bu fonksiyonda sözcük kopyalamaya yarar ve "string.h" kitaplığındadır.
#include <iostream.h>
#include <string.h>
#define OTUZ 30
void main(void)
{
char Dosya1[OTUZ]="C:\\belgelerim\\deneme.txt",
Dosya2[OTUZ];
strcpy(Dosya2, Dosya1);
cout<<Dosya2<<endl;
cout<<"\n ikinci dosyayi gir: ";
cin>>Dosya1;
strcpy(Dosya2, Dosya1);
cout<<"\n"<<Dosya2<<"\n";
} strcat()
strcat() fonksiyonu iki karakter katarını bir birine ekler.
strcmp()
İki sözcüğün (iki karakter katarının) aynı olup olmadığını kontrol etmek için kullanılır. Bu fonksiyon büyük/küçük harf duyarlı değildir.
atoi()
Bazen sayıları karakter dizisi olarak okumamız gerekebilir. Ancak esas, bu sayıların sayı değerlerine gereksinmemiz vardır. Atoi fonksiyon, bir karakter dizisini alır ve onu sayıya çevirir.
Örneğin; "123456" dizisini alır 123456 sayısına döndürür.
strstr()
Bunu bir örnekle anlatayım: "C++ dersleri" gibi bir sözcüğümüz var, strstr() fonksiyonu ile bu sözcük içinde "d" harfinin varlığını sorgulayabiliriz.
İşaretçilere Giriş
1. İşaretçilere Giriş
İşaretçiler (Pointers) ve bundan önce görmüş olduğumuz diziler (Arrays) ilerde yapacağımız uygulamalarda kullanımına kesin ihtiyaç duyacağımız başlıklardır. Bunlar bize dinamik bellek kullanımını sağlarlar. Dinamik bellek kullanımından bahsedecek olursak, belleğimizin kutucuklardan oluştuğunu hayal edin. 100 kutucuklu bir belleğimiz var. Bu kutucukların her birinin bir adresi vardır ve biz de bu adresler yolu ile kutucuklara erişiriz. İşte işaretçiler bu erişimi sağlıyor. Bu konuya çalışırken, anlamanın gayet kolay olduğunu göreceksiniz. Fakat ben sizi uyarayım, en kolay konular en çok hata yapılanlardır. İşaretçilerde yapılan hatalar programın hatta sistemin çökmesine sebep olabilir, aynı zamanda yapılan hataları kolay kolay bulamayabilirsiniz. Büyük projelerde bu sizi bayağı sıkıntıya sokacaktır. Onun için işaretçiler konusunda, kullanım tekniği hakkında size sık sık tavsiyelerde bulunacağım.
İşaretçilerin Tanımlanması ve Değer Atanması
Bir işaretçi tipi, hangi tipe işaret ettiğini belirten ve birer adres değeri içeren verilere sahiptir. Bir işaretçi değişken bildirimi, açık olarak hangi tip veriyi kullanacağını bildirerek başlar. Derleyicimizde * işareti ile işaretçi değişkeni tanımladığımızı anlar.
<tip> *<işaretçi adı>; Şeklinde yazılır. Örneğin, int *İsaretciAdi;
Şimdi de aynı satırda birden fazla işaretçi tanımlayalım.
İnt *is1, *is2, *is3; Şeklinde tanımlayabiliriz. Benim size tavsiye ettiğim budur. Fakat farklı bir yol olarak da (İnt *) is1, is2, is3; şeklinde de yazılabiliriz. Burda dikkat etmemiz gereken olay ise, int tipinde işaretçileri tanımlarken herhangi bir değişkende tanımlarsak (int *) şeklinde tek satırda yapmamız hatalıdır.
(İnt *) is1, is2, is3, x=4; //hata
int *is1, *is2, *is3, x=4; //doğru Sanırım ne demek istediğimi anladınız[IMG]http://www.************/images/smilies/smile.gif[/IMG].
Daha önce görmüş olduğumuz "&" adres operatörünü hatırlayalım, kendisisinden sonra gelen ifadenin adresini gösterir.
İnt x;
İnt *is1=&x; x i tanımladık, sonra is1 işaretimize x in adresini atadık. Kısaca is1 in gösterdiği adresteki değer diye biliriz[IMG]http://www.************/images/smilies/smile.gif[/IMG]
#include <iostream.h>
#include <string.h>
int main(void)
{
char *is1="deneme";
int index;
for(index=(strlen(is1)-1); index>=0; index--)
cout<<is1[index]<<endl;
cout<<"\n"<<is1;
return 0;
}
Programın çıktısı
---------
e
m
e
n
e
d
deneme
---------
Burada bir işaretçi değişkenine değer atamayı kullandık, aynı zamanda dizilerde gördüğümüz strlen() fonksiyonun örneğini de yapmış olduk.
İşaretçi İşlemleri ve Dinamik Bellek
2. İşaretçi İşlemleri ve Dinamik Bellek
İşaretçilere daha önce görmüş olduğumuz artırma (++), azalatma (--), çıkarma (-), toplama (+) işlemlerini uygulayabilirsiniz. Bunların yanında ilişkisel operatörleri de ( <=, =, !=, >= ) kullanmanız mümkündür. İlişkisel operatörlerin sadece aynı tip işaretçiler üzerinde uygulanacağını unutmayınız.
Bir dizinin boyutu değişken olabilir, daha dorusu bir program içinde değişkenler ve işaretçiler kullanılarak diziler dinamik bellek yerleşimi ile yapılabilir. C++ da dinamik belleş işlemleri new ve delete komutları ile gerçekleştirilir.
Genel tanımımız: new <tür> [<[uzunluk]>]
new int
new char
new double [10]
new float[n]
new char[strlen(s) + 1] new komutu ile yer tahsis etme işlemi yapmaktayız. new int ->1 int'lik yer tahsis edilmiştir. Şimdide tahsis ettiğimiz yerin serbest bırakılışını ele alalım. Bu sırada da delete komutu devreye giriyor. Daha doğrusu delete operatöürü new operatörüyle tahsis edilmiş olan blokları serbest bırakmak için kullanılır.
Genel tanımımız: Delete[ ] <işaretçiadı>; Eğer yer ayırma işlemi tek parça olarak yapılmışsa (köşeli parantez kullanılmadan yapılmışsa) silme işlemi de köşeli parantez kullanılmadan yapılmalıdır. Bir de şuna dikkat edelim
Delete x+1; //hatalıdır
Delete (x+1); //doğrudur kullanılacaktır. Şimdi bu söylediklerimizi aşağıdaki örnek üstünde uygulayalım.
//dinamik.cpp
//dinamik bellek kavramı
#include <iostream.h>
struct tarih { //struck u daha görmedigimiz
int ay; //icin su an buraya egilmeyin.
int gun;
int yil;
};
void main()
{
int i, *is1, *is2; // i bir sabit ve *is1, *is2 isaretcilerimiz
is1 = &i;
*is1 = 77;
is2 = new int;
*is2 = 178;
cout << "Değerler "<<i<<" "<<*is1<<" "<<*is2<<"\n";
is1 = new int;
is2 = is1;
*is1 = 95454;
cout << "Değerler "<<i<<" "<<*is1<<" "<<*is2<<"\n";
delete is1;
float *float_is1, *float_is2 = new float;
float_is1 = new float;
*float_is2 = 3.14159;
*float_is1 = 2.4 * (*float_is2);
delete float_is2;
delete float_is1;
tarih *tarih_is;
tarih_is = new tarih;
tarih_is->ay = 10;
tarih_is->gun = 18;
tarih_is->yil = 1938;
cout<<tarih_is->ay<<"/"<<tarih_is->gun<<"/"<<tarih_is->yil<<"\n";
delete tarih_is;
char *c_is;
c_is = new char[37];
delete [] c_is;
c_is = new char[sizeof(tarih) + 133];
delete [] c_is;
}
Void İşarerçiler
3. Void İşaretçiler
C++ da tip tanımlamaları fazla güçlü olmadığından bu sorunu işaretçileri void * tipi ile tanımlayarak hallediyoruz. Void tipinde bir işaretçi değişken tipi ile, adresin bulunduğu, ancak henüz tipinin belirlenmediği anlaşılmalıdır. Void i kullanırken dikkat etmemiz gereken kurallardan biri karşımıza bazı kısıtlamalar getirmesidir. Bunlardan söz edecek olursak; void işaretçilerde adres aritmetiği işlemlerini derleyici hata olarak gösterecektir.
void *is1;
İnt *is2;
///
İs1=is2;
İs1++; Burada dikkat etmemiz gereken is1 yani void ile tanımladığımız işaretçi üzerinde aritmetik işlem yapılmayacağıdır!
__________________
İşaretçiler ve Diziler
4. İşaretçiler ve Diziler
C++ da İşaretçiler ve diziler arasında çok yakın bir ilişki vardır. Bir dizinin ismi, dizideki ilk elemanın adresini içeren sabit bir değişkendi. Bundan diziler bölümünde bahsetmiştik. Şimdi işaretçiler ile dizileri ilişkilendirirsek, dizilerin adlarının birer işaretçiden oluştuğunu görmüş olacağız.
*(a+i)
a[i] Bu sayede bu iki ifadenin aynı olduğunu söylemiş oluruz. Bir de çok boyutlu dizilere uyarlarsak,
*(*(a+i)+j)
a[i][j] şeklini alır.
İnt a[100];
İnt *is1=&a[100]; Örneğimiz; //işaretçi ve diziler
#include <iostream.h>
void KareAl(int *sayi) {
*sayi *= *sayi;
}
void KareAlDizi(int *is1) {
for (int i=0; i<10; i++)
is1[i] *= is1[i];
}
int main() {
int x = 50;
int intis1[10];
KareAl(&x);
cout<<"x = "<<x<<endl;
KareAlDizi(intis1);
cout<<intis1;
return 0;
} Örneğimizi adım adım takip edersek: void KareAl(int *sayi) burda sayi adında bir işaretçiyi kullanarak bir fonsiyon tanımlanıyor. Fonksiyonumuzun adı kare alma. İkinci fonksiyonda ise is1 isimli bir işaretçi ile parametresini giriyoruz, fakat işlem diziler üstünde sürüyor. Demiştik ya, dizilerin adları da birer işaretçiden oluşur. Sonraki main() fonksiyonumuzda da, x sabit değişkenimizi ve int tipindeki intis1[ ] dizimizi tanımlıyoruz. Referans yolu ile fonksiyonumuzu sabit değeri gönderiyoruz. Bir diğer işlemle de işaretçi parametresine sahip fonksiyonumuza bir dizi gönderiyoruz. Sanırım gayet basit oldu[IMG]http://www.************/images/smilies/smile.gif[/IMG]. Bu sayede fonksiyonları da konuya ilişkilendirmiş olduk. Yoruldum... Çay yapıp geliyorum[IMG]http://www.************/images/smilies/smile.gif[/IMG]
__________________
İşaretçiler ve Fonksiyonlar
5. İşaretçiler ve Fonksiyonlar
İşaretçiler ve diziler bölümünde görmüş olduğumuz örnektede olduğu gibi. Biz fonksiyonun adresine onun adı ile ulaşırız.
Kareal(x); gibi. Şimdi bir fonksiyonu işaret eden bir işaretçiyi ele alalım. İnt KareAl( ); fonksiyonumuz olsun. İnt (*KareAl)( ); Bu da Fonksiyonu işaret eden bir işaretçimiz oldu. Biz genellikle işaret edilen fonksiyonları menülerde ve sıralamalarda kullanırız. Aşağıda bir sıralama örneği verilmiştir.
//is_ve_fonk.cpp
//işaretçiler ve fonksiyonlar
#include <stdlib.h>
#include <iostream>
using namespace std;
void YatayYaz(char*);
void DikeyYaz(char*);
void ismiYaz(char*, void (*Yaz)(char*));
int main()
{
char isim[] = "Deneme";
ismiYaz(isim,DikeyYaz);
ismiYaz(isim,YatayYaz);
system("pause");
return 0;
}
void YatayYaz(char *isim)
{
if(!isim)
return;
cout << isim;
}
void DikeyYaz(char *isim)
{
if(!isim)
return;
int i = 0;
while(isim[i] != NULL)
{
cout << isim[i++];
cout << endl;
}
}
void ismiYaz(char *isim, void (*Yaz)(char*))
{
Yaz(isim);
cout << endl;
}
__________________
Fonksiyonlara işaretçi Parametresi
6. Fonksiyonlara işaretçi Parametresi
İşaretçiler ve diziler bölümünde yapmış olduğumuz örnekte,
void KareAl(int *sayi); şeklinde bir fonksiyon tanımladık. Burada *sayi adında bir işaretçiyi parametre olarak fonksiyona göndermiş olduk. Zaten kullanım şeklini de örnekte olduğu gibi
KareAl(&x); x in adresini fonksiyona yazmamız yeterli oldu. Bu sayede ek bir işaretçi tanımlamamıza gerek kalmadı.
Farklı bir örnek daha verecek olursak:
#include <stdlib.h>
#include <iostream>
using namespace std;
void artan(int is1);
void artan2(int *is1);
void artan(int is1)
{
is1 += 5;
}
void artan2(int *is1)
{
*is1 += 5;
}
int main()
{
int i = 0;
artan(i);
cout << "i simdi: " << i << endl;
artan2(&i);
cout << "i simdi: " << i << endl;
system("pause");
return 0;
} Görülmüş olduğu gibi artan2 adındaki fonkyionumuza int tipindeki *is1 işaretçisini parametre olarak verdik ve main() artan2(&i); şeklinde çağrımızı yaptık.
!!!En zor kısmı atlattık sanırım. Lütfen geri dönüp örnekleri yeniden gözden geçirirseniz sizin için yararlı olacaktır. Bir program yazana kadar sizi bırakmayacağım[IMG]http://www.************/images/smilies/smile.gif[/IMG] !!!
Kısaca C++'ya giriş yaptık.[IMG]http://www.************/images/smilies/smile.gif[/IMG]Bundan sonrası çok çalışıp yorularak küçük programlar yapıp kendimizi geliştirmemiz gerekiyor.
__________________
"O zaman vecd ile bin secde eder -varsa- taşım."
-Vücuda verilen kuvvet, Hak’ka ibadet, halka hizmet içindir.
C++ görüntülü eğitim almak için bu siteden yararlanılabilir.
Üye olmak gerekiyor, dileyen zaman ayırıp üye olabilir zamanım yok diyenler için bir üyelik aldım.
Kullanıcı adı: cpp
Şifre : risaleinur
http://www.seyretogren.com/yazilim/c-dersleri.html
"O zaman vecd ile bin secde eder -varsa- taşım."
-Vücuda verilen kuvvet, Hak’ka ibadet, halka hizmet içindir.
Teşekkürler![]()
Şu an 1 kullanıcı var. (0 üye ve 1 konuk)