Temel C Dokümanları 5 (Fonksiyonlar)
Bu derste fonksiyonlardan bahsedecem....
Simdiye kadarki yazdıgımız programlarda main() diye bir kısım vardı bilirsiniz... Programın yapacağı islerin hepsini bu main in icine yazıyorduk. Bu main() aslında bir fonksiyon. Programımızın ana fonksiyonu... Biz istersek programı başka fonksiyonlara bolerek de çalıştırabiliriz. Peki bunu niye yapalım ? Baska fonksiyonlar da kullanmak zorundamı kalıyoruz bazen ? Hayır.. sadece main fonksiyonunun icinde her şeyi halledebiliriz ama bazen belli kodları tekrar, tekrar yazmamız gerekebilir. Biz de işimizi kolaylastırmak ve programımızı duzenli bi hale getirmek icin belli isleri yapan kodlardan bir fonksiyon olustururuz ve bu kodlar tekrar, tekrar yazılacagına sadece fonksiyonumuzu cagırarak buyuk bi kufletten kurtulmus oluruz. Kısaca fonksiyonlar belli kod kumelerini tasıyan tek satırlık komutlardır diyebiliriz...
Bir fonksiyon oluşturmak icin temel olarak iki şey yapılmalıdır. Birincisi fonksiyonun adını ve kullanımını belirleyip tanıtmak(decleration) türkçeye de deklare etmek diye gecmiştir. İkincisi fonkiyonun icerdigi kodları yani yaptıgı işleri yazmak. Buna da implementation deniyor. Turkcesini bilmiyorum
Şimdi "yazdır" diye bir fonksiyon yapalım...
void yazdır(); // bu satırda yazdır adında bir fonksiyon tanıttık yani deklare ettik...
void yazdır() // burada da fonksiyonumuzun implementation ını yaptık.. yani fonksiyonun
{ // yapacağı işi { } ler acarak icine yazdık.. burda fonksiyonumuz ekrana
printf("Merhaba"
; // Merhaba yazıyor... yaptığı iş bu....
}
peki bu fonksiyonun başına yazdıgımız void de neyin nesi ?
Bu sorunun cevabını vermek icin bir fonksiyonun nelerden olustuguna deginmek gerek.
Bir fonksiyonun girdileri ve bir cıktısı vardır. Mesela iki tam sayıyı birbiri ile toplayıp sonucu veren bir fonksiyon duşunelim. Bu fonksiyonun iki tane girdisi olacak ( toplanacak sayılar) ve bir cıktısı ( toplamanın sonucu ). Bir fonksiyonu tanıtırken kac tane girdi aldıgını bu girdilerin turunun ne oldugunu ( tam sayımı, virgullu sayımı yada harf mi ) ve cıktısının turunu belirlememiz gerekir.
Yazdır fonksiyonunda, fonksiyon herhangi bir girdi almıyor ve bir cıktısıda yok. girdi almadıgını belirtmek icin yazdır dan sonra actıgımız parantezlerin icini bos bırakıyoruz yazdır() seklinde.
Cıktısının olmadıgını belirtmek icin de başına void yazıyoruz. void, cıktısının olmadıgını anlatıyor.
Bu noktada fonksiyonun çıktısı ile ekrana yazdırdıgımız yazıyı karıştırmamak lazım. Ekrana bir yazı yazıyor diye o fonksiyonun çıktısı var demek değildir.Fonksiyonların girdilerinin ve çıktılarının nasıl oldugunu inceleyelim:
toplama fonksiyonu:
int topla(int a, int b); // deklare ettik
int topla(int a, int b) // implementation
{
int c; // fonksiyonun icinde c diye bir tam sayı belirledik
c=a+b; // c yi fonksiyonun girdileri olan a ve b nin toplamına eşitledik
return c; // cıktı olarak c yi ver dedik
}
Yukarda goruldugu gibi topla fonksiyonunda void in yerine int yazdık çünkü bu sefer fonksiyonumuzun bir cıktısı olacak ve turu integer yani tam sayı olacak. Parantezlerin icinde de a ve b adında iki tene integer belirledik ve bunlar fonksiyonlumuzun girdileri oldu.Parantezlerin icindeki girdiler virgulle birbirinden ayrıldılar. return c; satırı ile fonksiyonun cıktısının ne olacagını belirlemis olduk. Bir fonksiyonun cıktısı varsa bu return komutu ile belirlenir.
Fonksiyon oluşturmayı öğrendik. Simdi olusturdugumuz fonksiyonu programımızda nasıl cagıracagımızı ( nasıl kullanacagımızı) ogrenelim:
main()
{
int x;
x=topla(3,5);
printf("%d",x);
}
yukardaki programda topla fonksiyonunu cagırdık girdi olarak 3 ve 5 i verdik cıktısını da x degiskenine atadık. Sonuc olarak x 3+5 yani 8 oldu. printf komutunun ekrana verdigi degere bakacak olursak 8 oldugunu goruruz. Yukardaki kodları birlestirip fonksiyon kullanıldıgı bi program yapacak olursak soyle olur...
#include<stdio.h>
int topla(int a, int b);
int topla(int a, int b)
{
int c;
c=a+b;
return c;
}
main()
{
int x;
x=topla(3,5);
printf("%d",x);
}
Gordugunuz gibi main i yazmadan once main in icinde kullanacagımız fonksiyonu once olusturduk sonra da main in icinde cagırdık.
Fonksiyonları ogrendigimize gore scope olayına da deginmemiz lazım. Scope turkce olarak icerik diye cevrilebilir. Bir program scope lardan olusur.Programda kullanılan her fonksiyonun bir scopu vardır main de dahil olmak uzere... Scope degiskenlerin birbirine karısmamasını saglar. Yukardaki ornekte hem mainin icinde hem de topla fonksiyonunun icinde degiskenler belirlendigini goruyorsunuz.. main in icinde belirledigimiz degiskenin adı da x yerine a olasydı topla fonksiyonunun icindeki a degiskeni ile karışırmıydı ? hayır.. cunku her degisken scope larına goredir. x degiskeninin scopu maindir a,b ve c degiskenlerinin scope u da topla fonksiyonudur...
x in adını a yaparsak programın kafası karışmaz... program icin iki tane a degiskeni olur biri scope u main olan a degiskeni, digeri scope u topla olan a degiskeni program scope ları farklı oldugu icin bu ikisini birbirine karışrtırmaz... ama aynı scope un icinde aynı isimli iki degisken belirleyemessiniz main in icinde iki tane a olamaz..
simdi bu scope olayını daha iyi anlamamıza yarayacak bir program yazalım:
#include<stdio.h>
void ekle(int x);
void ekle(int x)
{
x=x+1;
}
main()
{
int y;
y=5;
ekle(y);
prinrtf("%d",y);
}
Bu programda aldıgı değere bir ekleyen ekle adında bir fonksiyon olusturduk. mainin icinde y diye bir degisken belirledik değerini de 5 yaptık. sonra y degiskenini ekle fonksiyonuna verdik. printf le de y nin son değerini ekrana vermesini istedik. Simdi ekrana verilecek olan sayı y nin bir fazlası mı olacak ? Yani ekrana 6 mı yazılacak ? Bu soruya evet diyesi geliyor insanın cunku ekle fonksiyonu y nin degerini bir artırdı sanıyoruz ama oyle olmadı aslında. Sorunun cevabı hayır... ekrana 5 sayısı yazılacaktır. Simdi ekle(y); satırında olanları inceleyelim:
Bu satırda once y nin degeri ekle fonksiyonuna verildi.Sonra, ekle fonksiyonunun scope unda olan x degiskeninin degeri main in scope unda olan y nin değerine yani 5 e eşitlendi. Şu an ekle fonksiyonunun scope undayız yani eklenin içindeyiz... ekle fonksiyonunun icinde x in degeri bir artırıldı yani 6 oldu sonra ekle fonksiyonunun yapacagı işler bitti ve icinden cıktık, artık tekrar main in scope undayız ve main in icinde artık x diye bi değişken yok... Ve gordugunuz gibi y değişkenine bir değişiklik yapılmadı ... ekle fonksiyonu sadece kendi içinde bulunan x değişkenine bir değer atayıp sonra da onu bir artırdı ama kendi scope unda olmayan y değişkenine bir şey yapamadı...
main in icinde belirledigimiz y degiskeninin adını x diye deistirsek de bisey farketmezdi... cunku gene main in icindeki x ile eklenin icindeki x farklı şeyler olacaktı cunku scope ları farklı...
Demekki her fonksiyon kendi scope undaki degiskenlere etki edebiliyor ve her degisken bulundugu scope a gore ayrı bir sekilde degerlendiriliyor program tarafından...
Peki fonksiyonların main in icinde belirlenmis bir degiskenin degerini degistirmesinin bi yolu yokmu ? Var birincisi, fonksiyona bir cıktı belirlemek ve bu cıktıyı mainin icindeki degiskene atamak ilk programımızda ki şu satırda oldugu gibi: x=topla(3,5);
İkincisi ise pointer kullanmak ... pointerları da bir dahaki dersimizde işleyecez .
Simdi ödev veriyorum:
Asal sayı bulan bir program yapmıstık hatırlarsanız... Simdi o programı geliştirelim biraz... Bu seferki programımız çalıştığında kullanıcıdan iki sayı girmesini isteyecek ve bu iki sayı arasındaki asal sayıları alt alta ekrana verecek... Mesela 10 ve 15 diye iki sayı girdik.. program ekrana
11
13
verecek... Bu programla 5 milyonla ile 6 milyon arasındaki tüm asal sayıları bulabilirsiniz mesela...
Programda bir sayının asal olup olmadıgını kontrol eden bir fonksiyon kullanılacak... mesela fonksiyona verilen sayı asalsa cıktı olarak 1 versin degilse 0 versin... mainin icinde de bu fonksiyon kullanılarak bir loop yapılacak ve loopta girilen iki sayı arasındaki tüm sayılar sırayla fonksiyona verilecek eğer sonuc 1 olursa o sayı ekrana yazdırılacak...