FONKSİYONLAR

C genel amaçlı bir programlama dilidir. 1970 yıllarında Bell Laboratuvarlarında UNIX işletim sistemi yaratılırken ortaya çıkmıştır.

Öteki dillere göre küçüktür. Özellikle giriş/çıkış deyimleri sistemin bir parçası değildir. bunlar birer C fonksiyonu ile yaplır. Genel olarak her C derleyicisinin yanında C fonksiyonlarını içeren zengin kütüphaneler vardır. C hem sistem düzeyinde hem program düzeyinde çalışabilir.

Fonksiyon nedir?

C dilinde fonksiyonlar programın yapı taşlarıdır. Belirli bir işi ylapmak için uygun biçimde bir araya getirilmiş C deyimlerinden oluşur. Böyle olduğu için bir programa özgü olarak yazlan bir C fonksiyonu aynı işlevi görmek üzere bir başka C programına çağrılabilir ve orada kullanılabilir. C de her iş bir fonksiyonla yapılır. Ana programın kendisi de bir fonksiyondur ve main() adını alır.

Fonksiyonlar için söz dizimi

Bir fonksiyonun bildirimi için söz dizimi ţöyledir:

depo_sınıfı tür fonksiyon_adı (varsa değişkenler)

..................................................

değişkenlerin bildirimi

..................................................

{

..................................................

yerel (iç) değişkenlerin bildirimi

..................................................

deyim_1;

deyim_2; Bu blok içinde baţka blaklar yer

alabilir.

deyim_n;

..................................................

return();

}

Her fonksiyonun bir adı vardır; addan sonra () parantezleri mutlaka konulur. Eğer fonksiyonun bağlı olduğu değişkenler (parametreler) varsa () içine yazılırlar. Birden çok değişken varsa virgülle birbirinden ayrılır. Değişkenlerin türünü belirten bildirim ‘{‘ blok başlangıcından sonra bildirilir. Sonra deyimler yazılır. Varsa, fonksiyonun alacağı değer

return();

deyiminde() içine yazılır. Örneğin,

float ortalama(x,y)

float x,y;

{

floatz;

z=(x+y)/2;

}

fonksiyonu iki sayının ortalamasını bulur.

Bazı derleyiciler, hemen değişkenin önünde türün belirtilmesine izin verirler:

topla(int x,float y)

{

..................................

deyimler

..................................

}

PASCAL'da procedurler ve fonksiyonlar iç-içe yuvalanabilirler ama C fonksiyonları iç-içe yuvalanamaz. Bu şekilde iç-içe yuvalanma verilere erişimi kısıtlar. C de verilere ve fonksiyonlara ulaşımda daha çok flexibilite vardır.

Öte yandan, bir fonksiyon tanımlanırken, iç-içe istenildiği kadar blok kunulabilir. Her bir blok “{“ simgesi ile başlayıp, “}” simgesi ile biter.

main()

{

printf(‘Bu ilk programımdır.’);

}

Her hangi bir metin yazdırılmak isteniyorsa, o metin (string) yukarıdaki gibi ‘ ‘ (tırnak) içinde yazılmalıdır.

main()

{

printf(‘Bu ilk programımdır.\n C dili çok

hünerlidir.’)

}

Bu program koşturulduğunda çıktısı şöyle olacaktır:

Bu ilk programımdır.

C dili çok hünerlidir.

Çok kullanılan fonksiyonlar C derleyicisi ile birlikte verilir. Bu tür fonksiyonlar fonksiyon kütüphanesi denebilecek bir paket içinde sunulabilir. Hangi fonksiyonların hangi adlarla hangi kütüphaneye yerleştirileceği, doğrudan doğruya derleyiciyi yaratan firmanın isteğine bağlıdır. Ancak, standart fonksiyonlar diye adlandrlan ve hemen her derleyicide yer alan fonksiyonlar firmaların çoğu tarafından aynı amaç ve aynı ad ile yaratılır

Örneğin, standart giriş-çıkış işlemlerini yapan stdio.h bunlara yalnızca bir örnektir. Gene, abs(), pow(), exp(), log(), sin(), cos(), tan(), asin(), acos(), atan(), atan2(), gibi başlıca matematik fonksiyonları bu tür standart fonsiyonlar arasındadır.

Bugün piyasada satışa sunulmuş binlerce C fonksiyonu vardır. Bunları satın alırken, fonksiyonun hangi firmanın ürettiği hangi derleyiciye uyduğunu ve hangi donanım dizgesinde çalıştığını bilmek gerekir. Maalesef bu konuda istenen standartlar oluşmuş değildir ve gün geçtikçe de standartlardan uzaklaşılmaktadır.

Elbette, C dilinde hazır fonksiyonları kullanmak program yazımın koluylaştırır ve program yazma zamanını azaltır. Ancak, istenen işi yapacak hazır fonksiyonlar olmadığı zaman, programcı C dilinin standart deyimlerini kullanarak istediği işi yapacak fonksiyonları kolayca yazabilir. C dilinde yazılabilecek programlar için bir üst sınır yoktur. İyi bir programcı, yarattığı fonksiyonlarda değişkenleri ustaca adlandırarak o fonksiyonların baţka programlarda da kullanılabilir olmasını sağlayabilir. Böylece her program yazışta, benzer işleri yapan fonksiyonları yeniden yazmak yerine, daha önce yarattığı fonksiyonları programa çağırıp kullanmaya başlayabilir.

C dilinde, genel kural olarak, bir program içinde bir fonksiyon çağrılmadan önce tanıtılmış olmalıdır. Bu işleme fonksiyonun bildirimi diyoruz. Fonksiyon bildirimi, değişken bildiriminde olduğu gibi yapılır. Ancak fonksiyon bildirimin önceden yapılmasının gerekli olmadığı bir tek durum vardır:

int değerli fonksiyonlar bildiriminden önce çağrılabilir. Bunun nasıl olduğunu biraz sonra örneklerle inceleyeceğiz.

Fonksiyon kuruluţu:

Bir fonksiyon yaratılırken şu öğeleri belirtilir:

depo sınıfı tür ad (değişkenler)

değişkenlerin türlerinin bildirimi;

{ yerel değişkenler;

deyimler;

return(değer);

}

Örneğin,

extern float net_ücret(katsayı, vergi_yüzdesi)

double brüt;

float vergi;

{ int gösterge=140;

float brüt,net;

brüt= katsayı*gösterge;

gelir_vergisi=brüt*vergi_yüzdesi;

net=brüt-gelir_vergisi;

return(net);

}

Depo sınıfı

Fonsiyonun depo edileceği sınıfı belirtmek için kullanılabilir. Bu durumda auto sınıfından sayılır.

Tür (type)

Fonksiyonun işledikten sonra bize vereceği sonucun türünü belirtmek için yazılır. Tür int, float, double v.b. gibi temel veri türlerinden birisi olabilir. Tür belirtilmediği zaman o türün int olduğu varsayılır.

Ad

Her fonsiyon tanımında gereklidir. Değişken adlandırmada uyulan kurallara uyularak ad verilebilir.

() simgeleri Bir fonksiyonu tanımlarken onun ad yazıldıktan sonra () simgelerini koymak zorunludur. Bu parantezler, tanımlanan nesnenin bir fonksiyon olduğunu belirtir.

Değişkenler

Eğer fonksiyon bir yada daha çok değişkene bağlı ise bu değişkenlerin adlarının, hemen fonksiyon adından sonra, () içinde yazılması gerekir. Birden çok değişken varsa, değişkenler arasına ‘,’ (virgül) konulur. Değişken yoksa bile () simgeleri unutulmamalıdır.

Değişken türlerinin bildirimi

Fonksiyon adından sonra () içinde yazılan değişkenlerin türlerinin yazılarak bildirilmesi işlemidir.

{} simgeleri arasına fonksiyonun işlevini yaptıracak deyimler yerleştirilir.

Yerel değişkenler

Fonksiyon içinde gerekli olacak değişkenler varsa { simgesinden sonra öncelikle onlar bildirilir. Bu değişkenlere yerel değişkenler denilir. Yalnızca bildirimin yapıldığı blok için geçerlidirler. Başka fonksiyonlar buradaki yerel değişkenleri göremezler, kullanamazlar. Eğer aynı adla adlandırılmış global değişkenler varsa, bu fonksiyon kendi yerel değişkenlerine öncelik tanır; yani aynı adlı kendi değişkenini kullanır. Bu nedenle global ve yerel değişkenlerden hangisinin kullanılmak istediğine dikkat edilmelidir. Bunun nasıl yapılacağı biraz sonra anlatılacaktır.

Deyimler

Fonksiyonun istenen işlevi yapması için gerekli C deyimleridir.

Return(değer)

Eğer fonksiyonun verdiği sonuç bir başka blok içinde gerekli ise bu deyim kullanılmalıdır. Return deyimi yazılmadan fonksiyon bir değer veremez.

İç-değişkenler

Belirli bir fonsiyon içinde tanımlanan ve yalnızca bu fonksiyon tarafından kullanılan değişkenlere iç değişkenler denilir. İç değişkenler fonksiyonun {} içindeki gövdesi içine yerleşir. Hemen { dan sonra iç değişkenlerin bildirimi yapılır. Örneğin, yukardaki örnekte;

{ int gösterge=40

float brüt,net;

........................

bildirimleri birer iç değişken tanımlar.

Bir fonksiyonun iç değişkenini bir başka fonksiyon göremez, kullanamaz. Aynı adı taşıyan bir iç bir de dış değişken olduğu zaman, fonksiyon önceliği kendi iç değişkenine tanır.

Dış değişkenler

Bir fonksiyonun dışında ve başka bir fonksiyonun içinde olmayan değişkenlere dış değişkenler denilir. Örneğin,

/*Fonct6.C*/

#include stdio.h

int n;

long factorial();

main(void)

{

int i;

long int sonuc;

i=6;

{ sonuc=factorial(i); /*ilk cağrı*/

printf(‘%d!=%d dir.\n’,i,sonuc);

}

}

int factorial(int number)

{

if (number==0) /*denetim*/

return(1);

else

return(number*factorial(number-1);

}

 

 

DİKKAT 5 İNCİ SAYFA EKSİK

 

 

Programcının Tanımladığı Fonksiyonlar

C dilinde fonksiyonlar programın yapı taşlarıdır. Bir C fonksiyonu, belli bir işi yapmak için gerekli C deyimlerini içeren bir programdır. Böyle olduğu için bir programa özgü olarak yazılan bir C fonksiyonu aynı işlevi görmek üzere bir başka C programına çağrılabilir ve orada kullanılabilir.

main() fonksiyonu da bir C fonksiyonudur.

Fonksiyunun yapısı

Bir fonksiyonun sözdizimi ţöyledir;

tür ad (değişkenler)

....................

değişkenler için tür bildirgesi

...............................

{

...............................

yerel (iç) değişkenlerin bildirimi

...............................

deyimler

...............................

}

Değişken Bildirimi

Kaynak programda kullanılacak bütün değişkenler, uygun yerlerde bildirilmelidir. Değişken bildirimi, derleyici için değişkeni tanımlamak ; yani onun türünü, adını ve varsa ilk değerini belirtmek demektir. Değişken bildirimi için söz dizimi ţöyledir:

tür ad =değer ;

parantezlerinin içi, değişkene ilk değer vermek içindir. Bildirim anında ilk değer verilmeyecekse

tür ad;

yazılır. Aynı türden olmak koşuluyla birden çok değişken bir deyim ile tanımlanabilir. Bu durumda değişken adları bir birlelerinden virgülle (,) ayrılır. Aşağıdaki bildirge deyimi üç tane float türü değişken tanımlamaktadır.

float aylık, vergi,net;

Değişkene değer adama

Değişkene bir değer verme işidir. Bunun için sözdizimi ţöyledir:

ad = değer;

Örneğin,

int x,y=892;

x=275;

program parçasının ilk satırı int türünden x ile x adlı iki değişken bildiriyor ve y değişkenine 892 değerini adıyor. İkinci satr, x değişkenine 275 değerini adıyor.

Kaynak programda fonksiyon tanımlama zorunluluğu yoktur. Programın yapmasını istediğimiz her işi main() içerisine yazmak mümkündür. Ama, yapısal bir dil olan C dilinin hünerlerini ancak fonksiyonları kullanarak ortaya koyabiliriz. Bu nedenle, öncelikle, derleyicideki hazır fonksiyonları iyi tanımalıyız. Sonra da, programcı olarak kendimiz fonksiyon yaratmayı ve onları ustaca kullanmayı alışkanlık haline getirmeliyiz

Şimdi kaynak programda bir fonksiyonun tanımlanışını, ve onun main() tarafından özel değerlerle çağrılışını görelim.

Örnek2

/*hesap.c*/

#include stdio.h

main()

{

int toplam;

toplam=topla(2873,5438);

printf(öToplamın değeri %d dir.\n’,toplam);

}

int topla(x,y)

int x,y;

{

int t;

t=x+y;

return(t);

}

Kaynak programdaki deyimleri kısaca açıklamakta yarar vardır;

  1. Satır: Kaynak programın adı /* */ açıklama simgeleri arasına yazılmıştır. Bu ad derleyiciye verilmeyecektir; yalnızca, okurun bilgi edinmesi içindir. Kaynak programın adı yazılmayabilir; ama bir kayıt ortamına kaydedebilmesi için işletim sistemi onu bir kütük olarak görebilmelidir, yani bir ad verilmesi zorunludur. Bu adın, kaynak programın başına yazılması, okura kolaylık sağlar.

2. Satır: include stdio.h deyimi, C dilinde standart giriş/çıkış işlemlerini yapan fonksiyonları içeren stdio.h kütüğünü çağırır.

3. Satır: Baş fonksiyonu başlıyor.

4. Satır: Baş fonksiyonun blok başlangıcı.

5. Satır: Baş fonksiyonun bir yerel (iç) değişkeni olarak int türünden toplam adlı bir değişken bildirimi yapılıyor. main() fonksiyonu içinde bildirilen bu değişkeni, öteki bütün fonksiyonlar tanıyacaktır; yani toplam adlı değişken, main() 'in çağıracağı her fonksiyon için bir dış (global) değişken olacaktır.

6. Satır: Bu satırdaki deyim iki iş yapmaktadır. Önce topla adlı fonksiyonu çağırmakta ve bu fonksiyonun x=2873 ve y=5438 için değerini hesaplamaktadır. Sonra çıkan değeri toplam adlı değişkene adamaktadır.

7. Satır: printf (‘Toplamın değeri %6d dir.\n’,toplam); deyimi, önce printf() hazır fonksiyonunu çağırmaktır. Sonra bu fonksiyona metin ile karışık biçimlendirilmiş bir sayı yazdırmaktadır.

8. Satır: Baş fonksiyon blokunun bitişi.

Bundan sonraki satırlarda, kaynak program, topla adlı bir fonksiyon tanımlamaktadır. Fonksiyon tanamının her bir deyimi derleyiciye şunları bildirmektedir:

1. Satır: Fonksiyon int türündendir, adı topla dır. x,y adlı iki değişkene bağlıdır.

2. Satır: Fonksiyonun bağlı olduğu x,y değişkenleri int türündendir.

3. Satır: Fonksiyon blokunun başlangıcıdır.

4. Satır: Fonksiyonun int türünden t adlı bir yerel değişkeni vardır.

5. Satır: t değişkenine x+y değeri adanmaktadır.

6. Satır: Fonksiyonun değeri t dir.

7. Satır: Fonksiyon blokunun bitişidir.

Fonksiyonun t adlı bir yerel (iç) değişkeni vardır. T'ye adanan değer x+y dir. Fonksiyonun değeri t dir. Bu değer return(t) deyimi ile verilmektedir. Bir çok C derleyicisinde, parantezler konulmadan;

return t;

yazmak yeterlidir. return anahtar sözcüğü fonksiyonun vereceği değeri belirtmek için kullanılır. Eğer fonksiyonun bir değeri yoksa, yalnızca

return ;

yazılır.

Bir fonksiyonun adından sonra () parantezlerinin yazılması gereklidir. Varsa değişkenler parantez içine yazılır. Birden çok değişken varsa, birbirlerinden virgülle ayrılırlar. Bazı derleyiciler, parantez içinde değişken türünü de yazmaya izin verir. Bazılarında ise, değişken türleri hemen fonksiyon adından sonra, ama { blok başlangıcından önce bildirilir. Fonksiyonun, varsa yerel değişkenleri, { blok başlangıcından hemen sonra bildirilir.

Tür bildirgesinden sonra fonksiyonun blok başlangıcı belirlenir. Bunu belirleyen simge { simgesidir. Fonksiyonun kullanacığı C deyimleri ve varsa iç bloklar, çağrılı fonksiyonların adları v.b. yazılır. En sonunda fonksiyonun blok bitiţi belirlenir. Bunu belirleyen simge } simgesidir.

Bir C fonksiyonu bir başka C fonksiyonunu ve hatta kendi kendisini çağırabilir. Ama bir C fonksiyonu içinde bir başka C fonksiyonu tanımlanamaz.

Fonksiyon kavramını ileride daha ayrıntılı olarak ele alacağız.

Bu aşamada, printf() fonksiyonuna biçimlendirilmiş çıktıların nasıl yaptırıldığını örneklerle görmek iyi olacaktır.

printf(‘Sorusunun yanıtı %6d dir’,x);

komutu x değişkeninin değeri ne ise onu yazar. Eğer x`in değeri 3467 ise ekranda

sorunun yanıtı 3467 dir.

yazısı görülür.

Burada metinler olduğu gibi gelir, x yerine bellekte yazılı olan değer girer.

%6 simgesi x değişkenine 6 hane ayrılmasını sağlar. d simgesi, İngilizce`de decimal sözcüğünden gelir, onluk dizgede tamsayı yazılacağnı belirtir. x yazılacak değişkeni belirtir.

Hemen hemen her C deyimi ; ile biter. Bütün program ţöyledir:

main()

{ x=1234

printf(‘Bu sorunun yanıtı %6d dir.’,x);

}

Bu programın isteneni yazmasını bekliyoruz. Ama C derleyicisi bunu henüz derlemeyecektir.

Standart fonksiyonlar

Çok kullanılan fonksiyonlar C derleyicisi ile birlikte verilir. Bu tür fonksiyonlar fonksiyon kütüphanesi denebilecek bir paket içinde sunulabilir. Hangi fonksiyonların hangi adlarla hangi kütüphaneye yerleştirileceği, doğrudan doğruya derleyiciyi yaratan firmanın isteğine bağlıdır. Ancak, standart fonksiyonlar diye adlandırılan ve hemen her derleyicide yer alan fonksiyonlar hemen her firma tarafından aynı amaç ve biçimde yaratılır.

MATEMATİKSEL FONKSİYONLAR

Matematiksal işlemleri yapmaya yarayan fonksiyonlar math.h adlı öncül kütükte yer alır. Bunların listesi aşağıdadır. Listede fonksiyonların C ve PASCAL dillerindeki adları ayrı ayrı verilmektedir:

Fonksiyon C Pascall

Salt değer abs(x) abs(x)

Kare pow(x,2.0) sqr(x)

sinus sin(x) sin(x)

cosinus cos(x) cos(x)

tangent tan(x) tan(x)

arccos acos(x)

arcsin asin(x)

arctan atan(x) arctan(x)

arctan atan2(x)

Doğal loğ log(x) ln(x)

Üstel exp(x) exp(x)

Karekök sqrt(x) sqrt(x)

polinom poly

Buffer`a giriş çıkış yapan fonksiyonlar

C dilinde giriş işlemleri (buffer`a) birer fonksiyon ile yapılır.

getchar() Klavyeden bir karekter girişini sağlar.

putchar() Standart çıkışa bir karakter gönderir(ekrana)

getc() Bir çok derleyicide kütükten bir karekter okur.

putc() Bir çok derleyicede kütüğe bir karekter yollar.

getch() Stdin adlı kütüğe bir karakter yazar.} UNİX

putch() stdout adlı kütüğe bir karakter yazar.}işletim sistemi

gets() Klavyeden metin girişini sağlar.

puts() Bir bellek hücresinden başlıyarak NULL'a kadar olan karakteri std çıkış (ekran) gönderir.

Bunların nasıl kullanıldığını yeri geldikçe göreceğiz.

Bir C programı çalışırken otomatik olarak en az üç kütük açılır.

stdin Klavye

stdout Ekran

stderr Ekran

 

PROGRAMIN HAZIRLIK EVRELERİ

bilgisayarın bir işi yapabilmesi için şu öğeler gereklidir.

1. Kaynak program Her hangi bir programlama dilinin deyimleri kullanılarak metin (text) biçiminde yazılan programdır.

2. Derleyici Kaynak programı object koduna çevirir. Farklı dillerin ve farklı bilgisayarların derleyicileri farklıdır.

3. Linker (bağlayıcı) Object kodları birleştirerek makina diline çevrilmiş (yani çalışabilir executable) bir kütük yaratır.

Her bilgisayar programında olduğu gibi, C dilinde bir programın yazılması ve koşturulması şu aşamalardan geçer.

  1. Bir editör (kelime iţlemci) yüklenir.
  2. Editör ile kaynak C programı yazılır.
  3. Yazılan kaynak programa bir ad verilir; floppy disket, sabit disk, teyp v.b. bir kayıt ortamına kaydedilir; kelime işlemci kapatılır.
  4. Kullanılacak C-derleyicisi (compiter) yüklenir. Kaynak programın derleyici tarafından işlenmesini sağlayan komut yazılır. Bu komut, derleyiciden derleyiciye değişebilir. Komutun nasıl yazılacağı,kullanılan derleyicinin başvuru kaynaklarında yazılıdır.

Kaynak program, genellikle, derleyicilerden bir kaç kez geçer. Her geçişte ayrı bir işlem yapılır. Bu geçişler, isteğe bağlı olarak, bazı derleyicilerde kendiliğinden ve sırasıyla olur; bazılarında ise her geçiş, kullanıcı tarafından yapılır. Örneğin, XENIX-C derleyicisi derleme işlemini dört evrede tamamlar.

Birinci geçiş (Önişlem): İçerilen (include) kütükler, makro tanımlar, sabit tanımlar ve benzerleri denetlenir.

İkinci geçiş: C diline ait deyimler geçer;simge tablosu oluşturulur, varsa sözdizimi yanlışları listelenir.

Üçüncü geçiş: Kodları yaratır.

Dördüncü geçiţ: Optimum performans için konlar düzenlenir.

Geçiş evreleri tamamlanınca, derleyici kaynak proğramı makina diline çevirmiş ve kayıt ortamına kaydetmiş olur. Değişik makinalarda ve değişik derleyicilerde bunlara değişik adlar verilir. Genelde, derleyicinin yarattığı bu kodlardan oluşan kütüğe object kütük denilir.

linker (bağlayıcı) yüklenir. Bir object kütük ya da birleştirilecek object kütükler linker'e verilir. Linker object kütük(ler)de yer almayan ama programa gerekli olan fonksiyonlar için library'e bakar; bulunca onları birleştirir. Birleşik biçim için makina koduna yaratır ve kaydeder.

Bir programı oluşturan fonksiyonlar tek tek ya da bir arada derlenebilir. Tek tek derlenen fonksiyonlar ile library'deki fonksiyonlar linker ile birleţtirilir.

Linker, istendiğinde bir birlerinden ayrı olarak yazılmış kaynak programlardan yaratılan object kütükleri birleştirerek tek bir program haline getirir. Bu birleşme işinin nasıl yapılacağı makinaya, derleyiciye ve linker'e bağlı olarak farklılıklar gösterir. Kullanıcı bu aşamalar için ilgili kılavuzlara bakmalıdır.

DOS işletim sistemi altında çalışan derleyici ve linkerler ile yaratılan makina kodları EXE uzantısını alırlar.

Linker'in yarattığı kodlar yürütülebilir biçime getirilmiş programladır; yani makina diline dönüşmüş programdır. Bu programları koşturmak (işletmek) için adlarını yazmak yeterlidir.

Son yıllarda yaratılan bazı entegre programlarda yukarıda sıralanan evreler kısmen ya da tamamen kendiliğinden yapılmaktadır. Bir çoğunun kendi editörü vardır. Ana menüden kullanıcının istediği seçenekler yapılr. TURBO C, Zortec C++,C++ gibi entegre programlar bunlara örnektir.

DEBUGGER: Derleyicinin gördüğü yanlışlıkları gidermeye yarayan programdır.

 

Buna göre şu şemayı çizebiliriz:

 

Kaynak

Program

 

Debugger

 

Object

Kodları

 

 

LİNKER

Fonksiyon Kütüphanesi Baţka object Kütükler

 

 

Yürütülebilir

Program

Uyarı

Kaynak programlarıderlemek ve birleştirmek için gerekli işlemler derleyiciye bağlı olmakla birlikte, farklı derleyiciler için yapılan işlemler birbirine benzer. Derleme ve link aşamalarında yaratılan kütüklerin uzantıları da işletim sistemine bağlı olarak değişebilir. IBM uyumlu PC'lerde, derleyicininyarattığı object kütükler OBJ uzantısını alır. Linker'in yarattığı çalışabilir kütük ise EXE uzantısını alır.

Tek bir programın derlenmesi

Deneme l.C adıyla yazılmış bir kaynak program düşünelim.

cc-c Deneme 1.C

komutu yazılıp ENTER'e basılır. [C Uzantısı yazılmayabilir]. Buradaki C seçkisi, derleyiciye linker'i devreye sokmamasını söyler. Böylece, derleyici

Deneme1. obj

adlı object programı üretir. Bu progranı çalışıbilir kütüğe çevirmek için

link Deneme1.obj

yazılır [.obj uzantısı yazılmayabilir]. Linker, Deneme1.obj kütğünden

Deneme1.exe

adlı kütüğü yaratır. Bu çalışabilir bir kütüktür. Bunu çalıştırmak için

deneme1.EXE

yazıp ENTER'e basmak yetecektir. [.exe uzantısı yazılmayabilir].

Birden çok kaynak programın ayrı ayrı derlenip birleştirilmesi

Deneme1.C ve Deneme2.C adlarıyla yazılmış iki kaynak program olsun. Bu iki program, yukarıda açıklandığı gibi ayrı ayrı derlenip object kütükleri yaratılır. Bu iki object kütüğü birleştirip Deneme.EXE adlı kütüğü yaratmak için

link cc Deneme1.obj deneme2.obj-0 Deneme.EXE

komutunu yazmak yetecektir. Bu komut DENEME.EXE adıyla yürütülebilir bir kütük oluşturur. Bu program çalıştırmak için, DOS ortamında

deneme

yazıp ENTER'e basmak yetecektir.

Eğer kütükler, yazma/okuma (y/o) kafasının bulunduğu yerde değilse, işletim sisteminin onları bulabilmesi için tam adreslerini (sürücü adı, directory, path) belirtmek gerekir.

nden

 

 

KAYNAK PROGRAMLARIN YAPISI

TEMEL KAVRAMLAR

main() fonksiyonu

Her C programı main() adı verilen bir baş fonksiyon ile baş fonksiyonda kullanılacak neslelerinbildirgesinden ibarettir. Baş fonksiyonun içine baţka fonksiyonlar yerleţebilir. Baţ fonksiyonun sözdizimi ţöyledir:

[programda kullanılacak nesnelerin bildirgesi]

main()

{

.......................................

deyimler ve/ya fonksiyonlar

.......................................

}

C dili küçük-büyük harf ayrımına duyarlıdır

Bazı diller büyük harf-küçük harf ayrımını yapmaz; bazı diller büyük ve küçük harfleri ayrı ayrı algılar.

C dili, büyük harf-küçük harf ayrımını yapar. Esas olarak küçük harfleri kullanır; yani kaynak programda bütün deyimler, fonksiyonlar, anahtar sözcükler vb. küçük harflerle yazılır. Dolayısıyla, kaynak program yazarken, bu kurala kesinlikle uymamız gerekecektir. Büyük harflerin kullanılabilaceği kural dışı durumları ileride açıklayacağız.

Örnek 1

Bir kelime işlemci kullanarak aşağıdaki metni yazalım.

/*Merhaba.C*/

#include stdio.h

main()

{

printf(‘Merhaba,C!..’);

}

Buna kaynak program. Bu kaynak program, yukarıda açıklandığı gibi derlenip koşturulursa, ekrana

Merhaba, c!..

yazısı çıkar. Buna programın çıktısı diyoruz.

Bir çıktıyı ekranda görüntülemek için C dilinde printf() (print format) fonksiyonunu kullanırız. Örneğin, yukarıdaki yerine

Örnek 2.

/*ilkprg.C*/

#include stdio.h

main()

{

printf (‘Bu, C dilinde yazdığım ilk denemedir.’);

}

programını koşturursak, bu kez ekrana

Bu, C dilinde yazdığım ilk denemedir.

yazısı çıkar.

Kaynak program

Bir C programı bir dizi C deyiminden ve/ya fonksiyondan oluşur.Kaynak program, bir kelime işlemci kullanılarak yazılır ve bir kayıt ortamına kaydedilir. Örnek 2 ile verilen programlar birer basit programdır.

Açıklama simgeleri: /* */

C kaynak programı yazılırken, okura açıklanmasında yarar görülen ama derleyiciye gitmemesi istenen metinler /* */ simgeleri arasına yazılır. Bu simgeler BASIC dilindeki REM'in karşılığıdır. Örnek l'deki program adı /* */ simgeleri arasına alındığı için, derleyici o satırı işlemez.

#include

C dili küçük bir dildir. Genel amaçlı bazı dillerde olduğu gibi giriş/çıkış işlemleri ve bazı temel işlevler dilin ayrılmaz parçaları değildir; aksine onların herbirisi, derleyici dışında yaratılan bir fonksiyon ile yapılır. Çok kullanılan bazı fonksiyonları içeren kütüphaneler oluşturulmuştur. #include anahtar sözcüğü bu tür kütüphaneleri çağırmak için kullanılır. Değişik firmaların yarattığı derleyicilerle birlikte verilen fonksiyon kütüphaneleri farklı olabilir. Ama hemen hepsinde stdio.h ve math.h gibi bazı öncü kütüphaneler (header files) standart olarak vardır. stdio.h öncü kütüphanesi temel giriş/çıkış işlemlerini yapan fonksiyonları içerir.

 

VERİ TÜRLERİ

DEĞİŞKENLER

Sayısal bilgisayarlar yalnızca ikilik (binary) dizgede yazılı sayıları saklayabilirler. Bilgisayar belleği hücrelerden oluşur. Her bir hücre 8, 16 ya da 32 sayak (bit)'lik olabilir. Sayaklık büyüklüğü bilgisayarın marka ve modeline bağlı olarak değişir. Sayaklık büyüdükçe makinanın etkinliği artar.

Bir programlama dilinde kullanılan her değişkene ana bellekte bir yer ayrılır. Bazı değşikenler küçük bir yere sığdığı halde bazıları daha büyük yer ister. Bu nedenle, hemen her dilde, değişken türleri önceden belirlenir ve bunların her birisine ana bellekte belli ve yeterli büyüklükte birer yer ayrılır. C dilinde üç tane asal veri türü vardır. Bu türlerin adları, açıklamaları ve PC'de bit ve byte cinsinden kapladıkları bellek alanları şöyledir.

Tür Açıklama bit uzunluğu byte uzunluğu

char karekter(harfyada simge) 16 bit 2 byte

int tamsayı 16 bit 2 byte

float kesirli sayı 32 bit 4 byte

Bu asal türlerden türetilmiş aşağıdaki türler de hemen her C derleyicisinde vardır. Bunlara asal türlerin türevleri denilir.

Tür Açıklama bit uzunluğu byte uzunluğu

unsigned işaretsiz(pozitif)tamsayı 16 bit 2 byte

shortint küçük tamsayı 16 bit 2 byte

longint büyük tamsayı 32 bit 4 byte

double büyük kesirli sayı 64 bit 8 byte

string char dizini değişir değişir

struct yapı değişir değişir

Son ikisi, esas olarak programcı tarafından yaratılır. Bunun nasıl olduğunu görecegiz.

Char türü değişkenlere ana bellekte 1 byte (8 Bit) büyüklüğünde bir yer ayrılır. İnt türü için bilgisayarın 1 kelime (word) büyüklüğü kadar yer ayrılır. 1 kelime büyüklüğü bilgisayardan bilgisayara değişir. PC'lerde bu uzunluk genellikle 2 byt'tır.

Bir C programında bütün değişkenler kullanılmadan önce bildirilmelidir (declare). Bu iş bir bildirgeyle yapılır. C'de değişkenler üç niteliğe sahiptirler:

depo sınıfı (storage class)

türü

ilk değeri

Bildirgede değişkenlerin türünün ve adının bildirilmesi zurunludur. Depo sınıfı ve ilk değer bildirimleri isteğe bağlıdır. Buna göre, bir değişken bildirimi için sözdizimi aşağıdaki üç deyimden birisiyle yapılır:

tür ad;

[sınıf] tür ad;

[sınıf] tür ad; [=ilk değer];

bildirimde [ ] içindekilerin yazılması isteğe bağlıdır; bildirgede yer almayabilir. İsteğe bağlı nitelikler bildirilirken [ ] parantezleri yazılmaz. Örneğin,

auto float toplam=0.0;

bildirgesi, toplam adlı değişkenin sınıfının auto, türünün float olduğunu ve kendisine 0.0 başlangıç değerinin adandığını bildirir.

Özetle, depo sınıfı ancak gerekliyse belirtilir. Özellikle, auto sınıfını belirtmeye çoğu kez gerek görülmez. Tür mutlaka belirtilmelidir, [=ilk değer] isteğe bağlıdır.

DEPO SINIFLARI (STORAGE CLASSES)

C'de depo sınıfları bir değişkenin nerede saklanacağını, onu kimlerin (hangi fonksiyonların, hangi blokların) kullanacağını ve yaşam süresini (ne zaman kullanılacağnı) belirler. Dört depo sınıfı vardır

1. auto

İngilizce'deki automatic sözcüğünün kısaltılmışıdır. Bir değişken için auto nitelemesi, nitelenen değişkenin ana bellekte geçici bir süre kalacağını belirtir. Bu süre, değişkenin bildirildiği blokun çalıştığı süredir. Bir fonksiyon tanımında, depo sınıfı belirtilmeden bildirimi yapılan her yerel değişken auto sınıfına ait olur. Örneğin,

vergi() {

auto int gösterge, katsayı;

auto float brüt, vergi;

..........

}

biçiminde de tanımlayabiliriz. Bu iki tanım birbirine denk olur.

2. Extern

İngilizce'deki external sözcüğünün kısaltılmışıdır. Bir program için extern (dış) değişkenler, programa ait bütün blokların ve bütün fonksiyonların kullanabildiği değişkenler yada fonksiyonlardır. Dolayısıyla, bu değişkenlerin yaşam süreleri, programın başlangıcından sonuna kadardır. Bildirgesi, bütün fonksiyonların ve bütün blokların dışında olan değişken ve fonksiyonlar extern değişken sayılır. Örneğin,

.....

int a,b;

main() {...}

.....

fonk1() {

int a,b,

....

}

fonk2() {

extern a,b;

.....

}

Program parçasında, derleyici, ilk satırda bildirilen a ve b değişkenlerini extern olarak sayar ve onlara ana bellekte birer yer ayırır. Bu yer program sonuna kadar korunacaktır. Fonk 1() fonksiyonun iç değişkenleri de a ve b adını almıştır. Bunlar fonk1() için auto sınıfına aittir. Derleyici, bu ikisine de ana bellekte birer yer ayırır. Bu yerler, önceki yerlerden farklıdır. Ancak fonk1() tarafından kullanılabilir ve fonk1() çalıştığı süre içinde korunur; sonra onlara yapılan bellek tahsisi ortadan kalkar. Fonk2() fonksiyonun iç değişkenleri de a ve b adını almıştır; ancak bu değişkenler extern nitelemesine sahiptir. Dolayısıyla, derleyici, bunlar için ana bellekte yeni yerler ayırmız, ilk satırda bildirilen a ve b değişkenlerine ayrılan yerleri kullanmasını sağlar. Bu işi yapmak linker'in görevidir.

Extern değişkenler, farklı kütüklerde olduğu zaman da kullanılabilir. Örneğin, aşağıdaki Kütük_1 ve Kütük_2 adlı programların ayrı ayrı derlendiğini ve linker ile birleştirildiğini varsayalım:

Kütük_1

int a,b=12, c=45;

extern int hesap();

main()

{

a=hesap(b);

b=hesap(c);

printf(‘a=%d b=%d c=%d\n’,a,b,c);

}

Kütük_2

extern int c;

int hesap(x);

int x;

{

return(x*3+c+75);

}

Kütük_1'in birinci satırında bildirimi yapılan a,b,c değişkenleri, genel (global) değişkenleridir. Dolayasıyla extern sınıfına aittirler. Bu değişkenlerin bildirimini

extern int a,b,c=45;

biçiminde de yapabiliriz. Bu bildirim ilk satırdaki bildirime denktir. Kütük_2'de extern nitelemesine sahip c adlı değişken, kütük_1'deki c değişkeni ile aynıdır; yani her ikisi de aynı adresi (bellek alanını) kullanacaklardır.

Kütük_1'in ikinci satırındaki

extern int hesap();

bildirimi yapılmayabilirdi. Çünkü, bu fonksiyonun tanımı, kütük_2 içinde, bütün blokların dışında yapıldığı için extern depo sınıfına ait olacaktır. Ayrıcı, türü belirtilmeyen her değişken ve her fonksiyon int türünden sayılır. Dolayısıyla, bu satırı hiç yazmadan da programın Kütük_2 içinde tanımlanan hesap() fonksiyonunu bir extern int değişken olarak algılaması mümkündür.

Kütük_1'in içinde tanımlanan main() fonksiyonu da extern sınıfındandır. Dolayısıyla, derlenip birleştirilen başka kütükler tarafından kullanılabilir.

Extern nitelemesi fonksiyonların bağlı olduğu değişkenlerin bildiriminde (formal parametre bildirimi) kullanılamaz. Birden çok kütük derlenip birleştiriliyorsa, bir extern değişten yalnızca bir kütük içinde bildirilir; diğerlerinde bu değişken mutlaka extern nitelemesini alır.

3. Register

Bu niteleme, bir değişkenin Merkezi İşlem Birimi (CPU) registerlerinde saklanmasını istemek için yapılır. Programa hız kazandırmak amacına yöneliktir. Bir değişkeni ana bellekte ayrılan bir yerde saklamak yerine, onu CPU registerlerinden birisinde saklamak, erişim hızını çok artıracaktır. Dolayısıyla, bir blok içinde çok kez kullanılacak değişkenlere bu niteleme verilir. Ancak, regişter nitelemesine sahip değişkenlere reğişterde yer ayrılabileceği garanti edilemez. Eğer o anda değişkene tahsis edilebilecek bir register varsa, derleyici, istenen tahsisi yapar; yoksa, o değişkeni auto sınıfından sayar. Bu nedenle, & adres operatörü reğister nitelemesine sahip değişkenlere uygulanamayabilir.

Register nitelemesi, sıralama ve benzeri işleri yapan döngülerde çok kullanılır.

Aşağıdaki fonksiyon verilen bir sayıyı aramaktadır. Hızlı işlem için, aranan sayı ile index'e register nitelemesi verilmiştir:

bul(0

register int hedef;

{

extern int a,b[];

register int index;

int sayaç=0;

for (index=0; index<a; index++)

{

if (b[index]==hedef) sayaç++;

return (sayaç);

}

register nitelemesi ancak, bir fonksiyonun yerel değişkenlerine ve formal parametrelerine verilebilir.

4.static

Statik değişken bildiriminin iki nedeni vardır:

    1. Yerel değişkenlere ana bellekte ayrılan adreslerin kalıcı olmasını sağlar.
    2. Global değişkenlerin ve fonksiyonların geçerli olacağı bölgeleri kısıtlar.

Statik değiştenler yerel ya da global olabilir. Ama fonksiyonun formal parametrelerine static nitelemesi verilemez.

  1. Bir fonksiyonun her çağırılışında, o fonksiyonun yerel değişkenleri için ana bellekte birer yer ayrılır; fonksiyonun işlevi sona erince, değişkenlerine ayrılan yerler yok edilir. Eğer fonksiyon ana programda defalarca çağrılıp kullanılacaksa, her çağırışta bu işlemler yinelenecektir. Bu durumlarda, programcı, bazı yerel değişkenlerin yerlerini ana bellekte sürekli korumak isteyebilir. static nitelemesi bu işi başarır; yani fonksiyonun yerel değişkenlerine ayrılan yerin yok edilmeden ana bellekte sürekli olarak korunmasını sağlar. Başka bir deyişle, static nitelemesi yerel değişkenlere kalıcı özel yerler tahsis edilmesini sağlar. Bellekte kalıcı bir adresi olmasına karşın, static nitelemesine sahip yerel bir değişkene başka fonksiyonlar erişemez.
  2. Anımsanacagı üzere, global değişkenler bir kütükteki bütün fonksiyonların erişebildiği değişkenlerdir. Eğer birden çok kütük ayrı ayrı derlenip birleştiriliyorsa,extern niteliğine sahip aynı adlı değişkenlere, her kütükteki fonksiyonlar erişebilir. Bazan, programcı, bunun olmasını istemez; yani global değişkenlere bazı fonksiyonların erişebilmesini, bazılarının da erişememesini isteyebilir. Bu durumda, değişkenin önüne statik nitelemesini koymak yetecektir. Bu durumda, o satırdan önceki fonksiyonlar static nitelikli global değişkenlere erişemeyecektir.

Benzer ţekilde , bir fonksiyona static niteliği verilirse, o fonksiyon ancak o kütük içinde görülebilir; başka kütükler ona erişemez