You are on page 1of 104

C Programlama Dili'ne Giri Ders 1: Giri

Giri
Bu ilk derste, bir C programn nasl derlenip altrlaca ve Internet'te bulabileceiz derleyicilerden bahsedilecektir. En basit C programnn derleyip altrdktan sonra, geriye kalan sadece C Programlama Dili'nin kurallarn, yapsn ve deyimlerini renmekten ibarettir.

1.1 Tarihe
C Programlama Dili genel amal orta seviyeli ve yapsal bir programlama dilidir. 1972 ylnda Dennis Ritchie tarafndan Bell Telefon Labaraturvarnda Unix iletim sistemi ile kullanlmak iin tasarlanmtr. C, zellikle sistem programlamada sembolik makine dili (Asembler) ile tercih edilmektedir. letim sistemleri, derleyiciler ve debug gibi aa seviyeli sistem programlarnn yazlmnda youn olarak C programlama dili kullanlr. C'nin yaylmas ve gelimesi, byk bir blm C dili ile yazlan UNIX iletim sisteminin popler olmasyla balamtr. C Programlama Dili, hemen her alanda kullanlmaktadr. Gnmzde nesneye ynelik programlama dilleri (C++, Java) ve script dilleri (JavaScript, JavaApplet, PHP) gibi programlama dilleri C Programlama Dili'nden esinlenmitir. C tanabilir (portable) bir dildir. Yani herhangi bir C program hibir deiiklie uramadan, veya ok az bir deiimle, baka bir derleyicide ve/veya iletim sisteminde derlenebilir. rnein, Windows iletim sistemlerinde yazlan bir C kodu, Linux, UNIX veya VAX gibi iletim sistemlerinde de derlenebilir. Tanabilirlik, herkesin kabul ettii bir standart ile gerekletirilebilir. Bugn, C Programla Dili iin American National Standards Institute (ANSI) kurumunun Mart 2000'de belirledii C99: ISO/IEC 9899:1999 standart Standart C olarak kabul edilmitir.

1.2 Neden C?
C Programlama Dili'ni popler klan nemli nedenler aada listelenmitir:

C, gl ve esnek bir dildir. C ile iletim sistemi veya derleyici yazabilir, kelime ilemciler oluturabilir veya grafik izebilirsiniz. C, iyi bir yazlm gelitirme ortamna sahiptir. C, zel komut ve veri tipi tanmlamasna izin verir. C, tanabilir bir dildir. C, geliimini tamamlam ve standard olumu bir dildir. C, yapsal bir dildir. C kodlar fonksiyon olarak adlandralan alt programlardan olumutur. C++, Java, JavaScript, JavaApplet, PHP, C#, ... gibi diller C dilinden esinlenmitir.

1.3 lk C Program
Program 1.1 de verilen C program derlendikten sonra, ekrana 'Merhaba Dnya!' yazsn basan yaln bir C programdr. Satr balarna yerletirilen 1:, 2: 3: ... rakamlarnn yazlmasna gerek yoktur. Bu rakamlar sadece daha sonra program ile ilgili aklama yaplrken, ilgili satrda bulunan kodlar izah edilirken kullanlacaktr. Bu programn bilgisayarda ilk.c ad ile kaydedilmitir. Program 1.1: Derlendikten sonra ekrana 'Merhaba Dnya!' yazar
01: /* ilk.c: ilk C programi */ 02: #include <stdio.h> 03: 04: main() 05: { 06: printf("Merhaba Dnya!\n"); 07: } /* ... */

Programda, 1. satrda /* ... */ sembolleri grlmektedir. Bu ifadeler arasnda yazlan herhangi bir metin, ilem vb. satrlar, derleyici tarafndan ilenmez (deerlendirilmez). Yani /* */ifadeleri aklama operatrdr.
NOT Aklama operatr olarak C++ tarz iki-bl (//) de kullanlmaktadr. Gnmzde birok C derleyicisi // operatrn desteklemektedir. Bu operatr kullanmadan nce derleyicinizin bu operatr desteklediinden emin olun.
/* Bu satrlar derleyici tarafndan deerlendirilmez. Ayrca programn alma hzn da deitirmez. */ // Bu satrlar derleyici tarafndan // deerlendirilmez. Ayrca programn // alma hzn da deitirmez. C++ tarz C tarz

#include <stdio.h>

2. satrdaki #include deyimi, programda eklenecek olan balk dosyann iaret eder. Bu rnekte verilen balk dosyas (header file) stdio.h dir. #include <stdio.h> ifadesi stdio.h dosyasnn derleme ilemine dahil edileceini anlatr.
main()

4. satrdaki main() zel bir fonksiyondur. Ana program bu dosyada saklanyor anlamndadr. Programn yrtlmesine bu fonksiyondan balanr. Dolaysyla her C programnda bir tane main() adl fonksiyon olmaldr.
printf()

6. satrdaki printf() standart ktphane bulunan ekrana formatl bilgi yazdrma fonksiyondur. stdio.h dosyas bu fonksiyonu kullanmak iin program bana ilave edilmitir. Aadaprintf() fonksiyonunun basit kullanm gsterilmitir.

rnek kullanm ekli


printf("Element: Aluminyum"); printf("Atom numaras = %d",13); printf("Younluk = %f g/cm3",2.7); printf("Erime noktas = %f derece",660.32);

Ekranda yazlacak ifade


Element: Aluminyum Atom numaras = 13 Younluk = 2.7 g/cm3 Erime noktas = 660.32 derece

1.4 Balk Dosyalar


C dilinde bir program yazlrken, balk dosyas (header file) olarak adlandrlan bir takm dosyalar #include nilemcisi kullanlarak program iine dahil edilir. C ktphanesinde bulunan birok fonksiyon, balk dosyalar iindeki baz bildirimleri kullanr. Bu tr dosyalarn uzants .h dir. ANSI C'deki standart balk dosyalar unlardr:
assert.h ctype.h errno.h float.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stddef.h stdio.h stdlib.h string.h time.h

Bir ok C derleyicisinde yukardakilere ek olarak tanmlanm balk dosyalar da vardr. Bunlar derleyicinin yardm ksmndan veya derleyicinin kullanm klavuzundan renilebilir. programnda kullanlan balk dosyas stdio.h, #include <stdio.h> ifadesi ile derleme ilemine dahil edilmitir. stdio.h standard giri/k (STandarD-Input-Output) ktphane fonksiyonlar iin baz bildirimleri barndran bir dosyasdr. Programda kullanlan printf() fonksiyonunu kullanmadan nce bu balk dosyas programn bana mutlaka ilave edilmelidir. Aksi halde derleme esnasnda
ilk.c undefined reference to _printf

eklinde bir hata mesaj ile karlalr.

1.5 Kaynak Kodunun Derlenmesi


C programlar veya kaynak kodlar (source code) uzants .c olan dosyalarda saklanr. Kaynak kod, bir C derleyicisi (C compiler) ile nesne koduna (object code) daha sonra uygun bir balayc (linker) program ile iletim sistemininde altrlabilen (executable) bir koda dntrlr. Baz iletim sistemleri ile kullanlan C Derleyicileri ve bu derleyicilerde ilk.c programnn komut satrnda nasl derlenecei Tablo 1.1'de verilmitir. Eer ismi geen derleyicinin bir editr varsa ilk.c bu editr de derlenebilir.

Tablo 1.1: letim sistemleri, baz derleyiciler ve derleme komutlar


letim Sistemi Derleyici Microsoft C Borland Turbo C Web Borland C Zortec C GCC (GNU Compiler Collection) Windows iin Web GCC (GNU Compiler Collection) Web Derleme
cl ilk.c tcc ilk.c bcc ilk.c ztc ilk.c gcc ilk.c -o ilk.exe gcc ilk.c -o ilk

altrma
ilk.exe ilk.exe ilk.exe ilk.exe ilk.exe ./ilk ilk

MS-DOS / Windows

UNIX / Linux

veya nice

Bunlarn dnda, komut satrn kullanmadan, kodlarnz Windows ortamnda alan GCC tabanl DevC++ veya Salford Plato3 derleyicileri ile derlemek mmkn. Bu tip derleyicilerde hata ayklama ilemini kolaylatrmak iin kodlar farl renkte gsterilir. Fakat program ktlar iin kullanlan ekran klasik DOS ekrandr. ekil 1.1 ve 1.2"de bu programlarn ekran grntleri verilmitir.

ekil 1.1: DevC++ derleyicine ait editr. Derleme ve altrma ilemleri ara ubuu zerindeki butonlarla yaplr.

ekil 1.2: Silverfrost Salford (Plato3) derleyicine ait editr. Derleme, balama ve altrma ilemleri ara ubuu zerindeki butonlarla yaplr. Derslerimizde kullanlan kaynak kodlar, Turbo C ve GCC derleyicileri ile komutsatrnda derlenmitir. Turbo C derleyicisi istee bal editrden veya komut satrndan derlenebilir. Editr balatmak iin C:\TC> dizini altndaki TC.EXE dosyasnn altrlmas yeterlidir. ekil 1.3'de Turbo C editr ortam gsterilmitir.

ekil 1.3: Turbo C derleyicisine ait editr. Derleme iin F9, Derleme balama ve altrma ilemleri iin CTRL+F9 tu kombinasyonu kullanlabilir..
NOT DevC++, Salford, GCC ve Turbo C derleyicilerini C/C++ Derleyicileri ksmnda bulabilirsiniz.
ilk.c

nin Borland Turbo C ve GCC Programlar ile derlenmesi ve altrlmas:


Linux (GCC)
$ gcc ilk.c -o ilk $ ./ilk

DERLEME ve ALITIRMA
MS DOS (Turbo C)
C:\TC> tcc ilk.c C:\TC> ilk.exe ilk.c

nin kts:

IKTI
Merhaba Dnya!

1.6 C Kodlarnn Temel zellikleri


Bir C program aada verilen zellikleri mutlaka tamaldr.

Yazlmda kullanlacak olan her fonksiyon iin ilgili balk dosyas programn bana ileve edilmedlidir. Her C program main() fonksiyonunu iermelidir. Program iinde kullanlacak olan deikenler ve sabitler mutlaka tanmlanmaldr. Satrn sonuna ; iareti konmaldr. Her bloun ve fonksiyonun balangc ve bitii srasyla { ve } sembolleridir. C dilinde yazlan kodlarda kk-byk harf ayrm vardr (case sensitive). rnein A ile a derleyici tarafndan farkl deerlendirilir. Aklama operatr /* */ sembolleridir.

1.7 Kod Yazm iin Baz Tavsiyeler


Program aklamalar ve dkman hazrlama program yazldka yapn! Bu unutulmamas gereken ok nemli husustur. Deiken, sabit ve fonksiyon adlar anlaml kelimelerden seilip yeterince uzun olmaldr. Eer bu isimler bir ka kelimeden oluacak ise, kelimeler alt izgi ( _ ) ile ayrlmaldr veya her kelime byk harfle balamaldr. rnein:
int son_alinan_bit; void KesmeSayisi(); float OrtalamaDeger = 12.7786;

Sabitlerin btn harflerini byk harfle yazn. rnein:


#define PI 3.14; const int STATUS=0x0379;

Her alt yapya girerken birka boluk veya TAB tuunu kullann. Bu okunabilirlii arttracaktr. rnein:
k = 0; for(i=0; i<10; i++) { for(j=0; j<i; j+=2) { do{ if( j>1 )

k = i+j;

x[k] = 1.0/k; }while(k!=0); } }

Aritmetik operatrler ve atama operatrlerinden nce ve sonra boluk karakteri kullann. Bu, yazlan matematiksel ifadelerin daha iyi anlalmasn salayacaktr.rnein:
h_max = pow(Vo,2) / (2*g);

Tf Vy y z

= = = =

2*Vo/g; Vo - g*t; Vo*t - (g*t*t)/2.0; ( a*cos(x) + b*sin(x) )*log( fabs(y) );

Program bittikten sonra tekrar tekrar programnz inceleyerek, programnz daha iyi ekilde yazma yollarn arayn ve ayn fonksiyonlar daha ksa algoritmalarla ve/veya daha modler ekilde elde etmeye aln.

Ders 2: Veri Tipleri, Deikenler ve Sabitler


Giri
Orta ve yksek seviyeli dillerin hemen hemen hepsinde veri tipi ve deiken kavram bulunmaktadr. Bu ksmda C programlama dilindeki temel veri tipleri, tanmlayclar, deikenler ve sabitler konu edilecektir.

2.1 Veri Tipleri


Veri tipi (data type) program iinde kullanlacak deiken, sabit, fonksiyon isimleri gibi tanmlayclarn tipini, yani bellekte ayrlacak blgenin bykln, belirlemek iin kullanlr. Bir programc, bir programlama dilinde ilk olarak renmesi gereken, o dile ait veri tipleridir. nk bu, programcnn kullanaca deikenlerin ve sabitlerin snrlarn belirler. C programlama dilinde drt tane temel veri tipi bulunmaktadr. Bunlar:
char int float double

Fakat baz zel niteleyiciler vardr ki bunlar yukardaki temel tiplerin nne gelerek onlarn trevlerini oluturur. Bunlar:
short long unsigned

Bu niteleyiciler sayesinde deikenin bellekte kaplayaca alan istee gre deitirilebilir. Ksa (short), uzun (long), ve normal (int) tamsay arasnda yalnzca uzunluk fark vardr. Eer normal tamsay 32 bit (4 bayt) ise uzun tamsay 64 bit (8 bayt) uzunluunda ve ksa tamsay 16 biti (2 bayt) gemeyecek uzunluktadr. aretsiz (unsigned) n eki kullanld taktirde, veri tipi ile saklanacak deerin sfr ve sfrdan byk olmas salanr. aretli ve iaretsiz verilerin bellekteki uzunluklar ayndr. Fakat, iaretsiz tipindeki verilerin st limiti, iaretlinin iki katdr.

NOT Ksa ve uzun tamsay tutacak tanmlayclar iin int anahtar kelimesinin yazlmasna gerek yoktur.
short s; long k; /* short int s; anlamnda */ /* long int k; anlamnda */

Bir C program ierisinde, veri tiplerinin bellekte kaplad alan sizeof operatr ile renilebilir. lgi cekici olan, bu alanlarn derleyiciye ve iletim sistemine bal olarak deiiklik gstermesidir. Program 2.1'de, sizeof operatr kullanlarak, veri tiplerinin bellek uzunlularnn nasl ekrana yazdrlaca gsterilmitir. Programn kts, farkl derleyiciler ve iletim sisteminde denendiinde bu durum daha iyi anlalr. Ltfen inceleyin. Program 2.1: Deiken tipleri ve trevlerinin bellekte kapladklar alanlar
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: /* 02prg01.c : sizeof operatrnn kullanm */ #include <stdio.h> main() { printf( printf( printf( printf( printf( char)); printf( short)); printf( int)); printf( long)); printf( printf( printf( double)); }

"char "short "int "long "unsigned char

: : : : :

%d %d %d %d %d

bayt\n", bayt\n", bayt\n", bayt\n", bayt\n",

sizeof(char)); sizeof(short)); sizeof(int)); sizeof(long)); sizeof(unsigned

"unsigned short : %d bayt\n", sizeof(unsigned "unsigned int "unsigned long "float "double "long double : %d bayt\n", sizeof(unsigned : %d bayt\n", sizeof(unsigned : %d bayt\n", sizeof(float)); : %d bayt\n", sizeof(double)); : %d bayt\n", sizeof(long

IKTI
Windows (32 bit) Turbo C
char short int long unsigned char unsigned short unsigned int unsigned long float double long double bayt int : : : : : : : : : : : 1 bayt 2 bayt 2 bayt 4 bayt 1 bayt 2 bayt 2 bayt 4 bayt 4 bayt 8 bayt 10

Windows (32 bit) Salford


char short int long unsigned char unsigned short unsigned int unsigned long float double long double : : : : : : : : : : : 1 bayt 2 bayt 4 bayt 4 bayt 1 bayt 2 bayt 4 bayt 4 bayt 4 bayt 8 bayt 10 bayt

Linux (32 bit) GCC


char short int long unsigned char unsigned short unsigned int unsigned long float double long double bayt : : : : : : : : : : : 1 bayt 2 bayt 4 bayt 4 bayt 1 bayt 2 bayt 4 bayt 4 bayt 4 bayt 8 bayt 12

Linux (64 bit) GCC


char short int long unsigned char unsigned short unsigned int unsigned long float double long double bayt : : : : : : : : : : : 1 bayt 2 bayt 4 bayt 8 bayt 1 bayt 2 bayt 4 bayt 8 bayt 4 bayt 8 bayt 16

veritipi ve trevleri ile hesaplanabilecek en kk ve en byk tamsaylar iin aadaki forml kullanlabilir:

Alt snr = -28*sizeof(tip) st snr = 28*sizeof(tip)-1 rnein 4 baytlk bir int tipi iin: Alt snr = -28*sizeof(int) = -232 = -2147483648 st snr = 28*sizeof(int)-1 = 232-1 = 2147483647 Tablo 2.1'de btn tipler, bellekte kapladklar alanlar ve hesaplanabilcek (bellekte doru olarak saklanabilecek) en byk ve en kk saylar listelenmitir.

Veri Tipi
char unsigned char short int unsigned short int int unsigned int long int unsigned long int float

Aklama Tek bir karakter veya kk tamsay iin Ksa tamsay iin Tamsay iin Uzun tamsay iin Tek duyarl gerel say iin (7 basamak) ift duyarl gerel say iin (15 basamak)

Bellekte igal ettii boyut (bayt) 1 2 4 -128 0 -32,768 0

Alt snr 127 255 32,767 65,535

st snr

-2,147,483,648 2,147,483,647 0 4,294,967,295 9,223,372,036,854,775,807 9,223,372,036,854,775,808 0 18,446,744,073,709,551,615 +3.4e +/- 38 +1.7e +/- 308

4 8

-3.4e +/- 38 -1.7e +/- 308

double

Tablo 2.1: Deiken tipleri ve bellekte kapladklar alanlar

2.2 Deikenler
Deikenler bilgisayarn geici belleinde bilginin sakland gzlere verilen sembolik adlardr. Bir C programnda, bir deiken tanmlandnda bu deiken iin bellekte bir yer ayrlr. Her deikenin tuttuu deerin nasl bir veri olduunu gsteren (nceki blmde anlatlan) bir veri tipi vardr. C programlama dilinde, deikenler ve sabitler programn banda bulunmaldr. Baz uygulamalarda deikenin bir balang deerinin olmas istenir. Byle durumlarda deiken bildirilirken balang deeri verilebilir. rnein:

char isim='X', z; /* deer atamak zorunlu deil */ int sayi=0, n; float toplam=0.0, sonuc=22.14;

Deiken isimleri verirken baz kurallara uymak zorunludur. Bunlar:


Deiken adlar en fazla 32 karakterden oluabilir. 32 karakterden uzun deiken adlar ilk 32 karakteri deerlendirilir. Geriye kalan karakterler ileme tabi tutulmaz. Deiken adlar ingiliz alfabesinde bulunan karakterler (A-Z) veya (a-z) yada rakamlar (0-9) ile yazlmaldr. Trke karakterler, zel karakter veya boluk karakteri kullanlamaz. Deiken adlar herhangi bir rakam ile balayamaz. Ilk karakter bir harf olamaldr. Sonrakiler rakamlardan oluabilir. Aada verilen kelimeler ANSI C 'nin anahtar kelimeleridir (key words) ve deiken ismi olarak kullanlamaz.
auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while

Bu kurallara gre aaadaki deiken (sabit, fonksiyon) adlarnn geerliliini inceleyiniz.


Deiken/Sabit/Fonksiyon/Yap Ad Geerlilik asal geerli Momentum geerli ivme geerli olasilik geerli IsikHizi geerli isik_hizi geerli isik hizi geersiz k_hz geersiz 1Bit geersiz typedef geersiz Aklama Alt izgi karakteri '_' kullanlabilir Boluk karakteri kullanlamaz Trke karakter kullanlamaz rakam ile balanamaz Anahtar kelimelerden birisi kullanlamaz

2.3 Sabitler
Sabit bildirimi, balang deeri verilen deiken bildirimi gibi yaplr. Ancak, veri tipinin nne const anahtar szc konmaldr. rnein:
const const const const float PI = 3.142857; double NOT= 12345.8596235489; int EOF= -1; char[] = "devam etmek iin bir tua basn...";

gibi sabit bildirimleri geerli olup bunlarn ierikleri program boyunca deitirilemez. Yalnzca kullanlabilir. Genellikle, sabit olarak bildirilen deiken isimleri byk harflerle, dier deiken isimlerinin ise kk harflerle yazlmas (gsterilmesi) C programclar tarafndan geleneksel hale gelmitir. Birok C programnda sabitler #define nilemci komutu ile de tanmlandn grebilirsiniz. Bu komutla sabit bildirimi, bir program parasna ve makro fonksiyon tanmlamas yaplabilir. Bir program gelitirilirken simgesel sabitlerin kullanlmas programn okunurluunu arttrr ve bazen gerekli de olabilir. Aada verilen simgesel sabit bildirimleri geerlidir. #define nilemcisi ile makro fonksiyon tanmalama ilemi, Blm 8 ve Blm 20'de anlatlacaktr.
#define MAX 100 #define DATA 0x0378 #define YARICAP 14.22

2.4 Rakamsal Bilgiler


C programlama dili iinde tanmlanabilecek sabit rakamlar rakamsal bilgi (literal) olarak adlandrlr. Her veri tipi kendi rakamsal bilgisine sahiptir. Bu bilgiler, kaynak kod ierisinde, zel deerleri ifade eder. rnein aadaki atama ileminde 25 ve 17.2 saylar gibi:
i = 25; r = 17.2; /* 25, int tipinde bir rakamsal bilgidir */ /* 17.2, double tipinde bir rakamsal bilgidir */

C dilinde btn tamsay sabitler varsaylan (default) olarak int tipinde, gerel say sabitler varsaylan olarak double tipindedir. Ancak sabitleri gsteren rakamlarn sonuna eklenecek U (veya u), L (veya l) ve F (veya f) harfleri ile bu durum deitirilebilir. Bu yzden, aadaki atamalar ayn anlamda deildir.
i i i i i = = = = = 25; 25U; 25L; 25UL; 25L; /* /* /* /* /* int unsigned int long int unsigned long long int rakam rakam rakam rakam rakam */ */ */ */ */

r = 17.2; /* double r = 17.2L; /* long double r = 17.2F; /* float

rakam */ rakam */ rakam */

Tamsay (int) rakamsal bilgiler, 8 (oktal) ve 16 (hexadesimal) say tabannda da gsterilebilir. Bunun iin sabit rakamn bana, 8 taban iin 0 (sfr) ve 16 tabann iin 0x sembolleri eklenir. 16'lk sistemdeki hafler byk (A, B, C, D, E ve F) veya kk (a, b, c ,d, e ve f) olabilir. Buna gsterime gre, aadaki atmalar ayn anlamadadr:
i i i i = = = = 75; 0113; 0x4b; 0x4B; /* /* /* /* i i i i = = = = 75, 10 tabannda */ 75, 8 tabannda */ 75, 16 tabannda */ 75, 16 tabannda */

Gerel saylar ondalkl veya stel olmak zere iki biimde gsterilebilir. rnein 123.456 saysnn ayn anlama gelen drt farkl gsterimi aada verilmitir. stel gsterimde, 1.23456e+2 veya 1.23456E+2 says matematikteki 1.23456 x 102 gsterimi ile edeerdir.
x x x x = = = = 123.456; 123.456e+0; 1.23456e+2; 1234.56E-1; /* /* /* /* ondalkl gsterimi */ stel gsterim */ stel gsterim */ stel gsterim */

Karakter sabitler, bir harf iin tek trnak, birden ok karakter iin ift trnak iinde belirtilirler.
'A' "Merhaba Dunya" /* bir karakter */ /* bir karakter kmesi */

Program 2.1'de, program iinde tanmlanan deiken sabitlerin ekrana nasl yazdrlaca gsterilmitir. Program 2.2: Deikenlerin ve sabitlerin ekrana yazdrlmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: /* 02prg02.c : Deikenler ve sabitlerin ekrana yazdrlmas */ #include <stdio.h> #define PI 3.141593 int main() { const int MAX = 100; char c = 'a'; char *s = "Bu bir sicim"; int i = 22; float f = 33.3; double d = 44.4; printf("PI = printf("MAX= printf("c = printf("s = printf("i = printf("f = printf("d = return 0; } %lf\n",PI); %d\n", MAX); %c\n", c); %s\n", s); %d\n", i); %f\n", f); %lf\n",d);

IKTI
PI = MAX= c = s = i = f = d = 3.141593 100 a Bu bir sicim 22 33.299999 44.400000

2.5 Deiken Bildirim Yerleri ve Trleri


Yerel (local) Bildirim Yerel deikenler kullanld fonksiyon ierisinde bildirilir. Yalnzca bildirildii fonksiyon ierisinde tannr ve kullanlabilir.
int topla(int a,int b) { /* yerel (local) deiken c nin bildirimi */ int c; c = a + b; return c; }

Genel (general) Bildirim Genel deikenler btn fonksiyonlarn dnda bildirilir. Bir deiken program boyunca srekli olarak kullanlyorsa genel olarak bildirilmelidir.
#include <stdio.h> void karesi(); /* m ve n global tip deikendir. Bu iki deiken tm program boyunca kullanlmaktadr. */

int m,n; main() { m=7; karesi(); printf("%d nin karesi %d dir",m,n); } void karesi(){ n = m*m; }

2.6 Tip Dnmleri


Bir forml ierisinde bir ok deiken veya sabit olabilir. Bu deiken ve sabitler birbirinden farkl tipte olursa, hesap sonucunun hangi tipte olaca nemlidir. Bir bantda, ierii dnme urayan deikenler eski ieriklerini korurlar. Dntrme ilemi iin geii bellek alan kullanlr; dntrlen deer kullanldktan sonra o alan serbest braklr.
char kr; int tam; long int ltam; unsigned int utam; short int stam; float f; double d;

bildirimlerine gre:
Bant ------kr+5 kr+5.0 d+tam f+d-2 utam-tam ltam*tam tam/2 tam/2.0 Sonu Tipi ---------int double double double unsigned long int double

NOT Tamsaylar aras blme kesme hatalarna (truncation error) neden olur. Bunun anlam iki tamsaynn oran yine bir tamsaydr. rnein: 4/2=2; ama 3/2=1 (1.5 deil).

Bir deikenin sabit deerin veya bantnn nne tr veya tak (cast) yazlarak sonucun hangi tip kmas istendii sylenebilir. Genel yazm biimi:
(tr tipi) bant;

rnein:
int x=9; float a,b,c; double d; ... a = x/4; b = x/4.0; c = (float) x/4;

ileminin sonucunda a deikenine 2.0, b ve c deikenlerine 2.25 deeri aktarlr. Yani 9/4 ile 9/4.0 farkl anlamdadr.

Ders 3: Operatrler
Giri
Operatrler, deikenler veya sabitler zerinde matematiksel ve karlatrma ilemlerini yapan simgelerdir. Yani bir operatr bir veya daha fazla nesne (deiken) zerinde ilem yapan sembollerdir. Bu ksmdam aritmetik operatrler, atama operatrleri ve sizeof operatr anlatcaktr. Karlatrma Operatrleri, Mantksal Operatrler ve Bit Dzeyinde ilem yapan operatrler daha sonraki blmlerde incelenektir.

3.1 Aritmetik Operatrler


Deiken veya sabitler zerinde temel aritmetik ilemleri gerekleyen operatrlerdir. Bunlar Tablo 3.1'de listelenmitir. Tablo 3.1: Aritmetik Operatrler
Operatr
+ * / %

Aklama toplama karma carpma blme artk blme

rnek
x + y x - y x * y x / y x % y

Anlam x ve y nin toplam x ve y nin fark x ve y nin arpm x ve y nin oran x / y den kalan say

3.2 Atama Operatrleri


Bu operatrler bir deikene, bir sabit vaya bir aritmetik ifade atamak (eitlemek) iin kullanlr. Birleik atama: baz ifadelerde ilem operatr ile atama operatr birlikte kullanlarak, ifadeler daha ksa yazlabilir. Eer ifade
deiken = deiken [operatr] aritmetik ifade;

eklinde ise, daha ksa bir biimde


deiken [operatr]= aritmetik ifade;

olarak yazlabilir. Bu operatrler Tablo 3.2'de listelenmitir. Tablo 3.2: Atama Operatrleri
Operatr
= += -= *= /= %= ++ --

Aklama atama ekleyerek atama eksilterek atama arparak atama blerek atama blp, kalann atama bir arttrma bir azaltma

rnek
x = 7; x += 3 x -= 5 x *= 4 x /= 2 x %= 9 x++

Anlam
x = 7; x = x + 3 x = x - 5 x = x * 4 x = x / 2 x = x % 9 x = x + 1 x = x - 1

veya ++x x-- veya --x

Bu tanmlamalara gre, aadaki atamalar inceleyiniz:


/* bir arttrma ilemleri */ i++; ++i; i += 1; i = i + 1;

/* karmak atamalar */ f *= i; // f = f * i; anlamnda f *= i+1; // f = f * (i+1); anlamnda z /= 1 + x; // z = z / (1+x); anlamnda

Bir arttrma veya eksiltme operatrlerini kullanrken dikkatli olunmaldr. nk aadaki trden atamalar bazen karkla neden olur.
a = 5; b = a++; c = ++a; // a = 5 // a = 6 ve b = 5 // a = 7 ve c = 7

Program 3.1: Aritmetik ve atama operatrlerinin kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: /* 03prg01.c: Aritmetik ve atama operatorlerinin kullanimi */ #include <stdio.h> main() { int x, y; x = 1; y = 3; y); x = x + y; printf("x <- x + y x); x = 1; /* x e tekrar 1 degeri ataniyor */ x += y; printf("x += y atamasinin sonucunda x=%d dir\n", x); return 0; } atamsinin sonucunda x=%d dir\n", /* /*

/* yerel degikenlerin bildirimi */ x in baslangic degeri */ y nin baslangic degeri */

printf(" x = %d ve y = %d, olarak veriliyor.\n", x,

IKTI
x = 1 ve y = 3, olarak veriliyor. x <- x + y atamasinin sonucunda x=4 dir x += y atamasinin sonucunda x=4 dir

3.3 sizeof Operatr


Veri tiplerinin, deikenlerin ve dizilerin bellekte kaplad alan sizeof operatr ile renilebilir. Genel kullanm:
sizeof(nesne)

eklindedir. Program 3.2'de bu operatrn nasl kullanld gsterilmitir.

Program 3.2: sizeof operatrn kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: /* 03prg02.c sizeof operatrnn deiik nesnelerle kullanm */ #include <stdio.h> int main(){ int int */ double d; double mizan[6]; char char /* bir gercel say */ /* 6 elemanl bir gercel dizi */ i; dizi[5]; /* bir tamsay */ /* 5 elemanl bir tamsay dizi

c; /* tek bir karakter */ str[] = "masa"; /* bir karakter topluluu */ = %d\n",sizeof(int)); = %d\n",sizeof(i)); = %d\n\n",sizeof(dizi));

printf("sizeof(int) printf("sizeof(i) printf("sizeof(dizi)

printf("sizeof(double)= %d\n",sizeof(double)); printf("sizeof(d) = %d\n",sizeof(d)); printf("sizeof(mizan) = %d\n\n",sizeof(mizan)); printf("sizeof(char) printf("sizeof(c) printf("sizeof(str) return 0; } = %d\n",sizeof(char)); = %d\n",sizeof(c)); = %d\n",sizeof(str));

IKTI
sizeof(int) sizeof(i) sizeof(dizi) = 4 = 4 = 20

sizeof(double)= 8 sizeof(d) = 8 sizeof(mizan) = 48 sizeof(char) sizeof(c) sizeof(str) = 1 = 1 = 5

Programda sizeof(int) deeri ile sizeof(i) deerinin ayn olduu grlr. dizinin boyutu 5 olduu iin, sizeof(dizi) = sizeof(int)*5 = 20 eklinde hesaplanmaktadr. Dierleri iin benzer durum sz konusu. Ancak, str 4 elemanl bir dizi olduu halde sizeof(str) = 5 dir. Neden? Bunu ilerideki blmlerde reneceiz.

Ders 4: Temel Giri/k Fonksiyonlar


Giri
Temel giri/k fonksiyonlar, btn programla dillerinde mevcuttur. Bu tr fonksiyonlar, kullancya ekrana veya yazcya bilgi yazdrmasna, ve bilgisayara klavyeden veri girii yapmasna izin verir. Temel giri/k fonksiyonlar kullanlrken stdio.h balk dosyas programn bana eklenmelidir. Bu ksmda, en ok kullanlan giri/k fonksiyonlar anlatlacaktr.

4.1 printf() Fonksiyonu


Standart C ktphanesinde bulunan printf() fonksiyonu, deikenlerin tuttuu deerleri, onlarn adreslerini veya bir mesaj ekrana belli bir dzenle (format) standart ka (stdout), yani ekrana, yazdrmak iin kullanlan fonksiyondur. Daha nce yazlan rnek programlarda printf() fonksiyonundan yararlanmtk. imdi bu fonksiyonun nasl kullanldna bakalm. Genel yazm biimi:
int printf(const char *format, ...);

Basit olarak ekrana Hata

olutu!..

eklinde bir mesaj yazrma ilemi:

printf("Hata Olutu!..");

eklindedir. ou zaman ekrana, programda kullanlan bir deikenin deeri yazdrlmak istenebilir. rnein ekrana bir tamsay deikeninin ieriini basrmak iin, printf()
.... int x = 12; printf("x in deeri %d dir", x); ....

gibi kullanlr. Bu program parasnn ekran kts yle olacaktr:


x in deeri 12 dir

Bu rnekte printf fonksiyonuna iki parametre aktarlmtr. Birincisi ekranda gsterilecek ve ift trnaklar arasna yazlan ifadeler, ikincisi ise ekranda saysal deeri gsterilmek istenen deiken (x).
*format

ksmdan olumaktadr:

I. II.

Dz metin (literal string): yazdrlmak istenen ileti. rnein: printf("Ben gelmedim kavga iin..."); gibi. Konrol karakterleri (escape squence): deikenlerin ve sabitlerin nasl yazlacan belirtmek veya imlecin alt satra geirilmesi gibi baz ilemlerin gerekletirilmesi iin kullanlr. Bu karakterler Tablo 4.1'de listelenmitir. rnein: printf("\tDostun evi gnldr...\n"); gibi. Tablo 4.1: Kontrol karakterleri
Karakter
\a \b \f \n \r \t \v \" \' \\ %%

Anlam Ses retir (alert) imleci bir sola kaydr (backspace) Sayfa atla. Bir sonraki sayfann bana ge (formfeed) Bir alt satra ge (newline) Satr ba yap (carriage return) Yatay TAB (horizontal TAB) Dikey TAB (vertical TAB) ift trnak karakterini ekrana yaz Tek trnak karakterini ekrana yaz \ karakterini ekrana yaz % karakterini ekrana yaz

III.

Tip belirleyici (conversion specifier): % iareti ile balar ve bir veya iki karakterden oluur (%d gibi). Ekrana yazdrlmak istenen deikenin tipi, % iaretinden sonra belirtilir (Bkz. Tablo 4.2) rnein: printf("x in deeri %d dir"); gibi. Tablo 4.2: Tip karakterleri
Tip Karakteri
%c %s %d %ld %u %lu %f %lf

Anlam tek bir karakter karakter dizisi (string) iaretli ondalk tamsay uzun iaretli ondalk tamsay iaretsiz ondalk tamsay iaretsiz uzun tamsay Gerel say ift duayarl gerel say

Yazdrlacak veri tipi


char char int, short long unsigned int, unsigned short unsigned long float double

Tip karakterlerini kullanarak, birden ok veri tipi yazdrlabilir. rnein:


... int float char not= 12; pi = 3.14; kr = 'A';

printf(" not = %d , pi = %f ve kr = %c dir", not, pi, kr); ...

gibi.

fonksiyonu esnektir. Parametreler herhangi bir C deyimi olabilir. rnein x ve y nin toplam yle yazlabilir:
printf() printf("%d", x+y); printf

fonksiyonu kullanm Program 4.1'de verilmitir.

Program 4.1: printf() fonksiyonunun kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: /* 04prg01.c Saysal deerleri ekrana yazdrmak iin printf fonksiyonunun kullanm */ #include <stdio.h> main() { int a = 2, b = 10, c = 50; float f = 1.05, g = 25.5, h = -0.1, yuzde; printf("3 tamsayi : %d %d %d\n", a, b, c); printf("3 tamsayi [TAB] : %d \t%d \t%d\n", a, b, c); printf("\n"); printf("3 reel sayi (yanyana) : %f %f %f\n", f, g, h); printf("3 reel sayi (altalta) : \n%f\n%f\n%f\n\n", f, g, h); yuzde = 220 * 25/100.0; printf("220 nin %%25 i %f dir\n", yuzde); printf("%f/%f isleminin sonucu = %f\n", g, f, g / f); printf("\nprogram sonunda beep sesi cikar...\a"); return 0; }

IKTI
3 tamsayi : 2 10 50 3 tamsayi [TAB] : 2 10

50

3 reel sayi (yanyana) : 1.050000 25.500000 -0.100000 3 reel sayi (altalta) : 1.050000 25.500000 -0.100000 220 nin %25 i 55.000000 dir 25.500000/1.050000 isleminin sonucu = 24.285715 program sonunda beep sesi cikar...

fonksiyonunun geri dn deeri int tipindedir. Bu geri dn deeri ktnn ka karakter olduunu gsterir. Yani, printf fonksiyonu, *format ile tanmlanm karakter topluluunun ka bayt olduu hesaplar. Program 4.2, printf'in bu ynnde ortaya karan bir programdr.
printf

Program 4.2: printf() fonksiyonunun kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: /* 04prg02.c printf fonksiyonunun geri dn deerini gsterir */ #include <stdio.h> int main() { int karSay; int sayi = 1234; karSay = printf("Ugurlu sayim = %d\n",sayi); printf("Ust satirda karakter sayisi: %d dir\n", karSay); return 0; }

IKTI
Ugurlu sayim = 1234 Ust satirda karakter sayisi: 20 dir

11. satrdaki ilemle, hem ekrana Ugurlu sayim = 1234 iletisi bastrlmakta, hem de karSay deikenine bu iletinin uzunluu atanmaktadr. Ekrana baslan karakterlerin says (\n karakteri dahil) 20 dir.

4.2 scanf() Fonksiyonu


Birok programda ekrana verilerin bastrlmasnn yansra klavyeden veri okunmas gerekebilir. scanf() fonksiyonu klavyeden veri okumak iin kullanlan fonksiyondur. printf() gibi scanf()fonksiyonuda Tablo 4.1 ve Tablo 4.2'de verilen karakterleri kullanr. rnein klaveden bir x tamsays okumak iin:
scanf("%d",&x);

satrn yazmak yeterli olacaktr. Burada & iareti adres operatr olarak adlandrlr. Klavyeden iki farkl say okunmak istendinde scanf() fonksiyonu yle kullanlabilir:
scanf("%d %f",&x,&y);

veriler klavyeden
16 1.56

yada
16 1.56

veya
16 1.56

ekilinde girilebilir. Program 4.3'de scanf() fonsiyonunun kullanm gsterilmitir.

Program 4.3: scanf() fonksiyonun kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 04prg03.c scanf() fonksiyonu ile int ve float tipindeki verilerin okunmas */ #include <stdio.h> main() { int float

t; g;

printf("Bir gercel sayi girin: "); scanf("%f",&g); printf("Bir tamsayi girin : "); scanf("%d",&t); printf("\n"); printf("\t %f * %f = %f\n",g,g,g*g); printf("\t %d * %d = %d\n",t,t,t*t); return 0; }

IKTI
Bir gercel sayi girin: 1.34 Bir tamsayi girin : 12 1.340000 * 1.340000 = 1.795600 12 * 12 = 144

4.3 puts() Fonksiyonu


Ekrana yazdrlacak ifade bir karakter topluluu ise, printf()'e alternatif olarak puts() fonksiyonu kullanlabilir. Ancak puts(), ekrana bu karakter topluluu yazdktan sonra, imleci alt satra geirir. Buna gre:
printf("Sevgi varln mayasdr.\n");

ile
puts("Sevgi varln mayasdr.");

kullanmlar edeerdir.
puts()

fonksiyonu Tablo 4.1 de verilen kontrol karakterleri ile kullanlabilir.

puts("Bu birinci satr...\nBu ikinci satr."); Bu birinci satr... Bu ikinci satr.

4.4 gets() Fonksiyonu


Klavyeden bir karakter topluluu okumak iin kullanlr. Okuma ilemi yeni satr karakteriyle( \n) karlaslncaya kadar srer. puts() - gets() arsndaki iliki, printf() - scanf() arasndaki gibidir. Yani,
scanf("%s",str);

ile
gets(str);

ayn anlamdadr. puts()

- gets()

fonksiyonlarnn kullanm daha sonra ayrntl ilenecektir.

4.5 getchar() Fonksiyonu


Bu fonksiyon ile standart giriten bir karakter okunur. Program istenen bir yerde dudurup, bir karakater girinceye kadar bekletir. rnein:
for(i=0; i<10; i++) { getchar(); printf("%d\n",i); } ...

Yukardaki program paras 0-9 aras saylar srasyla ekranda gstermek iin kullanlr. Fakat her rakam yazdrlmadan nce klavyeden herhangi bir karakter girip [Enter] tuuna baslmas beklenir. Bu bekleme getchar() fonksiyonu ile gerekletirilir.

4.6 Formatl kt
Bundan nceki programlardaki deikenler serbest biimde (free format), yani derleyicinin belirledii biimde ekrana yazdrlmt. Bazen giri ve kn biimi kullanc tarafndan belirlenmesi gerekebilir. Bu ilem: Tamsaylarda %d yerine %wd Gerel saylarda %f yerine %w.kf Stringlerde %s yerine %ws biimindeki kullanm ile salanr. Burada w yazlacak olan saynn alan genilii olarak adlandrlr. Gerel bir deiken ekrana yazlacaksa, deikenin virglden sonra ka basamann yazdrlaca ksays ile belirlenir. Ancak w > k + 2 olmaldr.
int i=583,j=1453; printf("%d %d\n",i,j); printf("%5d %8d\n",i,j); /* serbest biim */ /* formatl */

program parasnn ekran kts yledir:

IKTI
583 1453 583 1453

Birinci satr serbest formatta ikinci satr ise formatl yazlmtr. i deikeninin tuttuu 583 says %5d formatyla yazdrlnca, bu say iin 5 alan genilii tanmlanr arakasndan sadan balayarak say bu alana yazlr. Benzer olarak j deikeni, 8 alan genilikli bir blgeye yazlr. Gerel saylarda i biraz daha kark. rnein:
int x=123.456; printf("%f\n",x); printf("%8.2f\n",x); /* serbest biim */ /* formatl */

program paras altrldnda aadaki sonu gzlenir: IKTI


123.456001 123.46

Birinci satr serbest formatta ikinci satr ise formatl yazlmtr. kinci satrda x deikeni iin ayrlan alan genilii 8 ve noktadan sonra 2 basamaa kadar hassasiyet nemsenmitir. Dikkat edilirse noktadan sonra say uygun bir ekilde yuvarlanm ve say saa dayal olarak yazlmtr. Program 4.4: printf() in formatl kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: /* 04prg04.c: Formatl kt */ #include <stdio.h> main() { float x = 7324.25, y = 244.531; int i = 1299; char *c = "Merhaba C"; printf("%10d\n" printf("%10s\n" ,i); ,c);

printf("%10.5f\n",x); printf("%10.1f\n",y); return 0; }

IKTI
1299 Merhaba C 7324.25000 244.5

Ders 5: Temel Ktphane Fonksiyonlar


Giri
Bu ksmda, C Programlama Dili'nde sk kullanlan ve dier blmlerde yararlanacamz ktphane fonksiyonlarnn bazlar ilenecektir. Ktphane fonksiyonu C dilinde nceden tanmlanm hazr fonksiyonlardr. C dilinde birok i bu fonksiyonlarla yaplmaktadr. Her ktphane fonksiyonu bir balk dosyasnda tanmlanmtr. Bu yzden bir ktphane fonksiyonunu kullanmadan nce, onun hangi balk dosyas ile kullanlmas gerektiini bilmelisiniz.

5.1 Matematiksel Fonksiyonlar (math.h)


Matematiksel fonksiyonlarn hemen hemen hepsi double veri tipindedir. Bu fonksiyonlardan biri program iinde kullanlacaksa math.h balk dosyas program iine eklenmelidir. En ok kullanlan matematiksel fonksiyonlar Tablo 5.1'de listelenmitir. Tablo 5.1: math.h ktphanesinde tanml baz fonksiyonlar
Fonksiyon Bildirimi
int abs(int x); double fabs(double x); int floor(double x); int ceil(double x); double double double double sqrt(double x); pow(double x, y); log(double x);

Aklama x tamsaysnn mutlak deerini hesaplar x gerel saysnn mutlak deerini hesaplar x'e (x'den byk olmayan) en yakn tamsayy gnderir x'e (x'den kk olmayan) en yakn tamsayy gnderir pozitif x saysnn karekkn hesaplar x deerini hesaplar pozitif x saysnn doal logaritmasn hesaplar, ln(x) pozitif x saysnn 10 tabanndaki logaritmasn hesaplar radyan cinsinden girilien x saysnn sins deerini hesaplar radyan cinsinden girilien x saysnn kosins deerini hesaplar radyan cinsinden girilien x saysnn tanjant deerini hesaplar sins deeri x olan ay gnderir. A -pi/2 ile pi/2 arasndadr. cosins deeri x olan ay gnderir. A -pi/2 ile pi/2 arasndadr. tanjant deeri x olan ay gnderir. A -pi/2 ile pi/2 arasndadr.
y

rnek

Sonu 4 fabs(-4.0) 4.000000


abs(-4) abs(-0.5) ceil(-0.5) sqrt(4.0) pow(2., 3.) log(4.0) log10(4.0) sin(3.14) cos(3.14) tan(3.14) asin(0.5) acos(0.5) atan(0.5)

-1 0 2.000000 8.000000 1.386294 0.602060 0.001593 0.999999 0.001593 0.523599 1.047198 0.463648

double log10(double x); double sin(double x); double cos(double x); double tan(double x); double asin(double x); double acos(double x); double atan(double x);

NOT Bir programda math.h ktphanesi kullanlacakca, GCC derleyicisi lm seenei ile birlikte kullanlmaldr. rnein test.c iinde math.h'i kullanyorsa derleme:
gcc -lm test.c -o test

eklinde yaplmaldr. Aksi halde bir hata mesaj ile karlalr.

Trigonometrik (sin, cos, tan) fonksiyonlar kendisine parametre olarak gelen deeri radyan olarak kabul eder ve sonucu hesaplar. Eer alar derece cinsinden hesaplanmas gerekiyorsa u dnm kullanlanlabilir:
radyan = (3.141593/180.0) * derece;

Program 5.1: sin(), cos(), and tan() fonksiyonlarnn kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: /* 05prg01.c 30 dercelik ann sins, kosins, tanjant ve kotanjant deerleri */ #include <stdio.h> #include <math.h> #define PI 3.141593

int main() { double aci = 30.0; aci *= PI/180.0; /* radyana evir */ sin(aci)); cos(aci)); tan(aci)); 1.0/tan(aci));

puts("30 derecenin"); printf("sinusu : %lf\n", printf("kosinusu : %lf\n", printf("tanjanti : %lf\n", printf("kotanjanti: %lf\n", return 0; }

IKTI
30 derecenin sinusu : 0.500000 kosinusu : 0.866025 tanjanti : 0.577350 kotanjanti: 1.732051

5.2 Standart Ktphane Fonksiyonlar (stdlib.h)


Standart ktphanede, program sonlandran, dinamik bellek ynetiminde kullanlan veya rastgele say retme vb. ilevleri yerine getiren bir ok fonksiyon mevcuttur. Bu ksmda, bunlardan bir ka Tablo 5.2'de listelenmitir. Tablo 5.2: stdlib.h ktphanesinde tanml baz fonksiyonlar
Fonksiyon Bildirimi
int atoi(const char *s); long atol(const char *s); double atof(const char *s); void exit(int durum);

Aklama Bir karakter topluluunu tamsayya evirir

rnek
atoi("-12345")

Sonu -12345

Bir karakter topluluunu uzun tamsayya evirir atol("1234567890") 1234567890 Bir karakter topluluunu gercel sayya evirir Program sonlandrarak kontrol iletim sistemine geri verir. 0 ile RAND_MAX arasnda rastgele say retir. RAND_MAX, stdlib.h iinde tanmlanm bir sembolik sabittir stdlib.h'de tanmlanm iki saydan en byn bulan makro fonksiyon stdlib.h'de tanmlanm iki saydan en kn bulan makro fonksiyon
atof("-123.546") exit(1)

-123.456 50485132 9 5

int rand(void);

rand()

max(a,b) min(a,b)

max(5, 9) min(5, 9)

Program 5.2: rand() fonksiyonu kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: /* 05prg02.c 0-100 arasnda 10 tane rasgele say retir */ #include <stdio.h> #include <stdlib.h> int main() { int i, ri; for(i=1; i<=10; i++) { ri = rand() % 100; /* 0-100 aras tamsay */ printf("\%d\t%d\n",i,ri); } puts("10 tane rasgele sayi uretildi."); return 0; }

IKTI
1 2 3 4 5 6 7 8 9 10 83 86 77 15 93 35 86 92 49 21

5.3 Karakter zerinde lem Yapan Fonksiyonlar (ctype.h)


Tablo 5.3: ctype.h Ktphanesinde tanml fonksiyonlar
Fonksiyon Bildirimi Aklama isalpha(c) c bir harf ise 0 dan farkl, deilse 0 gnderir isalnum(c) c A-Z, a-z veya 0-9 arasnda ise 0 dan farkl, deilse 0 gnderir isascii(c) c bir ASCII karakter ise 0 dan farkl, deilse 0 gnderir isdigit(c) c bir rakam ise 0 dan farkl, deilse 0 gnderir islower(c) c a-z arasnda ise 0 dan farkl, deilse 0 gnderir isupper(c) c A-Z arasnda ise 0 dan farkl, deilse 0 gnderir toascii(c) c says ile verilen ASCII koda sahip karakteri elde eden makro tolower(c) c karakterini kk harfe evirir toupper(c) c karakterini byk harfe evirir rnek
isalpha('a') isalnum('a') isascii('a') isdigit('4') islower('P') islower('P') toascii(65) tolower('D') toupper('b')

Sonu 8 1 1 2 0 4 A d B

Program 5.3: ctype.h ktphansinde bulunan baz makrolarn kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 05prg03.c ASCII kodlar 32-127 arasnda olan karakterler zerinde ctype.h ktphanesinde tanml baz makrolarn kullanm */ #include <stdio.h> #include <ctype.h> int main(void) { int i; char c; for(i=32; i<127; i++) { c = toascii(i); printf("%d\t%c\t%c\t%d\n", i,c,tolower(c),isdigit(c)); } return 0; }

IKTI
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

! " # $ % & ' ( ) * + , . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c

! " # $ % & ' ( ) * + , . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ a b c d e f g h i j k l m n o p q r s t u v w x y z [ \ ] ^ _ ` a b c

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

d e f g h i j k l m n o p q r s t u v w x y z { | } ~

d e f g h i j k l m n o p q r s t u v w x y z { | } ~

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Ders 6: Karlatrma Deyimleri


Giri
Program ierisinde bazen iki veya daha fazla deerin karlatrlmas gerekebilir. Bunun iin, btn programlama dillerinde karlatrma deyimleri mevcuttur. C dili, if, switch ve ? olmak zere tip karlatrma ilemi yapmaya izin verir. Ancak ? bir operatrdr. if karlatrma deyimi ile, dier programlama dilinde olduu gibi if-else yaps da kurulabilir. switch deyimi, bir deikenin ieriine gre program akn ynlendirir.

6.1 Karlatrma Operatrleri ve Mantksal Operatrler


Tablo 6.1'de listelenen Karlatrma Operatrleri, saysal deerleri veya karakterleri mukayese etmek iin kullanlr.

Tablo 6.1: Karlatrma Operatrleri

Operatr
> < == >= <= !=

Aklama byktr kktr eittir byk-eittir kk-eittir eit deil

rnek
x > y x < y x == y x >= y x <= y x != y

Anlam x, y den byk m? x, y den kk m? x, y ye eit mi? x, y den byk yada eit mi? x, y den kk yada eit mi? x, y den farkl m?

Birden ok karlatrma ilemi, Tablo 6.2'deki Mantksal Operatrler'le birletirilebilir. Tablo 6.2: Mantksal Operatrler
Operatr
&& ||

Aklama mantksal VE mantksal VEYA

rnek
x>2 && x<y x>2 || x<y

Anlam x, 2 den byk VE y den kk m? x, 2 den byk VEYA y den kk m?

C dilinde, bir mantksal ilemin sonucu tamsay 0 (sfr) veya baka bir deer olur. 0 olumsuz 0'dan farkl deerler olumlu olarak yorumlanr. Buna gre, aadaki program parasnn
... int x = 1, y = 2, s, u, z; s = 2 > 1; u = x > 3; z = x <= y && y >0; printf("%d\t%d\t%d", s, u, z); ...

kts:
1 0 1

eklinde olur. Bunun nedeni:


2 her zaman 1 den byk olduu iin s deikenine 1, x = 1 < 3 olduu iin x deikenine 0, z = x <= y && y >0; eitliin satarafnn sonucu olumlu olduu iin z deikenine 1 atanr.

6.2 if, if-else Yaps


Bu deyimler, koullu ilem yapan deyimlerdir. if ve else tek bir karlatrma deyimi olup else kullanm istee baldr. Eer bu koul olumlu ise if den sonraki blm yrtlr ve else den sonraki blm atlanr. Koul olumsuz ise if den sonraki kme atlanr ve eer varsa, else den sonraki kmedeki ilemler gerekletirilir.

if

deyiminin yapnn genel biimi yledir:


if(koul)

{ ... deyimler; (kme) ... }

deyimi kullanlrken kmenin balangc ve bitiini gsteren, kme parantezleri kullanlmasnda kullancya bir esneklik sunulmutur. Eer if deyiminden sonra icra edilecek deyimler tek satrdan oluuyorsa, bu iaretlerin kullanlmas zorunlu deildir. Yani, if deyimden sonra { ve } iaretleri kullanlmamsa, bu deyimi takip eden sadece ilk satr ileme konur. Bu durum, else if, else deyimlerinde ve daha sonra ilenecek for ve while gibi dng deyimlerinde de geerlidir.
if

Buna gre aadaki kullanm


if(x == y){ puts("x ve y esit"); }

ile
if(x == y) puts("x ve y esit");

edeerdir.
if

deyiminin else ile birlikte kullanm u ekildedir:


if(koul){ ... deyimler; (kme1) ... } else{ ... deyimler; (kme2) ... }

Bu yapnn kullanlmasna dair bir rnek Program 6.1'de gsterilmitir. Program, klavyeden girilen bir tamsaynn ift olup olmadn snar. Bilindii gibi, ift saylar, 2 ile kalansz blnebilen saylardr.

Program 6.1: if-else deyiminin kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 06prg01.c Klavyeden girilen bir saynn ift olup olmadn snar. */ #include <stdio.h> int main() { int sayi; printf("Bir sayi girin: "); scanf("%d",&sayi); if (sayi % 2 == 0) printf("sayi cifttir.\n"); else printf("sayi tektir.\n"); return 0; }

IKTI
Bir sayi girin: 3 sayi tektir.

Mantksal Operatrler kullanarak birden ok karlatrma birletirilebilir. Buna iyi bir rnek Program 6.2'de gsterilmitir. Program, bir yln artk yl olup olmadn snar. Bir yl iinde, ubat ay 29 gn olursa o yl artk yl olarak adlandrlr. Artk yl peryodik olarak 4 ylda bir gelir. 1800 artk yl deildir. Genel sorgulama syle olmaldr: Eer bir yl

4 ile tam blnyorsa VE 100'e tam blnmyorsa VEYA 400 'e tam blnryorsa

o yl artk yldr. Program 6.2: if-else deyiminin kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: #include <stdio.h> void main() { int yil; printf("Bir yil girin: "); scanf("%d",&yil); if( yil % 4 == 0 && yil % 100 != 0 || yil % 400 == 0 ) printf("%d artik yil\n",yil); else printf("%d artik yil degil\n",yil); }

IKTI
Bir yil girin: 1996 1996 artik yil

Eer program iinde kullanlacak koullarn says ikiden ok ise aadaki yap kullanlr:
if(koul_1) { ... deyimler; (kme_1) ... } else if(koul_2) { ... deyimler; (kme_2) ... } . . . else if(koul_n-1) { ... deyimler; (kme_n-1) ... } else { ... deyimler; (kme_n) ... }

Program 6.3, ax2 + bx + c = 0 formundaki ikinci dereceden bir polinomun kklerini hesaplamaktadr. Programda delta deerinin sfrdan kk olmas durumda kklerin karmak sayya dneceide gz nne alnmtr. Bu program if, else if ve else yaps gstermek iin klasik bir rnektir.

Program 6.3: if, else if, else yaps


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: /* ax*x + bx + c = 0 denkleminin (karmak sayl kkler dahil) zm */ #include <stdio.h> #include <math.h> int main() { float a, b, c, delta, x1, x2, x, kok_delta; printf("a, b, c degerlerini girin:\n"); scanf("%f %f %f",&a,&b,&c); delta = b*b - 4.0*a*c; if( delta > 0.0 ){ x1 = ( -b + sqrt(delta) )/( 2.0*a ); x2 = ( -b - sqrt(delta) )/( 2.0*a ); printf("\nReel kokler:"); printf("\nx1 = %f",x1); printf("\nx2 = %f",x2); } else if( delta < 0.0 ){ kok_delta = ( sqrt(-delta) ) / (2.0*a); x = -0.5*b/a; printf("\nKarmasik kokler:"); printf("\nx1 = %f + (%f)i", x, kok_delta); printf("\nx2 = %f - (%f)i", x, kok_delta); } else{ x = -0.5*b/a; printf("\nKokler eit:"); printf("\nx1 = x2 = %f",x); } return 0; }

IKTI
a, b, c degerlerini girin: 2 4 -8 Reel kokler: x1 = 1.236068 x2 = -3.236068

IKTI
a, b, c degerlerini girin: 1 1 1 Karmasik kokler: x1 = -0.500000 + (0.866025)i x2 = -0.500000 - (0.866025)i

6.3 switch - case Yaps


Bu deyim bir deikenin ieriine bakarak, programn akn bir ok seenekten birine ynlendirir. case (durum) deyiminden sonra deikenin durumu belirlenir ve takip eden gelen satrlar (deyimler) ileme konur. Btn durumlarn aksi sz konu olduunda gerekletirilmesi istenen deyimler default deyiminden sonraki ksmda bildirilir. Genel yazm biimi:
switch(deiken) { case sabit1: ... deyimler; ... case sabit2: ... deyimler; ... . . . case sabitn: ... deyimler; ... default: ... hata deyimleri veya varsaylan deyimler; ... }

Program Program 6.4'te switch deyiminin basit bir kullanm gsterilmitir. Program 6.4: switch-case yapsnn kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: /* 06prg04.c: switch - case yapsnn kullanm */ #include <stdio.h> int main(void) { char kr; printf("Lutfen bir karakter girin\n"); kr = getchar(); /* tek bir karakterin okunmas */ switch (kr) { case 'a': printf("a harfine bastiniz\n"); case 'b': printf("b harfine bastiniz\n"); default: printf("a veya b ye basmadiniz\n"); } return 0; }

IKTI
Lutfen bir karakter girin a a harfine bastiniz b harfine bastiniz a veya b ye basmadiniz

IKTI
Lutfen bir karakter girin b b harfine bastiniz a veya b ye basmadiniz

IKTI

Lutfen bir karakter girin k a veya b ye basmadiniz

IKTI
Ltfen bir karakter girin c a veya b ye basmadiniz

Programda, klavyeden okunan tek bir karakter deikenin ieriine baklp uygun dallanmalar yaptrlmtr. 11. satrda deiken getchar() fonksiyonu ile okutulmutur. Eer 'a' veya 'b'karakterlerinden biri girilirse, ekrana bu harflerin girildiine dair mesaj yazlacak, aksi takdirde bu karakterin dnda bir karakterin giri olarak kullanld gsteren bir mesaj yazlacaktr. rnein 'c'karakteri klavyeden girilmi ise a veya b ye basmadiniz gibi. Fakat 'a' karakterleri girildiinde ekrana her durumda yazdrlmaktadr. Bunun sebebi, case 'a': durumunda srasyla 16, 18 ve 20. satrlarn ileme konmasdr. Bunu engellemek iin 16. satrdan sonra programn baka bir yere ynlendirilmesi gerekir. Bu ynlendirme break deyimi ile yaplr. Derleyici bu deyim ile karlatnda, bulunduu yapnn iinden koulsuz olarak ayrlr ve takip eden ileme balar. Program 6.4'te case 'a': durumu iin 16, 18 ve 20. satrlar da ileme konumutu. Eer klavyeden 'a' karakterini girip ekrana sadece a harfine bastiniz iletisi yazdrlmak isteniyorsa, 20. satra break deyimi ilave edilmelidir. break deyiminin kullanm Program 6.5'te gsterilmitir.

Program 6.5: switch-case yaps ve break kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: /* 06prg05.c: switch - case yaps ve break kullanm */ #include <stdio.h> int main(void) { char kr; printf("Lutfen bir karakter girin\n"); kr = getchar(); /* tek bir karakterin okunmas */ switch (kr) { case 'a': printf("a harfine bastiniz\n"); break; case 'b': printf("b harfine bastiniz\n"); break; default: printf("a veya b ye basmadiniz\n"); break; } return 0; }

IKTI
Lutfen bir karakter girin a a harfine bastiniz

IKTI
Lutfen bir karakter girin k a veya b ye basmadiniz

Program 6.6 switch-case yapsn farkl bir kullanm ile ilgili bir rnektir. Programda, nce iki say isteniyor ardndan yaplan seimle bu saylarn toplam, fark, arpm veya oran ekrana yazdrlyor.

Program 6.6: switch-case yaps ve break kullanm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: /* 06prg06.c: switch-case yaps */ #include <stdio.h> #include <stdlib.h> int main(void) { int secim; float x,y, sonuc; printf("Iki sayi girin: "); scanf("%f %f",&x,&y); puts("*** puts("[1] puts("[2] puts("[3] puts("[4] Menu ***"); Toplama"); Cikarma"); Carpma"); Bolme");

printf("Seciminiz: "); scanf("%d",&secim); switch( secim ) { case 1: sonuc = x + y; printf("Toplam = %f\n",sonuc); break; case 2: sonuc = x-y; printf("Fark = %f\n",sonuc); break; case 3: sonuc = x * y; printf("Carpim = %f\n",sonuc); break; case 4: sonuc = x/y; printf("Oran = %f\n",sonuc); break; default: puts("Yanlis secim !\a"); } return 0; }

IKTI
Iki sayi girin: 3 8 *** Menu *** [1] Toplama [2] Cikarma [3] Carpma [4] Bolme Seciminiz: 1 Toplam = 11.000000

IKTI
Iki sayi girin: 3 8 *** Menu *** [1] Toplama [2] Cikarma [3] Carpma [4] Bolme Seciminiz: 7 Yanlis secim !

yaps if-else yapsnn bir alternatifidir. Yani, Program 6.6'daki switchcase ksm, if-else yaps ile de aadaki gibi yazlabilirdi. nceleyiniz.
switch-case switch( secim ) { case 1: sonuc = x + y; printf("Toplam = if(secim == 1){ sonuc = x + y; printf("Toplam =

%f\n",sonuc); } %f\n",sonuc); else if(secim == 2){ break; sonuc = x-y; case 2: printf("Fark = %f\n",sonuc); sonuc = x-y; } printf("Fark = %f\n",sonuc); else if(secim == 3 ){ break; sonuc = x * y; case 3: printf("Carpim = sonuc = x * y; %f\n",sonuc); printf("Carpim = } %f\n",sonuc); else if(secim == 4){ break; sonuc = x/y; case 4: printf("Oran = %f\n",sonuc); sonuc = x/y; } printf("Oran = %f\n",sonuc); else{ break; puts("Yanlis secim !\a"); default: } puts("Yanlis secim !\a"); }

6.4 ? Karlatrma Operatr


Bu operatr, if-else karlatrma deyiminin yapt ii snrl olarak yapan bir operatrdr. Genel yazm biimi:
(koul) ? deyim1 : deyim2;

lk nce koul snanr. Eer koul olumluysa deyim1 aksi takdirde deyim2 deerlendirilir. deyim1 ve deyim2 de atama ilemi yaplamaz. Ancak koul deyiminde atama ilemi yaplabilir. deyim1 vedeyim2 yerine fonksiyon da kullanlabilir. Aada bu deyimin kullanmna ait rnekler verilmitir.
x = ( a > b ) ? a : b;

Yukardaki ifadede koul a'nn b'den byk olmasdr. Eer olumluysa x adl deikene a, deilse b deeri atanr. Bu ekilde kullanm if-else yaps ile kurulmak istenirse:

if( a > b ) else

x = a; x = b;

eklinde olacaktr. Program 6.7 ? karlatrma operatrnn basit bir kullanmn gstermektedir. Program 6.7: ? ve if kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 06prg07.c: ? ve if-else yapsnn kullanm */ #include <stdio.h> int main(void) { float x, y, z; printf("x : "); scanf("%f",&x); printf("y : "); scanf("%f",&y); if(y) */ z = ( y > x ) ? x/y : x*y; /* y>x ise z = x/y, deilse z = x*y */ else z = 0.0; printf("z = %f\n",z); return 0; } /* y, 0'dan farkl m?

IKTI
x : 3 y : 5 z = 0.600000

IKTI
x : 11 y : 0 z = 0.000000

12. satrdaki if deyimindeki koul biraz farkldr. Genel olarak koul bu ekilde bildirilirse, koulun 0 dan farkl olup olmad snanr. Yani:
if(y)

ile
if( y != 0 )

ayn anlamdadr. Bu kullanm ok yagndr. Eer y, 0 dan farkl ise koul olumlu olarak deerlendirilecektir. 13. satrda ? ile bir snama yaplmaktadr. Eer y, x den byk ise z deikenine x/y, aksi takdirde x*ydeeri atanmaktadr. Eer y = 0 ise z deikenine 0 deeri atanmaktadr.

Ders 7: Dngler
Giri
Dng (loop) deyimleri, bir kmenin belli bir koul altnda tekrar edilmesi iin kullanlr. C programlama dilinde, while, do...while ve for olmak zere tip dng deyimi vardr. Dier programlama dillerinde olduu gibi, bu deyimlerle istenildii kadar i-ie dng yaps kullanlabilir.

7.1 while Dngs


Tekrarlama deyimidir. Bir kme ya da deyim while kullanlarak bir ok kez yinelenebilir. Yinelenmesi iin koul snamas dngye girilmeden yaplr. Koul olumlu olduu srece evrim yinelenir. Bu deyimin kullanm Program 7.1 de gsterilmitir. Genel yazm biimi:
while(koul) { ... dngdeki deyimler; [kme] ... }

Program 7.1: while dngs


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: /* 07prg01.c: while dngs */ #include <stdio.h> main() { int x=0; while(x <= 10) printf("%d\n",x++); return 0; }

IKTI
0 1 2 3 4 5 6 7 8 9 10

Program 7.1, 0-10 arasndaki saylar ekrana yazdrmaktr. 9. satrdaki while deyiminden sonra { iareti kullanlmamtr. Bu durumda, sadece takip eden satr (10. satr) dngnn iine dahil edilir.

7.2 do ... while Dngs


Bu deyimin while deyiminden fark, koulun dng sonunda snanmasdr. Yani koul snanmadan dngye girilir ve dng kmesi en az bir kez yrtlr. Koul olumsuz ise dngden sonraki satra geilir. Bu deyimin kullanm Program 7.2 de gsterilmitir. Genel yazm biimi:
do{ ... dngdeki deyimler; ... }while(koul);

Program 7.2: do-while dngs


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 07prg02.c: do-while yaps */ #include <stdio.h> main() { int sayi; do { printf("Bir sayi girin : "); scanf("%d",&sayi); printf("iki kati : %d\n",2*sayi); }while( sayi>0 ); /* koul */

puts("Dng sona erdi."); return 0; }

IKTI
Bir sayi girin : 1 iki kati : 2 Bir sayi girin : 3 iki kati : 6 Bir sayi girin : 4 iki kati : 8 Bir sayi girin : -3 iki kati : -6 Cevrim sona erdi.

15. satrdaki koul olumlu olduu srece (sayi>0 olduu srece), klavyeden yeni bir deer 12. satrda okunur. Aksi takdirde (sayi<=0 ise) evrimin sona erdiine dair mesajla program sonlanr.

7.3 for Dngs


Bu deyim, dier dng deyimleri gibi bir kmeyi bir ok kez tekrarlamak iin kullanlr. Koul snamas while da olduu gibi dngye girmeden yaplr. Bu dng deyimin iinde dierlerinden farkl olarak balang deeri ve dng sayacna sahip olmasdr. Bu deyimin kullanm Program 7.3 de gsterilmitir Genel yazm biimi:
for( balang ; koul ; artm ) { ... dngdeki deyimler; ... }

Program 7.3: for dngs


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* 07prg03.c: for dngs ile faktoriyel hesab. */ #include <stdio.h> int main() { long i, n, faktor; printf("Faktoriyeli hesaplanacak sayi girin : "); scanf("%ld",&n); faktor=1; for(i=1; i<=n; i++){ faktor *= i; }

/* n! = 1 x 2 x 3 x ... x n */

printf("%ld! = %ld\n", n, faktor); return 0; }

IKTI
Faktoriyeli hesaplanacak sayi girin : 4 4! = 24

IKTI
Faktoriyeli hesaplanacak sayi girin : 15 15! = 2004310016

Program da faktoriyel hesab 16. satrda gerekletirilmitir. Faktriyel, bilindii gibi n! = 1x2x3x ... xn tanmlanr. Gerekte 15! = 1307674368000 olmasna ramen, program 15! = 2004310016 olarak hesaplamtr. Sizce bunun sebebi nedir?

Program 7.3'de dngye girilmeden, faktor


faktor = 1; for(i=1; i<=n; i++) faktor *= i;

= 1

atmas yaplmtr.

Bu dng ncesi ilk deer atamas, dngnn balang ksmnda u ekilde de yaplabilir:
for(faktor=1, i=1; i<=n; i++) faktor *= i;

fonksiyonu ile desimal (taban-10) saylarlarn nasl yazdrlaca bundan nceki ksmlarda gsterilmiti. Program 7.4'te 0-15 aras desimal saylarn Oktal (taban-8) ve Heksadesimal (taban16) karlklar ile printf kullanlarak yazdrlmas gsterilmitir.
printf

Program 7.4: Say sistemi


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: /* 07prg04.c: Say sistemi %d : desimal 10 tabanndaki %o : oktal 8 tabanndaki %x : hexadesimal 16 tabanndaki %X : hexadesimal 16 tabanndaki #include <stdio.h> int main() { int i; for (i=0; i<16; i++) printf("%2d %2o %x return 0; } %X\n", i,i,i,i); say say say (kk harf) say (byk harf) */

IKTI
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 A B C D E F

7.4 ie Gemi Dngler


Bir program iinde birbiri iine gemi birden ok dng de kullanlabilir. Bu durumda (btn programlama dillerinde olduu gibi) nce iteki dng, daha sonra dtaki dng icra edilir. basamakl, basamaklarnn kpleri toplam kendisine eit olan tam saylara Armstrong say denir. rnein: 371 bir Armstrong saydr nk 3^3 + 7^3 + 1^3 = 371. Program 7.5'de i ie gemi for dngs ile btn Armstrong saylar bulup ekrana yazar. nceleyiniz. Program 7.5: i-ie for dngleri
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: /* 07prg05.c: basamakl, basamaklarnn kpleri toplam kendisine eit olan tam saylara Armstrong say denir. rnein: 371 = 3^3 + 7^3 + 1^3. Bu program -ie gemi 3 dng ile btn Aramstrong saylar bulur. */ #include <stdio.h> int main() { int a,b,c, kup, sayi, k=1; for(a=1; a<=9; a++) for(b=0; b<=9; b++) for(c=0; c<=9; c++) { sayi = 100*a + 10*b + c; basamakl) */ kup = a*a*a + b*b*b + c*c*c; a^3+b^3+c^3 */ } return 0; }

/* sayi = abc ( /* kup =

if( sayi==kup ) printf("%d. %d\n",k++,sayi);

IKTI
1. 2. 3. 4. 153 370 371 407

7.5 Sonsuz Dng


Bir dng ilemini sonsuz kere tekrarlarsa bu dng sonzuz dng olarak adlandrlr. Byle bir dng iin, koul ok nemlidir. rnein while dngs iin:
... while(1) { printf("Sonsuz dng iindeyim...\n"); } ...

yada
... while(7>3) { printf("Sonsuz dng iindeyim...\n"); } ...

Her iki durumda da evrimler, sonsuz dng durumundadr. nk while(1) ve while(7>3) ifadelerdeki koullar daima olumludur. Bu durumda evrim sonsuz dngye girer. dngsnde, balang, koul ve artm parametrelerinden herhangi birini kullanmak istee baldr. Her hangi biri verilmediinde dngnn nasl davranaca iyi yorumlanmaldr. rnein fordngsnn hibir parametresi verilmezse, dng sonsuz evrime girer. Yani:
for for(;;) printf("Sonsuz dng iindeyim...\n");

gibi.

7.6 break Deyimi


Bir C programnda, bir ilem gerekletirilirken, ilemin sona erdirilmesi bu deyim ile yaplr. rnein, dng deyimleri iindekiler yrtlrken, evrimin, kouldan bamsz kesin olarak sonlanmas gerektiinde bu deyim kullanlr. Mesela:
... do{ scanf("%d",&x); if(x==0) break; printf("%f",1.0/x); }while(1); ...

Yukardaki program parasnda, do ... while dngsndeki koul daima olumludur. Bu durumda dng sonsuzdur. Fakat dng iinde if deyimindeki koul gerekleirse, dng kouluna baklmakszn terkedilir. Bu ilemi salayan break deyimidir.

Program 7.6 klavyeden girilen say pozitif olduu srece saynn faktoriyelini hesaplar. Say negatif olduunda dng break ile sonlandrlr. Inceleyiniz. Program 7.6: break deyiminin kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: /* 07prg06.c: n>=0 olduu srece n! deerini hesaplar */ #include <stdio.h> int main() { long int i,n,faktor; while(1) /* sonsuz dng */ { printf("Faktoriyeli hesaplanacak sayi girin : "); scanf("%ld",&n); if(n<0) break; /* dngy sonlandr */ for(faktor=1, i=1; i<=n; i++) faktor *= i; printf("%ld! = %ld\n",n,faktor); } return 0; }

IKTI
Faktoriyeli 2! = 2 Faktoriyeli 3! = 6 Faktoriyeli 5! = 120 Faktoriyeli 9! = 362880 Faktoriyeli 0! = 1 Faktoriyeli hesaplanacak sayi girin : 2 hesaplanacak sayi girin : 3 hesaplanacak sayi girin : 5 hesaplanacak sayi girin : 9 hesaplanacak sayi girin : 0 hesaplanacak sayi girin : -4

7.7 continue Deyimi


Bir dng ierisinde continue deyimi ile karlalrsa, ondan sonra gelen deyimler atlanr ve dng bir sonraki evrime girer. rnein:
... for(x=-50;i<=50;x++) { if(x<0) continue; /* x<0 ise alttaki satr atla */ printf("%d\t%f",x,sqrt(x)); } ...

Program parasnn kts:


0 1 2 3 . . . 50 0.000000 1.000000 1.414213 1.732050 . . . 7.071067

Program 7.7, x, y'den farkl olmak zere |x|+|y|<=3 eitsizliini salayan tamsay iftlerini bulup ekrana yazar. Bu eitsizlii salayan toplam 22 ift vardr. Programda, her bir ift parantez iinde yazdrlmtr. nceleyiniz. Program 7.7: continue deyiminin kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* x, y'den farkl olmak zere |x|+|y|<=3 eitsizliini salayan tamsay iftlerini ekrana yazar */ #include <stdio.h> int main() { int x,y,k=1; for (x=-3;x<=3;x++) for (y=-3;y<=3;y++) { /* x=y ise yeni evrime gir, alt satrlar atla */ if(x==y) continue; if( abs(x)+abs(y)<=3 ) printf("%2d. (%2d,%2d)\n",k++,x,y); } return 0; }

IKTI
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. (-3, 0) (-2,-1) (-2, 0) (-2, 1) (-1,-2) (-1, 0) (-1, 1) (-1, 2) ( 0,-3) ( 0,-2) ( 0,-1) ( 0, 1) ( 0, 2) ( 0, 3) ( 1,-2) ( 1,-1) ( 1, 0) ( 1, 2) ( 2,-1) ( 2, 0) ( 2, 1) ( 3, 0)

Ders 8: Fonksiyonlar I (Alt Programlar)


Giri
C Programlama Dili fonksiyon olarak adlandrlan alt programlarn birletirilmesi kavramna dayanr. Bir C program bir yada daha ok fonksiyonun bir araya gelmesi ile oluur. Bu zellik btn Yapsal Diller'in (C, Fortran, Pascal, ...) temelini oluturur. Yapsal Diller'e hakim olmak iin fonksiyon oluturmay ve kullanmay iyi renmek gerekir. Bu blmde, C Programlama Dili'ndeki fonksiyon kavram, sonraki blmde esnek argmanl fonksiyonlar ve main() fonksiyonu irdelenecektir.

8.1 Fonksiyon Kavram


Fonksiyon, belirli sayda verileri kullanarak bunlar ileyen ve bir sonu reten komut grubudur. Her fonksiyonun bir ad ve fonksiyona gelen deerleri gsteren argumanlar (bamsz deikenleri) vardr. Genel olarak bir fonksiyon ekil 8.1'deki gibi bir kutu ile temsil edilir:

ekil 8.1:Bir fonksiyonun kutu gsterimi Fonksiyonlarn girdilerine parametreler yada argumanlar denir. Bir fonksiyon bu parametreleri alp bir ileme tabi tutar ve bir deer hesaplar. Bu deer, kt veya geri dn deeri (return value) olarak adlandrlr. Unutmayn ki, bir fonksiyonun ka girii olursa olsun sadece bir k vardr. C Programlama Dili, kullancsna bu trden fonksiyon yazmasna izin verir. C dilinde hazrlanan bir fonksiyonun genel yaps yledir:
FonksiyonTipi FonksiyonAd(argman listesi) argumanlarn tip bildirimleri { Yerel deikenlerin bildirimi ... fonksiyon iindeki deyimler veya dier fonksiyonlar ... return geri dn deeri; }

rnein iki saynn toplamnn hesaplayacak bir fonksiyon yle tanmlanabilir:


/* klasik biim */ int topla(x,y) int x,y { int sonuc; sonuc = x + y; return sonuc; }

veya
/* modern biim */ int topla(int x,int y) { int sonuc; sonuc = x + y; return sonuc; }

veya
/* modern biim */ int topla(int x,int y) { return (x+y); }

Bu rnekte, fonksiyonun kimlik kart! ve kutu gsterimi yledir:


Fonksiyon tipi: int Fonksiyon ad : topla parametreler : x ve y geri dn deeri: x+y

Her program parasnda da return (geri dn) deyimi kullanlmaktadr. Bu deyim C programlama dilinin anahtar szcklerinden biridir ve fonksiyon ierisinde sonucu, kendisini aran yere gndemek iin kullanlr. Yani topla fonksiyonu herhangi bir programn ierisinde kullanldnda, fonksiyonun retecei sonu return deyiminden sonra belirtilen deiken veya ilem olacaktr. rnein fonksiyon:
... int t; ... t = topla(9,6); ...

eklinde kullanlrsa, t deikenine 9+6=15 deeri atanr. topla() fonksiyonunun kullanm Program 8.1'in zerinde aklanmtr.

8.2 Fonksiyon Bildirimi


Bir fonksiyonun bildirimi iki trl yaplr: 1. Ana programdan nce:
2. ... 3. int topla(int x,int y) 4. { 5. ... 6. } 7. ... 8. main() 9. { 10. ... 11. } /* fonksiyon */

12. Ana programdan sonra: Bu durumda fonksiyon rnei (function prototype) ana programdan nce bildirilmelidir.
13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... int topla(int x, int y); ... main() { ... } ... int topla(int x, int y) { ... } /* fonksiyon rnei */

/* fonksiyon */

Bir C program iinde, yazm olduunuz fonksiyonlar genellikle bu iki tipte kullanlr. kinci kullanmda fonksiyon prototipi mutlaka bildirilmelidir. Aksi halde bir hata mesaj ile karlalr. Fonksiyon prototipinde arguman isimlerinin yazlmas zorunlu deildir. Sadece arguman tiplerini belirtmek de yeterlidir. Yukardaki topla fonksiyona ait prototip:
int topla(int x, int y);

ekinde yazlabilei gibi


int topla(int, int);

eklinde de yazlabilir.

Buraya kadar anlatlanlar Program 8.1 zeride zetlenmitir. Program 8.1: topla fonksiyonunun ana programda kullanlmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: /* 08prg01.c: iki sayy toplar ve sonucu ekranda gsterir */ #include <stdio.h> int topla(int, int); int main() { int toplam,a,b; printf("Iki sayi girin : "); scanf("%d %d",&a,&b); /* fonksiyon arlp, a ve b deerleri parametre olarak aktarlyor. topla(a,b) = a + b deeri toplam deikenine atanmas */ toplam = topla(a,b); printf("%d ve %d nin toplami return 0; } /*** fonksiyon tanmlanmas ***/ /* Bu fonksiyon iki tamsayy toplar */ int topla( int x, int y ) { int sonuc; sonuc = x + y; return sonuc; } %d dir.\n", a,b,toplam); /*** fonksiyon prototipi ***/

IKTI
Iki sayi girin : 5 12 5 ve 12 nin toplami 17 dir.

Programda, klavyeden okunan a ve b deikenleri fonksiyonuna parametre olarak aktarlmtr. Bu deikenlerin isimleri ile topla fonksiyonunda kullanlan deikenlerin (x ve y) isimleri ayn olmas zorunlu deildir. Burara a ve b deikenleri srasyla x ve y deikenleri yerine konmutur. 16. satrda toplam adl tamsay deikenine topla fonksiyonunun dn deeri (a + b deeri) atanmtr.

Belki karmak gelmi olabilir. Fakat Program 8.1 daha ksa yle yazlabilirdi: Program 8.1b: topla fonksiyonunun ana programda kullanlmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: /* 08prg01b.c: iki sayy toplar ve sonucu ekranda gsterir */ #include <stdio.h> int topla( int x, int y ){ return (x+y); } int main(void) { int toplam,a,b; printf("Iki sayi girin : "); scanf("%d %d",&a,&b); toplam = topla(a,b); printf("%d ve %d nin toplami return 0; } %d dir.\n", a,b,toplam);

8.3 Geri Dn Deerleri


return

anahtar szcnn iki nemli ilevi vardr:

1. fonksiyonun geri dn deerini oluturur 2. fonksiyonu sonlandrr Bu deyiminden sonra bir deiken, ilem, sabit veya baka bir fonksiyon yazlabilir. rnein:
return (a+b/c); return 10; return topla(a,b)/2.0; /* parantez kullanmak zorunlu deil */ /* deiken kullanmak mecbur deil */ /* nce topla fonksiyonu alr */

Bir fonksiyonda birden ok geri dn deeri kullanlabilir. Fakat, ilk karlalan return deyiminden sonra fonksiyon sonlananr ve arlan yere bu deer gnderilir. rnein aadaki harffonksiyonunda be tane return deyimi kullanlmtr.
char harf(int not) { if( not>=0 && not<50 if( not>=50 && not<70 if( not>=70 && not<80 if( not>=80 && not<90 if( not>=90 }

) ) ) ) )

return return return return return

'F'; 'D'; 'C'; 'B'; 'A';

Bu fonksiyon kendisine parametre olarak gelen 0-100 arasndaki bir notun harf karln gnderir. Aslnda geri gnderilen deer bir tanedir. Eer bu fonksiyon aadaki gibi arlrsa:
char harfim; ... harfim = harf(78); ... harfim

deikenine 'C' deeri (karakteri) atanr.

Program 8.2'de bildirilen artik_yil fonksiyonu, kendisine parametre olarak gelen bir tamsayy yl bilgisi olarak kabul eder. Eer yl artk yl ise 1 aksi halde 0 gnderir. Programda iki tane returndeyimi kullanldna dikkat ediniz. Artk yl tanm Blm 6'da verilmiti. Program 8.2: iki return deyimi kullanan bir fonksiyon
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: /* 08prg02.c: Bir fonksiyonda iki return deyimi */ #include <stdio.h> int artik_yil(int); /* fonksiyon prototipi */ void main() { int yil; printf("Bir yil girin: "); scanf("%d",&yil); if( artik_yil(yil) ) printf("%d artik yil\n",yil); else printf("%d artik yil degil\n",yil); } /* yil artl yl ise 1 aksi halde 0 gnderir */ int artik_yil(int yil) { if( yil % 4 == 0 && yil % 100 != 0 || yil % 400 == 0 ) return 1; else return 0; }

IKTI
Bir yil girin: 1996 1996 artik yil

8.4 void Fonksiyonlar


Bir fonksiyonun her zaman geri dn deerinin olmas gerekmez. Bu durumda return deyimi kullanlmayabilir. Eer bu anahtar kelime yoksa, fonksiyon ana blou bitince kendiliinden sonlanr. Byle fonksiyonlarn tipi void (bo, hkmsz) olarak belirtilmelidir. Bu tip fonksiyonlar baka bir yerde kullanlrken, herhangi bir deikene atanmas sz konusu deildir, nk geri dn deeri yoktur. Ancak, void fonksiyonlara parametre aktarm yapmak mmkndr. Program 8.3'de void fonksiyona rnek olarak bankamatik fonksiyonu ve kullanm gsterilmitir. Bu fonksiyon kendisine parametre olarak gelen YTL cinsinden para miktarn 20, 10 ve 5 YTL'lik birimler halinde hesaplar. Girilen miktar 5 YTL'nin bir kat deilse, ekrana uygun bir mesaj gnderir. bankamatik fonksiyonu bir dizi hesap yapmasna ramen geriye hi bir deer gndermez. Program 8.3: void tipinde bir fonksiyon kullanm
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: #include <stdio.h> void bankamatik(int para) { int a,yirmilik,onluk,beslik; a = para; if(a%5==0) { yirmilik = a/20; a -= yirmilik*20; onluk = a/10; a -= onluk*10; beslik = a/5; a -= beslik*5; printf("\nYirmilik = %d",yirmilik); printf("\nOnluk = %d",onluk); printf("\nBeslik = %d\n",beslik); } else printf("Girilen miktar 5 YTL ve katlari olmali!\a\n"); /* return deyimi yok !*/ } int main() { int miktar; printf("Cekilecek para miktari (YTL) = "); scanf("%d",&miktar); bankamatik(miktar); atanmam ! */ retrun 0; } /* fonksiyon bir deikene

IKTI
Cekilecek para miktari = 135 Yirmilik = 6 Onluk = 1 Beslik = 1

IKTI
Cekilecek para miktari = 456 Girilen miktar 5 YTL ve katlari olmali!

anahtar szc C'ye sonradan dahil edilmitir. Standart C'de (ANSI C) bu deyimin kullanlmas zorunlu deildir. Ancak bu deyim okunabilirlii arttrmaktadr. rnein:
void void bankamatik(int para) { ... } bankamatik(int para) { ... }

eklindeki kullanmlar geerli ve ayn anlamdadr. Baka bir void fonksiyon rnei Program 8.4'de verilmitir. Programdaki kutu_ciz fonksiyonu, iki for dngs kullanarak 'X' karakterlerinden oluan basit bir kutu izimi yapar. Programda de sadece 18. satr defalarca ileme konur. Program altrldnda 8*35=280 adet 'X' karakteri ekrana bastrlr. nceleyiniz. Program 8.4: basit kutu izen fonksiyon
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: /* 08prg04.c: Basit bir kutu izen fonksiyon */ #include <stdio.h> void kutu_ciz( int satir, int sutun ) { int sut; for ( ; satir > 0; satir--) { for (sut = sutun; sut > 0; sut--) printf("X"); printf("\n"); } } int main(){ kutu_ciz(8,35); return 0; }

IKTI
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

8.5 Fonksiyon Parametreleri


Fonksiyon parametreleri (argmanlar) klasik ve modern olmak zere iki trl tanmanabilir. rnein aadaki fonksiyon kendisine parametre olarak gelen tamsaynn faktoriyelini gnderir. Bu fonksiyonun parametresi (n):
int faktoriyel(n) int n { int i=1, f=1; /* kalsik biim */

while(i<=n) f *= i++; return f; }

eklinde yada:
int faktoriyel(int n) { int i=1, f=1; while(i<=n) f *= i++; return f; } /* modern biim */

eklinde yazlabilir. Bir fonksiyona parametre aktarm yaplmas zorunlu deildir. Parametresiz bir fonksiyon da tanmlamak mmkndr. Bu durumda argmanlar ksm ya bo braklr yada bu ksma void yazlr. rnein standard C'de stdlib.h ktphanesinde tanml rand fonksiyonu yle tanmlanmtr:
int rand(void);

Son olarak, ne parametresi ne de geri dn deerine olan bir fonksiyon yle tanmlanabilir:
void mesaj_yaz() { printf("Hata olustu !..\n"); }

yada
void mesaj_yaz(void) { printf("Hata olustu !..\n"); }

8.6 Yapsal Programlama


Program iinde birden ok fonksiyon tanmlayp kullanmak mmkndr. Yani C Programlama Dili fonksiyonlarn inas dayal bir dildir. Bu zelliklik btn Yapsal Programlama Dilleri'nin (Structred Programming) temelini oluturur. Birden ok fonksiyonun main tarafndan nasl arldn temsil eden blok diyagram ekil 8.2'de gsterilmitir.

ekil 8.2: Ana programdan alt programlarn (fonksiyonlarn) arlmas. Fonksiyonu armak iin, fonksiyonun adn yazmak yeterlidir. Fonksiyonlarn sadece ana program tarafndan arlmas zorunlu deildir. Bir fonksiyon baka bir fonksiyon tarafndan da arlabilir. Bu tr kullanma dair bir rnek Program 8.5'de verilmitir.yilin_gunu fonksiyonu, verilen bir tarihin yln kanc gn olduunu hesaplar ve arld yere gnderir. nceleyiniz.

Program 8.5: bir fonksiyonun baka bir fonksiyon tarafndan arlmas


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: /* 08prg05.c: Verilen bir tarihin yln kanc gn olduunu hesaplar. */ #include <stdio.h> int yilin_gunu(int, int, int); int artik_yil(int); int main(void) { int gun = 1; int ay = 8; int yil = 2003;

/* tarih: 01 Austos 2003 */

printf("%02d %02d %d yilinin\n",gun,ay,yil ); printf("%d. gunudur\n",yilin_gunu(gun,ay,yil) ); return 0; } /* yil artl yl ise 1 aksi halde 0 gnderir */ int artik_yil(int yil) { if( yil%4==0 && yil%100!=0 || yil%400==0 ) return 1; else return 0; } /* yln kanc gn olduunu hesaplar ve o gn gnderirir */ int yilin_gunu(int gun, int ay, int yil) { int ygun = gun; switch(ay-1) { case 12: ygun case 11: ygun case 10: ygun case 9: ygun case 8: ygun case 7: ygun case 6: ygun case 5: ygun case 4: ygun case 3: ygun case 2: ygun 28+0 */ case 1: ygun } return ygun; }

+= += += += += += += += += += +=

31; 30; 31; 30; 31; 31; 30; 31; 30; 31; 28 + artik_yil(yil);

/* 28+1 veya

+= 31;

IKTI
01 08 2003 yilinin 213. gunudur

8.7 Makro Fonksiyon Tanmlamas


Balk dosyalarnda, bol miktarda makro fonksiyon uygulamalarna rastlanr. Makro tanmlamas #define nilemci komutu kullanlarak yaplr. rnein aadaki makro fonksiyonlar geerlidir.
#define kare(x) (x)*(x) #define delta(a,b,c) ((b)*(b)-4*(a)(c)) #define yaz() puts("Devam etmek iin bir tua basn...")

Bu ekilde tanmlanan fonksiyonlarn kullanm dierleri gibidir. Yalnzca programn banda tanmlanr. Ancak, bu tanmlamalarla fonksiyon bellekte bir yer igal etmez. Basit bir makro fonksiyon uygulamas Program 8.6'da gsterilmitir. buyuk(a,b) makrosu a>b ise a deerini aksi halde b deerini gnderir.

Program 8.6: Makro fonksiyon uygulamas


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: /* 08prg06.c: makro fonksiyon uygulamas */ #include <stdio.h> #define buyuk(a,b) ( (a>b) ? a:b) int main() { int x,y,eb; printf("iki say girin: "); scanf("%d,%d",&x,&y); eb = buyuk(x,y); printf("buyuk olan return 0; } %d\n",eb);

IKTI
iki say girin: 8,6 buyuk olan 8

Ders 9: Fonksiyonlar II (Alt programlar)


Giri
Bu ksmda, esnek argmanl fonksiyonlar, main() fonksiyonu ve komut satrndan main() fonksiyonuna parametre aktarm incelenektir.

9.1 Esnek Argmanl Fonksiyonlar


Aadaki gibi nc dereceden bir polinom dnelim: P(x) = a + bx + cx2 + dx3 burada a, b, c, d katsaylar gerel say sabitleridir. Bu polinomu temsil eden en basit fonksiyon yle tanmlanabilir.
double p(double x, double a, double b, double c, double d) { double p = a + b*x + c*x*x + d*x*x*x; return p; }

Buna gre, x = 1.7 iin, P(x) = 1 - 2x deerini hesaplamak iin bu fonksiyon aadaki gibi arlmaldr:
sonuc = p(1.7, 1.0, -2.0, 0.0, 0.0);

Burada, kullanlmayan katsaylar iin 0.0 deeri mutlaka fonksiyona geirilmelidir. Kullanlmayan argumanlar geirilmeden de fonksiyonu armak mmkndr. C++, Fortran 90 gibi dillerde olduu gibi, C Programlama Dili, kullanclarna argmanlar esnek olarak geirme imkan verir. Bunun anlam, belli kurallar salandnda, p() fonksiyonu aadaki gibi arlabilmesidir:
/* x n sonuc = p(1.7, 2, a b */ 1.0, -2.0);

Esnek argmanlar iin iki temel kural vardr:


Esnek argmanlar kullanm istee baldr. Esnek argmanlar oluturan kme ardk olarak listeye eklenmelidir.

Bu trden argmanlar, aadaki gibi, fonksiyonun parametre listesi ksmnda ... ile belirtilir.
double p(double x, int n, ...) { }

Esnek Argumanl Fonksiyon tanmlamas yapabilmek iin stdarg.h ktphanesinde tane makro fonksiyon tanmlanmtr. Bu fonksiyonlar Tablo 9.1'de listelenmitir. Tablo 9.1: stdarg.h'te tanml tip ve makro fonksiyonlar
Tip / Fonksiyon
va_list va_start(ap, n) va_arg(ap, tip) va_end(ap)

Aklama ardk esnek argmalar iin tip belirleyici


va_list tipinde bildirilmi ap gstericisi iin bellekten n elemanl yer ayrr.

Veri tipi tip ile belirlenmi kme elemanlarna eritirir.


va_list tipinde bildirilmi ap gstericisi iin bellekten blgeyi boaltr.

Bu kurallar nda, p() fonksiyonunun genel kullanm Program 9.1'de gsterilmitir. p(), kendisine parametre olarak gelen x, n ve ai katsaylarna gre P(x,n) = a0 + a1x + a2x2 + ... + anxn polinomu hesaplar. ai (i = 0, 1, 2, ..., n) katsaylar esnek argman olarak bildirilmitir.

Program 9.1: Sonu -1 ile biten kmeyi ekrana yazar


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: #include <stdarg.h> #include <stdio.h> #include <math.h> /* fonksiyon rnei */ double p(double, int, ...); int main(void){ double x = 1.7; printf("x = %lf icin:\n",x); printf("p(x, 1, p(x, 1, printf("p(x, 2, p(x, 2, printf("p(x, 3, p(x, 3, printf("p(x, 4, p(x, 4, printf("p(x, 5, p(x, 5, return 0; } /* Verilen x, n ve ai katsaylar iin, P(x,n) = a0 + a1*x + a2*x^2 + ... + an*x^n polinomu hesaplar. a0, a1, ..., an katsaylar esnek arguman olarak bildirilmitir. */ double p(double x, int n, ...) { double a, t = 0.0; int i; /* arguman gstericisi; ag va_list tipinde */ va_list ag; /* ag iin bellekten n adet hcre ayr */ va_start(ag, n); for(i=0; i<n; i++) { /* herbir arguman srasyla al */ a = va_arg(ag, double); /* polinomun deerini hesapla */ t += a*pow(x,i); } va_end(ag); return t; } 1.0) = %lf\n", 1.0)); 1.0, -2.0) = %lf\n", 1.0, -2.0)); 1.0, -2.0, 0.2) = %lf\n", 1.0, -2.0, 0.2)); 1.0, -2.0, 0.2, 1.1) = %lf\n", 1.0, -2.0, 0.2, 1.1)); 1.0, -2.0, 0.2, 1.1, -0.6) = %lf\n", 1.0, -2.0, 0.2, 1.1, -0.6));

IKTI
x = 1.700000 icin: p(x, 1, 1.0) = 1.000000 p(x, 2, 1.0, -2.0) = -2.400000 p(x, 3, 1.0, -2.0, 0.2) = -1.822000 p(x, 4, 1.0, -2.0, 0.2, 1.1) = 3.582300 p(x, 5, 1.0, -2.0, 0.2, 1.1, -0.6) = -1.428960

Program 9.2'de, argmanlar esnek olarak bildirilmi topla(int tamsaynn saynn toplamn hesaplar. Program 9.2: n tane saynn toplamn hesaplar
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: /* 09prg02.c n tane saynn toplamnn hesaplanmas */ #include <stdarg.h> #include <stdio.h> int topla(int, ...); int main(void) { printf("topla(2, 11,22) 11,22)); printf("topla(3, 11,22,33) 11,22,33)); printf("topla(4, 11,22,33,44) 11,22,33,44)); printf("topla(5, 11,22,33,44,55) 11,22,33,44,55)); printf("topla(6, 11,22,33,44,55,66) 11,22,33,44,66,66)); return 0; }

n, ...)

fonksiyonu, n tane

= %d\n", topla(2, = %d\n", topla(3, = %d\n", topla(4, = %d\n", topla(5, = %d\n", topla(6,

/* Esnek argumanla tanmlanm n tane tamsaynn saynn toplamn gnderir */ int topla(int n, ...) { va_list ap; int i, top = 0; va_start(ap, n); for (i=1; i<=n; i++) top += va_arg(ap, int); va_end(ap); return top; }

IKTI
topla(2, topla(3, topla(3, topla(5, topla(6, 11,22) 11,22,33) 11,22,33,44) 11,22,33,44,55) 11,22,33,44,55,66) = = = = = 33 66 110 165 242

Argman says bilidirilmeden de bir kme zerinde ilem yaplabilir. Ancak bu durumda kmenin boyutu baka bir yntemle hesaplanmaldr. Program 9.3'de, argmanlar esnek olarak bildirilmiargyaz(int arg, ...) fonksiyonu, son eleman -1 olan bir kmenin elemanlarn ekrana yazar. Kmenin sonu (yani boyutu) -1 ile belirlenmi olur. Program 9.3: Sonu -1 ile biten kmeyi ekrana yazar
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: /* 09prg03.c: Esnek argumanlarn yazdrlmas #include <stdio.h> #include <stdarg.h> /* herbiri int tipinde ve sonu -1 ile biten kmeyi ekrana yazar */ void argyaz(int arg, ...) { va_list ap; int i; va_start(ap, arg); for (i = arg; i != -1; i = va_arg(ap, int)) printf("%d ", i); va_end(ap); putchar('\n'); } int main(void) { argyaz(5, 2, 14, 84, 97, 15, 24, 48, -1); argyaz(84, 51, -1); argyaz(-1); argyaz(1, -1); return 0; } */

IKTI
5 2 14 84 97 15 24 48 84 51 1

9.2 main Fonksiyonu


Ana program anlamna gelen main de bir fonksiyondur. C programlarnn balangc ve sonu bu fonksiyonla belirlenir. Buna gre, bir C (veya C++) program sadece bir tane main ierebilir. fonksiyonu da geri dn deeri kullanabilir. main fonksiyonunun geri dn deerinin grevi, programn almas bittikten sonra sonucu iletim sistemine gndermektir. Program iinde returndeyimi ile iletilen deer 0 olduunda, bu iletim sistemi tarafndan "program baarl olarak sonland" olarak deerlendir. Baka bir deyile,
main return 0;

program, kullancnn talebi dorultusunda (olumlu anlamda) "yapmas gereken ii yapt" mesajn iletim sistemine bildirilir. 0'dan farkl herhangi bir deer ise programn sorunlu sonland anlamna gelecektir. Bu yzden btn C programlarmzn sonuna return 0; ilave ediyoruz. Baz programclar main fonksiyonunun bana ey yazmaz.
main() { ... return 0; }

Bu durumda geri dn deeri tamsay (int) kabul edilir. Bu ekilde kullanmda, yeni tip derleyiciler uyar (warning) mesaj verebilirler. Bu yzden, aadaki kullanm tavsiye ediyoruz.
int main() { ... return 0; }

Eer ana programdan bir deer dndrlmeyecekse, main fonksiyonunun nne aadaki gibi void deyimi eklelenmelidir. Ancak bu baz derleyiciler tarafndan hata olarak yorumlanr. Bu nedenle, aadaki kullanmlar pek tavsiye edilmez.
void main() { ... }

yada
void main(void) { ... }

9.3 main() Fonksiyonuna Parametre Aktarm


NOT Bu ve sonraki ksmda (9.3) anlatlanlar Blm 10, 11 ve 16 okunduktan sonra daha iyi anlalacaktr. Ancak, konu akn bozmamak iin, bu konunun buraya konmas uygun bulunmutur.

Ana programa parametre aktarm, derlenmi (altrlabilir) bir program komut satrndan (iletim sistemi ortamndan) altrlaca zaman yaplr. Parametre aktarm, programn ad yazlp bir boluk brakldktan hemen sonra yaplr. Parametreler, komut satrndan saysal olarak girilse bile program iinde karakter topluluu (string) olarak gelir. Bu durumda, bu ifadeleri saysal deerlere eviren (atoi(), atol(), atof() gibi) fonksiyonlar kullanlr[1]. Genel kullanm biimi:
... int main(arguman_says, arguman_vektr) int arguman_says; char *arguman_vektr[]; { . . . if(arguman_says < ...){ printf("Eksik parametre !\n"); exit(1); } if(arguman_says > ...){ printf("Cok fazla parametre !\n"); exit(1); } . ... arguman_vektr[0] ... /* 1. eleman program ad */ ... arguman_vektr[1] ... /* 2. eleman 1. parametre */ ... arguman_vektr[2] ... /* 3. eleman 2. parametre */ . }

Program 9.1, komut satrndan girilen iki saynn toplamn hesaplar.

Program 9.1: Komut satrndan girilen iki saynn toplamn hesaplar


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: /* topla.c Komut satrndan girilen iki saynn toplamn hesaplar. Kullanm: topla say1 say2 */ #include <stdio.h> #include <stdlib.h> int main(int argsay, char *argvek[]){ int toplam; if(argsay < 3){ printf("Eksik parametre !\n"); exit(1); } if(argsay > 3){ printf("Cok fazla parametre !\n"); exit(1); } toplam = atoi(argvek[1]) + atoi(argvek[2]); printf("Toplamlari %d\n",toplam); return 0; }

Program 9.1, topla.c derlendikten sonra retilen Windows ortamnda retilen topla.exe ve Linux ortamnda retilen topla dosyasnn altrlmas yledir:

Turbo C 2.0 Derlecisi kullanlarak (topla.c program C:\TC adl dizinin altna kaydedildii varsaylmtr)

Dev-C++ Derlecisi kullanlarak (topla.c program C:\Users\bingul\Desktop adl dizinin altna kaydedildii varsaylmtr)

Linux gcc derleyicisi kullanlarak (topla.c program /home/bingul/ adl dizinin altna kaydedildii varsaylmtr)

Komut satrnda yazlan dosya ad dahil toplam parametre says 3 tr. Bunlar:
topla | V argvek[0] 4 | V argvek[1] 9 | V argvek[2]

eklindedir.

Program 9.1, komut satrndan girilen iki saynn toplamn hesaplar. Bu programn daha gelimi hali Program 9.2'de verilmitir. Program 9.2 altrldnda, komut satrndan girilen iki say ve bir operatr bekler. Girilen operatre gre be aritmetik ilemden birinini yapp sonucu ekranda gsterir. nceleyiniz. Program 9.2: Komut satrndan girilen iki say ve bir operatr bilgisine gre 5 ilemden birini hesaplar
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: /* hesap.c: Komut satrndan girilen iki say zerinde 5 ilem yapar. Kullanm: hesap <sayi1> <operator> <sayi2> */ #include <stdio.h> #include <stdlib.h> int main(int args, char **argv) { int s1, s2; float sonuc; char op; if(args != 4){ printf("Eksik veya fazla parametre !\n"); printf("Kullanimi: hesap <sayi1> <operator> <sayi2>\n"); return 1; } s1 = atoi(argv[1]); op = argv[2][0]; karakteri: operator */ s2 = atoi(argv[3]); /* 1. parametre: sayi1 */ /* 2. parametrenin ilk /* 3. parametre: sayi2 */

switch(op) { case '+': sonuc = s1 + s2; break; case '-': sonuc = s1 - s2; break; case '*': sonuc = s1 * s2; break; case '/': sonuc = (float) s1 / s2; break; case '%': sonuc = s1 % s2; break; default: sonuc = 0.0; printf("Yanlis operator %c\n",op); printf("Operatorler: +, -, *, / veya %%\n"); } printf("sonuc = %f\n",sonuc); return 0; }

Program hesap.c adl dosyada sakland varsaylrsa, programn Linux ortamndaki kts yle olacaktr:

9.4 Komut Satr rnekleri


Aada verilen iki program, Linux iletim sistemindeki cp ve wc komutlarnn basit kaynak kodlardr:
cp (copy) komutu, bir text dosyasnn kopyasn Kullanm: cp kaynak_dosya hedef_dosya wc

oluturur.

(word count) komutu, bir dosyann ka karakter, kelime satrdan olutuunu bulup ekrana yazar.
Kullanm: wc dosya_ad

Ders 10: Diziler


Giri
Dizi, ayn tipteki verilere tek bir isimle erimek iin kullanlan bir kmedir. Bu kme matematikteki kme kavramndan biraz farkldr. Bir dizi bildirildikten sonra, dizinin btn elemanlar bellekte pepee saklanr. Bu yzden dizilere tek bir isim altnda ok sayda deiken ieren bellek blgesi de denir. Buna gre, bir diziyi dizi yapan iki temel zellik vardr:

dizi elemanlarn bellekte (program alt srece) srekli biimde bulunmas

dizi elemanlarn ayn trden deikenler olmas

10.1 Dizilerin Bildirimi


Bir dizi ok sayda deiken barndrdndan, bunlar birbirinden ayrdetmek iin indis ad verilen bir bilgiye ihtiya vardr. C Programlama Dili'nde, bir dizi hangi tipte tanmlanm olursa olsun balang indisi her zaman 0'dr. Bir dizinin bildirim ileminin genel biimi syledir:
veriTipi dizi_ad[eleman_says];

rnein, 5 elemanl, ktle verilerini bellekte tutmak iin, kutle dizisi yle tanmlanabilir:
float kutle[5];

Bu dizinin elemanlarna bir deer atama ilemi yle yaplabilir:


kutle[0] kutle[1] kutle[2] kutle[3] kutle[4] = = = = = 8.471 3.683 9.107 4.739 3.918

NOT 1. elemann indisi 0, 5. elemann indisinin 4 olduuna dikkat edin.

Bildirim srasnda dizilerin eleman says tamsay trnden bir sabit ifadesiyle belirtilmesi zorunludur. rnein:
int n = 100; int a[n];

eklindeki tanmlama, dizi uzunluunun deiken (n) ile belirtilmesi nedeniyle geersizdir. Bunun yerine, dizilerin eleman says aadaki gibi sembolik sabitlerle belirtmek mmkndr.
#define n ... int a[n]; 100

Bir dizinin bellekte kaplad alann bayt cinsinden karl sizeof operatr ile renilebilir.
int a[5], b, c; ... b = sizeof(a); c = sizeof(a) / sizeof(int);

/* bellekte kaplad alan: b = 4*5 = 20 bayt */ /* Dizinin boyutu : c = 20/4 = 5 */

10.2 Dizilere Balang Deeri Verme


Bir diziye balang deerleri aadaki gibi ksa formda atanabilir:
float kutle[5]= { 8.471, 3.683, 9.107, 4.739, 3.918 }; int maliyet[3] = { 25, 72, 94 }; double a[4] = { 10.0, 5.2, 7.5, 0.0};

Kme parantezlerinin sonlandrc ; karakteri ile bittiine dikkat ediniz. Bir dizinin uzunluu belirtilmeden de balang deeri atamak mmkndr.
int a[] = { 100, 200, 300, 400 }; float v[] = { 9.8, 11.0, 7.5, 0.0, 12.5};

Derleyici bu ekilde bir atama ile karlatnda, kme parantezi iindeki eleman saysn hesaplar ve dizinin o uzunlukta aldn varsayar. Yukardaki rnekte, a dizisinin 4, v dizisinin 5 elemanl olduu varsaylr.

10.3 Dizileri Yazdrma/Okuma


ve scanf fonksiyonlar bir dizinin okunmas ve yazdrlmas iin de kullanlr. rnein bir A dizisinin aadaki gibi bildirildiini varsayalm:
printf int A[10];

Bu dizinin elemanlarn klavyeden okumak iin:


for(i=0; i<10; i++) scanf("%d",&A[i]);

daha sonra bu deerlerini ekrana yazmak iin:


for(i=0;i<10;i++) printf("%d\n",A[i]);

Program 10.1, klavyeden girilen N = 10 adet saynn ortalamasn hesaplar. Ortalama forml ile hesaplanabilir.

Program 10.1: 10 saynn ortalamasn hesaplar


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: /* 10prg01.c: 10 tamsaynn aritmetik ortalamasn hesaplar */ #include <stdio.h> #define N 10 int main() { int i; float x[N], ort, toplam = 0.0; for(i=0; i<N; i++) { /* i. eleman okunuyor ... */ printf("%d. sayi : ",i+1); scanf("%f",&x[i]); toplam += x[i]; } ort = toplam/N; printf("Sayilarin ortalamasi = %f\n",ort); return 0; }

IKTI
1. sayi : 1 2. sayi : 0 3. sayi : 9 4. sayi : 7 5. sayi : 2 6. sayi : 10 7. sayi : 11 8. sayi : 4 9. sayi : 6 10. sayi : 5 Sayilarin ortalamasi = 5.500000

Bu programda, ortalamas alnacak saylar ad x olan 10 elemanl tamsay tipindeki bir dizide saklanmtr. Bu ekilde saklanan saylarn hepsi program alt srece bellekte kalacaktr. Bu sayede, program iinde daha sonra (gerektiinde) ayn saylar tekrar kullanlabilir. Bu program, dizi kullanmadan da yazlabilirdi. Fakat, baz hallerde dizi kullanmak kanlmaz olur. Porgram 10.2, n = 10 tane saynn ortalamasn ve standart sapmasn hesaplar. Standart sapma,

forml ile hesaplanabilir. Burada,

Program 10.2: 10 saynn ortalamasn ve standart sapmasn hesaplar


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: /* 10prg02.c 10 tane saynn aritmetik ortlamasn ve standart sapmasn hespalar. */ #include <stdio.h> #include <math.h> #define N 10 int main(void) { int i; float x[N], toplam = 0.0, ort, std_sap = 0.0; /* ortalama hesab */ for(i=0; i<N; i++) { printf("%d. sayi : ",i+1); scanf("%f",&x[i]); toplam += x[i]; } ort = toplam/N; /* standart sapma hesab */ for(toplam = 0.0, i=0; i<N; i++) toplam += pow(x[i]-ort, 2.0); std_sap = sqrt( toplam/(N-1) ); printf("Ortalama = %f\n",ort); printf("Standart sapma = %f\n",std_sap); return 0; }

IKTI
1. sayi : 7 2. sayi : 8 3. sayi : 9 4. sayi : 6 5. sayi : 5 6. sayi : 8 7. sayi : 8 8. sayi : 10 9. sayi : 11 10. sayi : 6 Ortalama = 7.000000 Standart sapma = 2.054805

10.4 Sralama (Sorting)


Baz uygulamalarda bir grup saynn bykten ke, veya kkten bye, doru sralanmas gerekebilir. Bu tip sralama problemleri iin eitli algoritmalar gelitirilmitir. Sralama mantn anlamadan nce bir dizinin en byk (veya en kk) elemannn nasl bulunduunu inceleyelim. Program 10.3, bir dizinin en byk elemann bulup ekrana yazar. Program 10.3: Bir dizinin en byk elemannn bulunuu
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: /* 10prg03.c Bir dizinin en byk elemann bulup ekrana yazar */ #include <stdio.h> int main(void) { int a[10] = {100, -250, 400, 125 ,550, 900, 689, 450, 347, 700}; int k, eb; /* ilk eleman en byk kabul ediliyor */ eb = a[0]; for(k=1; k<10; k++) if( a[k]>eb ) eb = a[k]; printf("En buyuk eleman = %d\n",eb); return 0; }

IKTI
En buyuk eleman = 900

En byk sayy bulan bu algoritma olduka kolaydr. 12. satrda eb = a[0]; atamas ile dizinin ilk elemannn en byk olduu varsaylr. Daha sonra bye rastladka (15. satr) eb = a[k]; ileeb deimektedir. Program 10.3 bir dizinin en byk elemann bulur. En byk elemann kanc indis (eleman) olduu sorgulanmak istendiinde: programdaki koul yapsn aadaki gibi deitirmek yeterlidir. ebdeitike, i deikeni en byk elemann indisini tutar.
for(k=0; k<10; k++){ if( a[k] > eb ){ eb = a[k]; i = k; } }

n elemanl bir dizinin, elemanlarn bykten ke doru sralamak iin ok popler iki algoritma aada verilmitir[2].

Seerek Sralama (Selection Sort): En byk eleman bul baa koy biimindeki sramadr. Algoritmann uygulamas Program 10.4'de gsterilmitir. Bu algoritmada kullanlan kombinasyon says (algoritmann karmakl): n*(n-1)/2 dir. Program 10.4: Seerek Sralama (Selection Sort) Algoritmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: /* 09prg04.c Seerek Sralama (Selection Sort) Algoritmas ile bir dizinin elemanlarn bykten ke dogru sralar */ #include <stdio.h> #define n 10 int main(void) { int a[n] = {100, -250, 400, 125 ,550, 900, 689, 450, 347, 700}; int i, j, k, eb; /* Dizinin kendisi */ printf("Once : "); for(k=0;k<n;k++) printf("%5d ",a[k]); /* Srala */ for(k=0; k<n; k++){ eb = a[k]; i = k; for(j=k+1; j<n; j++) if( a[j]>eb ){ eb = a[j]; i = j; } a[i] = a[k]; a[k] = eb; } /* Sralama bitti */ printf("\nSonra: "); for(k=0; k<n; k++) printf("%5d ",a[k]); printf("\n"); return 0; }

IKTI
Once : 700 Sonra: -250 100 900 -250 700 400 689 125 550 550 450 900 400 689 347 450 125 347 100

Kabarck Sralama (Bubble Sort): Yanyana elemanlar karlatrarak yer deitir biimde sralamadr. Algoritmann uygulamas Program 10.5'de gsterilmitir. Bu algoritmann karmakl: (n-1)2 dir. Program 10.5: Kabarck Sralama (Bubble Sort) Algoritmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: /* 09prg05.c Kabarck Sralama (Bubble Sort) Algoritmas ile bir dizinin elemanlarn bykten ke dogru sralar */ #include <stdio.h> #define n 10 int main(void) { int a[n] = {100, -250, 400, 125 ,550, 900, 689, 450, 347, 700}; int j,k,gecici; /* Dizinin kendisi */ printf("Once : "); for(k=0; k<n; k++) printf("%5d ",a[k]); /* Srala */ for(k=0; k<n-1; k++) for(j=0; j<n-1; j++) if( a[j]<a[j+1] ){ gecici = a[j]; a[j] = a[j+1]; a[j+1] = gecici; } /* Sralama bitti */ printf("\nSonra: "); for(k=0; k<n; k++) printf("%5d ",a[k]); printf("\n"); return 0; }

IKTI
Once : 700 Sonra: -250 100 900 -250 700 400 689 125 550 550 450 900 400 689 347 450 125 347 100

10.5 Karakter Dizileri (Strings)


C dilinde, karakter dizileri olduka sk kullanlr. Sadece karakter dizilerine zel olarak, karakter dizilerinin sonuna sonlandrc karakter olarak adlandrlan bir simge eklenir. Sonlandrc karakter, ilemlerin hzl ve etkin bir biimde yaplabilmesine olanak salar[2]. Sonlandrc karakter:

dizinin bittii yeri gsterir, ASCII tablosunun sfr numaral ('\0') karakteridir.
char s[7] = {'d','e','n','e','m','e','\0'};

Karakter dizilerine iki ekilde balang deeri verilebilir. yada


char s[7] = "deneme";

Birinci tanmlamada sonlandrc karakter programc tarafndan konmaldr. Ikinci tanmlamada ise buna gerek yoktur. nk, sonlandrc karakter bu atamayla, derleyici tarafndan eklenir.
NOT
char s[7] = "deneme";

atamas geeli olmasna ramen, aadaki atama geersizdir:


char s[7]; char s = "deneme";

Karakter dizileri gets() fonksiyonu ile klavyeden okunabilir.


char ad[20]; ... gets(ad);

Karakter dizleri veya katarlar Blm 12'de daha ayrntl ilenecektir. Burada sadece iki basit rnek sunulmutur. Program 10.6'da bir karakter dizisinin uzunluunun nasl bulunduu, Program 10.7'de ise bir karakter dizisinin tersyz edilii gsterilmitir. nceleyiniz.

Program 10.6: Bir karakter dizisinin uzunluunu bulur


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: /* 09prg06.c: Bir karakter dizisinin uzunluunu bulur */ #include <stdio.h> int main(void) { char s[40]; int k = 0; /* diziyi oku */ printf("Bir seyler yazin : "); gets(s); /* sonlandrc karaktere kadar karakterleri say */ while( s[k]!='\0' ) k++; printf("Dizinin uzunlugu : %d\n",k); return 0; }

IKTI
Birseyler yazin : Marmara Universitesi Dizinin uzunlugu : 21

Program 10.7: Bir karakter dizisinin tersini bulur


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: /* 09prg07.c: Bir karakter dizisini tersyz eder */ #include <stdio.h> int main(void) { char s[40], gecici; int i, n; /* diziyi oku */ printf("Bir seyler yazin : "); gets(s); /* sonlandrc karaktere kadar */ for(n=0; s[n] != '\0'; n++) ; for(i=0; i<n/2; i++){ gecici = s[n-i-1]; s[n-i-1] = s[i]; s[i] = gecici; } printf("Tersi return 0; } : %s\n",s);

IKTI
Bir seyler yazin : Deneme Tersi : emeneD

10.6 ok Boyutlu Diziler


Bir dizi aadaki gibi bildirildiinde bir boyutlu (tek indisli) dizi olarak adlandrlr. Bu tip dizilere vektr denir.
float a[9];

Bir dizi birden ok boyuta sahip olabilir. rnein iki boyutlu b dizisi yle tanmlanabilir:
float b[9][4];

ki boyutlu diziler matris olarak adlandrlr. ilk boyuta satr, ikinci boyuta stn denir. Yukarda b matrisinin eleman says 9x4=36 dr. Bu durumda, genel olarak bir dizi yle gsterilir: Tablo 10.1: Dizlerin Bildirimi
Dizi eiti Tek boyutlu diziler (Vektrler) ki boyutlu diziler (Matrisler) ok boyutlu diziler Genel Bildirimi
tip dizi_ad[eleman_says] tip dizi_ad[satr_says][sutun_says] tip dizi_ad[boyut_1][boyut_2]...[boyut_n];

rnek
int veri[10]; float mat[5][4]; double x[2][4][2];

ok boyutlu diziler tek boyuta indir generek bellekte tutulurlar. Tek indisli dizilerde olduu gibi, ok indisli dizilere de balang deeri vermek mmkn. rnein 3 satr ve 4 stnlu (3x4=12 elemanl) bir x matrisinin elemanlar yle tanmlanabilir:
int x[3][4] = {11,34,42,60, 72,99,10,50, 80,66,21,38};

Bu matris ekrana matris formunda yazlmak istendiinde:


for(i=0; i<3; i++) { for(j=0; j<4; j++) printf("%4d",x[i][j]); printf("\n"); }

kts:
11 72 80 34 99 66 42 10 21 60 50 38

eklinde olacaktr.

Program 10.8, iki matrisin toplamn baka bir matrise aktarr. Matris toplam forml ile tanmldr. nceleyiniz.

Program 10.8: ki matrisin toplam


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: /* 09prg08.c: iki matrisin toplam */ #include <stdio.h> #define SAT 2 #define SUT 3 int main() { int a[SAT][SUT] = {5, 3, 7, int b[SAT][SUT] = {1, 2, 3, int c[SAT][SUT]; int i, j; puts("A Matrisi:"); for(i=0; i<SAT; i++){ for(j=0; j<SUT; j++) printf("%4d",a[i][j]); printf("\n"); } puts("B Matrisi:"); for(i=0; i<SAT; i++){ for(j=0; j<SUT; j++) printf("%4d",b[i][j]); printf("\n"); } puts("\nC Matrisi:"); for(i=0; i<SAT; i++){ for(j=0; j<SUT; j++){ c[i][j] = a[i][j] + b[i][j]; printf("%4d",c[i][j]); } printf("\n"); } return 0; }

0, 1, 2}; 4, 5, 6};

IKTI
A Matrisi: 5 3 0 1 B Matrisi: 1 2 4 5

7 2 3 6

C Matrisi: 6 5 10 4 6 8

Program 10.9, iki kare matrisin arpm baka bir matrise aktarr. Matris arpm forml ile tanmldr.

Program 10.9: ki matrisin arpm


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: /* 10prg09.c: 3x3 boyutundaki iki kare matrisin arpm */ #include <stdio.h> #define N 3

int main() { int a[N][N], b[N][N], c[N][N]; int i,j,k,toplam; puts("A Matrisini girin:"); for(i=0; i<N; i++) for(j=0; j<N; j++) scanf("%d",&a[i][j]); puts("B Matrisini girin:"); for(i=0; i<N; i++) for(j=0; j<N; j++) scanf("%d",&b[i][j]); puts("\nC Matrisi:"); for(i=0; i<N; i++){ for(j=0; j<N; j++){ for(toplam=0, k=0; k<N; k++) toplam += a[i][k]*b[k][j]; c[i][j] = toplam; printf("%4d",c[i][j]); } printf("\n"); } return 0; }

IKTI
A Matrisini girin: 5 3 7 0 1 2 9 0 4 B Matrisini girin: 1 2 3 4 5 6 7 8 9 C Matrisi: 66 81 96 18 21 24 37 50 63

10.7 Dizilerin Fonksiyonlarda Kullanlmas


Diziler de sradan deikenler gibi bir fonksiyona parametere olarak akratlabilir. Fakat, aktarma kural biraz farkldr. Her zaman dizinin yannda boyutunun da bilinmesi gerekir. Program 10.10'da, bir dizinin elemanlarnn yazdrlmas ii bir fonksiyona yaptrlmtr. Fonkisyona parametre olarak dizinin yannda boyutu da ilave edilmitir. nceleyiniz. Program 10.10: Bir dizinin yazdrlmas
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: /* 10prg10.c: bir dizinin yazdrlmas */ #include <stdio.h> void dizi_yaz(float x[], int n); int main(){ float kutle[5]= { 8.471, 3.683, 9.107, 4.739, 3.918 }; dizi_yaz(kutle, 5); return 0; } void dizi_yaz(float x[], int n) { int i; for(i=0; i<n; i++) printf("%7.3f", x[i]); printf("\n"); }

IKTI
8.471 3.683 9.107 4.739 3.918

Eer dizi boyutu #define nilemcisi ile belirtilirse boyutun ayrca parametre olarak kullanlmasna gerek youktur. Bu durumda Program 10.10 yle deitirlebilir:
... #define BOYUT 5 void dizi_yaz(float x[]); void main(void) { float kutle[BOYUT]= { 8.471, 3.683, 9.107, 4.739, 3.918 }; dizi_yaz(kutle); } ...

Program 10.3'de bir dizinin en byk elemannn nasl bulunduu gsterilmiti. En byk eleman bulma ilemi bir fonksiyona nasl yaptrld Program 10.11'de gsterilmitir.

Program 10.11: Bir dizinin en byk elemannn bulunmas


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: /* 10prg11.c Bir dizinin en byk elemannn fonksiyonla bulunmas */ #include <stdio.h> /* n elemanl bir dizinin enbyk elemann gnderir */ int enBuyuk(int a[], int n) { int k, en_buyuk_eleman; /* ilk eleman en byk kabul ediliyor */ en_buyuk_eleman = a[0]; for(k=1; k<n; k++) if( a[k]>en_buyuk_eleman ) en_buyuk_eleman = a[k]; return en_buyuk_eleman; } int main() { int a[10] = {100, -250, 400, 125 ,550, 900, 689, 450, 347, 700}; int eb; eb = enBuyuk(a,10); printf("En buyuk eleman = %d\n",eb); return 0; }

IKTI
En buyuk eleman = 900

Son olarak, bir kare matrisin iz (trace) deerini bulup ekrana yazan bir fonksiyon Program 10.12'de verilmiitir. Bir kare matrisin izi, matrisin asal kegen zerinde bulunan elemanlarn toplam olarak tanmldr. Bu tanma gre, aadaki matrisin izi 2 + 8 + 4 = 14 tr..

z matematiksel olarak yle gsterilir:

Program 10.12: Bir matrisin izi


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: /* 10prg12.c Bir 3x3 bir matrisin izinin fonksiyonla bulunmas */ #include <stdio.h> double iz(double a[][3], int); int main() { double a[3][3], izA; int i,j; puts("matrisi girin:"); for(i=0; i<3; i++) for(j=0; j<3; j++) scanf("%lf",&a[i][j]); izA = iz(a,3); printf("matrisin izi = %lf\n",izA); return 0; } double iz(double a[][3], int n) { int i; double toplam = 0.0; for(i=0; i<n; i++) toplam += a[i][i]; return toplam; }

IKTI
matrisi girin: 2 1 -5 3 8 6 7 1 4 matrisin izi = 14.000000

Matrisler, fonksiyonlara parametre olarak geirilirken ikinci boyununda verildiine dikkat edin.

Ders 11: Gsterici (Pointer) Kavram


Giri
Hemen hemen btn programlama dillerinin temelinde gsterici (pointer) veri tipi bulunmaktadr. Bir ok dil gsterici kullanmn kullancya sunmamtr veya ok snrl olarak sunmutur. Fakat C Progrmalama Dili'nde gstericiler youn olarak kullanlr. Hatta gsterici kavram C dilinin bel kemiidir. Kavranmas biraz g olan gstericiler iin -latife yaplp- C kullanclarn "gsterici kullanabilenler ve kullanmayanlar" olmak zere iki gruba ayranlar da olmutur. zetle, bir C programcs gsterici kavramn anlamadan C diline hakim olamaz. Trke yazlan C kitaplarda pointer kelimesi yerine aadaki ifadelerden biri karlalabilir: pointer = iareti = gsterici = gsterge

11.1 Deiken ve Bellek Adresi


Bilgisayarn ana bellei (RAM) sral kaydetme gzlerinden olumutur. Her gze bir adres atanmtr. Bu adreslerin deerleri 0 ila bellein sahip olduu st deere bal olarak deiebilir. rnein 1GB MB bir bellek, 1024*1024*1024 = 1073741824 adet gzden oluur. Deiken tiplerinin bellekte igal ettii alann bayt cinsinden uzunluu sizeof() operatryle renildiini hatrlayn. Bir programlama dillinde, belli bir tipte deiken tanmlanp ve bir deer atandnda, o deikene drt temel zellik elik eder: 1. 2. 3. 4. deikenin ad deikenin tipi deikenin sahip olduu deer (ierik) deikenin bellekteki adresi

rnein tam adl bir tamsay deikenini aadaki gibi tanmladmz varsayalm:
int tam = 33;

Bu deiken iin, int tipinde bellekte bir hcre ayrlr ve o hcreye 33 says ikilik (binary) say sitemindeki karl olan 4 baytlk (32 bitlik): 00000000 00000000 00000000 00100001 says elektronik olarak yazlr. tam deikenine ait drt temel zellik ekil 11.1'deki gibi gsterilebilir:

ekil 11.1: Bir deikene elik eden drt temel zellik Bellek adresleri genellikle onaltlk (hexadecimal) say sisteminde ifade edilir. 0x3fffd14 says onluk (decimal) say sisteminde 67108116 sayna kark gelir. Bunun anlam, tam deikeni, program alt srece, bellekte 67108116. - 67108120. numaral gzler arasndaki 4 baytlk hcreyi igal edecek olmasdr. ekil 11.1'deki gsterim, basit ama anlalr bir tasvirdir. Gerekte, int tipindekitam deikeninin bellekteki yerleimi ve ierii (deeri) ekil 11.2'de gsterildii gibi olacaktr.

ekil 11.2: tam adl deikenin bellekteki gerek konumu ve ikilik dzendeki ierii Deikenin sakl olduu adres, & karakteri ile tanml adres operatr ile renilebilir. Bu operatr bir deikenin nne konursa, o deikenin ierii ile deil adresi ile ilgileniliyor anlamna gelir. Aadaki program parasnn:
int tam = 33; printf("icerik: %d\n",tam); printf("adres : %p\n",&tam);

kts:
icerik: 33 adres : 3fffd14

eklindedir. Burada birinci satr tam deikeninin ierii, ikinci ise adresidir. Adres yazdrlrken %p tip belirleyicisinin kullanldna dikkat ediniz.

11.2 Gsterici Nedir?


Gsterici, bellek alanndaki bir gzn adresinin sakland deikendir. Gstericilere veriler (yani deikenlerin ierii) deil de, o verilerin bellekte sakl olduu hcrenin balang adresleri atanr. Ksaca gsterici adres tutan bir deikendir. Bir gsterici, dier deikenler gibi, saysal bir deikendir. Bu sebeple kullanlmadan nce program iinde bildirilmelidir. Gsterici tipindeki deikenler yle tanmlanr:
tip_ad *gsterici_ad;

Burada tip_ad herhangi bir C tip ad olabilir. Deikenin nnedeki * karakteri ynlendirme (indirection) operatr olarak adlandrlr ve bu deikenin veri deil bir adres bilgisi tutacan iaret eder. rnein:
char *kr; int *x; float *deger, sonuc; deikenler */ /* tek bir karakter iin */ /* bir tamsay iin */ /* deger gsterici tipinde, sonuc sradan bir gerel

Yukarda bildirilen gstericilerden; kr bir karakterin, x bir tamsaynn ve deger bir gerel saynn bellekte sakl olduu yerlerin adreslerini tutar. Bir gstericiye, bir deikenin adresini atamak iin adres operatrn kullanabiliriz. rnein tamsay tipindeki tam adl bir deiken ve ptam bir gsterici olsun. Derleyicide, aadaki gibi bir atama yapldnda:
int *ptam, tam = 33; . . . ptam = &tam;

gstericisinin tam deikeninin sakland adresi tutacaktr. Bu durum ekil 11.3'deki gibi tasvir edilir.
ptam

ekil 11.3: Gstericinin bir deikenin adresini gstermesi

ekil 11.3'deki gsterimde, ptam gstericisinin ierii tam deikeninin ierii (33) deil adresidir (0x3fffd14). Ayrca, ptam deikeni, bellekte baka bir hcrede saklandna ve bu hcrenin intdeil int * tipinde bir blge olduuna dikkat ediniz. Buraya kadar anlatlanlar, Program 11.1'de zetlenmitir. Program 11.1: Bir deikenin ieriini ve adresini ekrana yazdrma
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: /* 10prg01.c: ilk gsterici program */ #include <stdio.h> int main() { int *ptam, tam = 33; ptam = &tam; printf("tam: printf("tam: printf("tam: return 0; } icerik = %d\n", tam); adres = %p\n",&tam); adres = %p\n",ptam);

7. satrda deikenler bildirilmitir. 9. satrdaki atama ile tam deikeninin adresi, ptam gstericisine atanmtr. Bu satrdan itibaren ptam, tam deikeninin gsterir. 11. satda tam'n ierii (33 says), 12. ve 13. satrda tam'n adresi, %p tip karakteri ile, ekrana yazdrlmtr. Ekran kts incelendiinde, &tam ve ptam iereriinin ayn anlamda olduu grlr. IKTI
tam: tam: tam: tam icerik = 33 adres = 0x3fffd14 adres = 0x3fffd14

adl deikenin ieriine ptam gsterici zerinde de eriilebilir. Bunun iin program iinde ptam deikeninin nne ynelendirme operatr (*) koymak yeterlidir. Yani *ptam, tam deikeninin adresini deil ieriini tutar. Buna gre:
*ptam = 44;

komutuyla, ptam'n adresini tuttuu hcreye 44 deeri atanr. Bu durum, Program 11.2'de gsterilmitir.

Program 11.2: Bir deikenin ieriini ve adresini ekrana yazdrma


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: /* 10prg02.c: ikinci gsterici program */ #include <stdio.h> int main() { int *ptam, tam = 33; ptam = &tam; /* ptam -> tam */

printf("&tam = %p\n",&tam); printf("ptam = %p\n",ptam); printf("\n"); printf("tam = %d\n",tam); printf("*ptam = %d\n",*ptam); printf("\n"); *ptam = 44; /* tam = 44 anlamnda */

printf("tam = %d\n",tam); printf("*ptam = %d\n",*ptam); return 0; }

IKTI
&tam ptam = 0x3fffd14 = 0x3fffd14

tam = 33 *ptam = 33 tam = 44 *ptam = 44

zetle ptam
*ptam

= &tam

atamasyla:

ve tam, tam adl deikenin ierii ile ilgilidir. ptam ve &tam, tam adl deikenin adresi ile ilgilidir. * ynlendirme ve & adres operatrdr.

11.3 Gsterici Aritmetii


Gstericiler kullanlrken, bazen gstericinin gsterdii adres taban alnp, o adresten nceki veya sonraki adreslere eriilmesi istenebilir. Bu durum, gstericiler zerinde, aritmetik ilemcilerin kullanlmasn gerektirir. Gstericiler zerinde yalnzca toplama (+), karma (-), bir arttrma (++) ve bir eksiltme (--) operatrleri ilemleri yaplabilir.

Aadaki gibi tane gsterici bildirilmi olsun:


char *kar; int *tam; double *ger;

Bu gstericiler srasyla, bir karakter, bir tamsay ve bir gerel saynn bellekte saklanaca adreslerini tutar. Herhangi bir anda, tuttuklar adresler de srasyla 10000 (0x2710), 20000 (0x4e20) ve 30000 (0x7530) olsun. Buna gre aadaki atama ielemlerinin sonucu:
kar++; tam++; ger++;

srasyla 10001 (0x2711), 20004 (0x4e24) ve 30008 (0x7538) olur. Bir gstericiye ekleme yapldnda, o anda tuttuu adres ile eklenen say dorudan toplanmaz. Byle olsayd, bu atamalarn sonular srasyla 10001, 20001 ve 30001 olurdu. Gerekte, gstericiye bir eklemek, gstericinin gsterdii yerdeki veriden hemen sonraki verinin adresini hesaplamaktr. Genel olarak, bir gstericiye n saysn eklemek (veya karmak), bekllekte gsterdii veriden sonra (veya nce) gelen n. elemann adresini hesaplamaktr. Buna gre aadaki atamalar yle yorumlanr.
kar++; tam = tam + 5; ger = ger - 3; /* kar = kar + sizeof(char) */ /* tam = tam + 5*sizeof(int) */ /* ger = ger - 3*sizeof(double) */

Program 11.3, bu blmde anlatlanlar zetlemektedir. nceleyiniz. Program 11.3: Gsterici aritmetii
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: /* 10prg03.c: gsterici aritmetii */ #include <stdio.h> int main() { char *pk, k = 'a'; int *pt, t = 22; double *pg, g = 5.5; pk = &k; pt = &t; pg = &g; printf("Onceki pk, pt, pg); pk++; pt--; pg = pg + 10; printf("Sonraki adresler: pk= %p pk, pt, pg); return 0; } pt= %p pg= %p \n", adresler: pk= %p pt= %p pg= %p \n",

IKTI
Onceki adresler: pk= 0xbfbbe88f 0xbfbbe880 Sonraki adresler: pk= 0xbfbbe890 0xbfbbe8d0 pt= 0xbfbbe888 pt= 0xbfbbe884 pg= pg=

11.4 Gsterici ve Diziler Arasndaki liki


C dilinde gstericiler ve diziler arasnda yakn bir iliki vardr. Bir dizinin ad, dizinin ilk elemannn adresini saklayan bir gstericidir. Bu yzden, bir dizinin herhangi bir elemanna gsterici ile de eriilebilir. rnein:
int kutle[5], *p, *q;

eklinde bir bildirim yaplsn. Buna gre aada yaplan atamalar geerlidir:
p = &kutle[0]; p = kutle; q = &kutle[4]; /* birinci elemann adresi p gstericisne atand */ /* birinci elemann adresi p gstericisne atand */ /* son elemann adresi q gstericisne atand */

lk iki satrdaki atamalar ayn anlamdadr. Dizi ad bir gsterici olduu iin, dorudan ayn tipteki bir gstericiye atanabilir. Ayrca, i bir tamsay olmak zere,
kutle[i];

ile
*(p+i);

ayn anlamdadr. Bunun sebebi, p gstericisi kutle dizisinin balang adresini tutmu olmasdr. p+i ilemi ile i+1. elemann adresi, ve *(p+i) ile de bu adresteki deer hesaplanr.
NOT Bir dizinin, i. elemanna erimek iin *(p+i) ilemi yaplmas zorunludur. Yani
*p+i; /* p nin gsterdii deere (dizinin ilk elemanna) i saysn ekle */ *(p+i); /* p nin gsterdii adresten i blok tedeki sayy hesapla */ anlamndadr. nk, * operatr + operatrne gre ilem nceliine

sahiptir.

Program 11.4'de tanmlanan fonksiyon kendine parameter olarak gelen n elemanl bir dizinin aritmetik ortlamasn hesaplar.

Program 11.4: Bir dizi ile gsterici arasndaki iliki


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: /* 10prg04.c: gsterici dizi ilikisi */ #include <stdio.h> double ortalama(double dizi[], int n); int main() { double a[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; double o; o = ortalama(a,5); printf("Dizinin ortalamas = %lf\n",o); return 0; } double ortalama(double dizi[], int n) { double *p, t=0.0; int i; p = dizi; /* veya p = &dizi[0] */

for(i=0; i<n; i++) t += *(p+i); return (t/n); }

IKTI
Dizinin ortalamas = 3.300000

20. - 31. satrda tanmlanan fonksiyon aadaki gibi de yazlabilirdi:


double ortalama(double dizi[], int n) { double *p, t=0.0; for(p=dizi; p < &dizi[n]; p++) t += *p; return (t/n); }

Bu fonksiyonda, dng sayac iin (i deikeni) kullanlmayp, dng iinde dizinin balang adresi p gstericisine atanm ve koul ksmnda adres karlatrlmas yaplmtr. Bu durumda dng,p'nin tuttuu adresten balar, ve p'nin adresi dizinin son elemannn adresinden (&dizi[n-1]) kk veya eit olduu srece evrim yinelenir.

11.5 Fonksiyon Parametresi Olan Gstericiler


C (ve C++) programlama dilinde fonksiyon parametreleri deer geerek (pass by value) yada adres geerek (pass by reference) olarak geilebilir. Blm 8'deki uygulamalarda fonksiyonlara parametreler deer geerek tanmt. Bu ekilde geirilen parametreler, fonksiyon iersinde deitirilse bile, fonksiyon alldktan sonra bu deiim arlan yerdeki deerini deitirmez. Fakat, bir parametre adres geerek aktarlsa, fonksiyon iindeki deiikler geilen parametreyi etkiler. Adres geerek aktarm, gsterici kullanmay zorunlu klar. rnein, Program 11.5'de fonksiyonlara deer ve adres geerek aktarmn nasl yaplaca gsterilmitir. Program 11.5: Bir deikenin ieriini ve adresini ekrana yazdrma
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: /* 10prg05.c: Deer geerek ve adres geerek aktarm */ #include <stdio.h> void f1(int ); void f2(int *); int main() { int x = 55; printf("x in degeri,\n"); printf("Fonksiyonlar cagrilmadan once: %d\n",x); /* f1 fonksiyonu arlyor...*/ f1(x); printf("f1 cagirildiktan sonra /* f2 fonksiyonu arlyor...*/ f2(&x); printf("f2 cagirildiktan sonra return 0; } /* Deer geerek aktarm */ void f1(int n){ n = 66; printf("f1 fonksiyonu icinde } /* Adres geerek aktarm */ void f2(int *n){ *n = 77; printf("f2 fonksiyonu icinde } /* iki fonksiyon */

: %d\n",x);

: %d\n",x);

: %d\n",n);

: %d\n",*n);

5. ve 6. satrlada kendine geilen parametrenin deerini alan f1 fonksiyonu ve parametrenin adresini alan f2 adl iki fonksiyon rnei belirtilmidir. 11. satrdaki x deikeni 16. ve 21. satrlarda,f1(x) ve f2(&x) fonksiyonlarna, srasyla deer ve adres geerek aktarlmtr. f1 iinde x (n = 66; ilemi ile) deiime uram, fakat arlma ileminin

sonucunda, x'in deeri deimemitir. Ancak f2 iinde x'in ( *n = 77 ilemi ile) deiimi, arldktan sonrada korunmutur. Yani, adres geerek yaplan aktarmda, f2'ye aktarlan deer deil adres olduu iin, yollanan x parametresi f2iinde deiiklie urayacak ve bu deiim arld 21. satrdan itibaren devam edecektir. IKTI
x in degeri, Fonksiyonlar cagrilmadan once: 55 f1 fonksiyonu icinde : 66 f1 cagirildiktan sonra : 55 f2 fonksiyonu icinde : 77 f2 cagirildiktan sonra : 77

Program 11.6'da iki tamsay deikeninin nasl takas (swap) edilecei gsterilmitir. Bu ilemi C porgramlama dilinde, eer deikenler global olarak bildirilmemise, gsterici kullanmadan bu ilemi yapmak imkanszdr. Program 11.6: ki tamsaynn birbiri ile takas edilmesi
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: /* 10prg06.c: iki saynn birbiri ile takas edilmesi */ #include <stdio.h> void takas(int *, int *); int main() { int a, b; a=22; b=33; printf("takas oncesi : a=%d takas(&a, &b); printf("takas sonrasi: a=%d return 0; } void takas(int *x, int *y) { int z; z = *x; *x = *y; *y = z; } b=%d\n",a,b); b=%d\n",a,b);

IKTI
takas oncesi : a=22 takas sonrasi: a=33 b=33 b=22

11.6 Geri Dn Deeri Gsterici Olan Fonksiyonlar


Fonkiyonlarn geri dn deeri bir gsterici olabilir. Bu durumda fonksiyon bir deer deil adres dndrecek demektir. Program 11.7'da nce bir dizinin indisleri, dizi deerleri ve dizi elemanlarnn adresleri ekrana baslr. Daha sonra, maxAdr(); fonksiyonu ile dizinin en byk elemannn adresi dndrlr. Bu rnek progam, gstericilerin gcn ok zarif bir biimde bize sunmaktadr. Ltfen inceleyiniz. Program 11.7: Bir dizinin en byk elemannn adresini renmek
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: /* 10prg07.c: */ geri donus degeri gosterici olan fonksiyon

#include <stdio.h> double* maxAdr(double a[], int boyut){ double ebd = a[0]; double *eba = &a[0]; int i; for(i=1; i<boyut; i++){ if(a[i]>ebd){ ebd = a[i]; // en byk deger eba = &a[i]; // en byk adres } } return eba; } int main() { double x[6] = {1.1, 3.3, 7.1, 5.4, 0.2, -1.5}; double *p; int k; // indis, dizi ve adresini ekrana bas for(k=0; k<6; k++){ printf("%d %lf %p\n", k, x[k], &x[k]); } p = maxAdr(x,6); printf("En byk deger: %lf\n", *p); printf("En byk adres: %p \n", p); printf("En byk konum: %d \n", int(p-&x[0])); return 0; }

Dizi elemanlar 21. satrda belirlenir. Bu dizinin indisleri, deerleri ve adresleri 26. satrda ekrana baslmtr. En byk elemann adresi 29. satrdaki p = maxAdr(a,6); ile p gstericisine atanmtr. 5. satrda bildirilen maxAdr(); fonksiyonu, en byk elemann adresini hesaplayp arlan yere gnderir. Burada dikkat edilmesi gereken husus, fonksiyonun dn deerinin yerel eba gstericisi olmasdr. eba gstericisi 12. satrda hesaplanan ve fonksiyon parametersi olan dizinin en byk elemann adresini tutmaktadr. Son olarak, fonksiyon arldktan sonra, p gstericisin gsterdii deer, tuttuu adres ve dizinin birinci elemanna gre konumu (indisi) ekrana baslmtr. Indis

hesab int(p-&x[0]) ilemi ile yaplabilir. Bu aslnda, p gstericisin tuttuu adres ile dizinin ilk elemannn adresi arasndaki farktr. Sonu yine bir adres olduu iin tamsay deer elde etmek iin int() taks kullanlmtr. Netice itibaryla bir fonksiyon ile ey ayn anda renilmi olur. IKTI
0 1 2 3 4 5 1.100000 0x7fff41b29ec0 3.300000 0x7fff41b29ec8 7.100000 0x7fff41b29ed0 5.400000 0x7fff41b29ed8 0.200000 0x7fff41b29ee0 -1.500000 0x7fff41b29ee8

En byk deger: 7.100000 En byk adres: 0x7fff41b29ed0 En byk konum: 2

11.7 Fonksiyon Gstericileri


Fonksiyon gstericileri, gsterici (pointer) kavramnn gcn gsterin dier bir uygulama alandr. Dizilerde olduu gibi, fonksiyon adlar da sabit gstericidir. Fonksiyon betiinin (kodlarnn) bellekte bir adreste tutulduu eklinde dnebiliriz. Fonksiyon gstericisi basit olarak fonksiyon adnn sakland bellek adresini tutan bir gstericidir. Fonksiyon gstericileri sayesinde fonksiyonlar baka fonksiyonlara parametre olarak aktarlabilmektedir. Fonksiyon adnn bellete yer igal ettii yle renilebilir:
int f(int); int (*pf)(int); pf = &f; /* fonksiyon bildirimi */ /* fonksiyon gstericisi bildirimi */ /* f'nin adresini pf'ye ata! */

Program 11.8: Bir fonksiyonun 'adresini' iki yoldan renme


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: /* 10prg08.c: Bir fonksiyonun 'adresini' renme */

#include <stdio.h> int f(int n){ int f=1, i; for(i=1; i<n; i++) f*=i; return f; } int main() { int (*pf)(int); pf = &f; printf("Fonksiyonun adresi = %p\n", &f); printf("Fonksiyonun adresi = %p\n", pf); return 0; }

IKTI
Fonksiyonun adresi = 0x4005b0 Fonksiyonun adresi = 0x4005b0

Aadaki ikinci rnekte, bir fonksiyon dier fonksiyona parametre olarak geirilmi ve saysal trevi hesaplanmtr. Trev hesaplanrken merkezi fark yaklam (central difference approximation) yntemi kullanlmtr.
NOT mfy ynteminde f(x) fonksiyonunun (h kk bir deer olmak zere) Taylor almlar syledir:
f(x+h) = f(x) + h*f'(x) + h2*f''(x)/2! + h3*f'''(x)/3! f(x-h) = f(x) - h*f'(x) + h2*f''(x)/2! - h2*f'''(x)/3! --f(x+h) - f(x-h) = 2*h*f'(x) + O(h3) + ... + ...

--------------------------------------------------------------------

Burada O(h3)'l terimler ihmal edilirse birinci trev yaklak olarak:


f'(x) = [f(x+h) - f(x-h)]/2h

forml ile hesaplanr.

Program 11.9: Trev alan fonksiyon


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: #include <stdio.h> double f(double); double turev( double (*)(double), double); int main() { double x = 1.1; printf("Fonksiyon x = %lf deki degeri = %lf\n", x, f(x)); printf("Fonksiyon x = %lf deki turevi = %lf\n", x, turev(f, x) ); return 0; } // trevi hesaplanacak fonksiyon double f(double x){ return x*x*x - 2*x + 5.; } // saysal trev alan fonksiyon double turev( double (*fonk)(double x), double x){ double h = 1.0e-3; return (fonk(x+h)-fonk(x-h)) / (2*h); }

IKTI
Fonksiyon x = 1.100000 deki degeri = 4.131000 Fonksiyon x = 1.100000 deki turevi = 1.630001

11.8 NULL Gsterici


Bir gstericinin bellekte herhangi bir adresi gstermesi, veya ncden gstermi olduu adres iptal edilmesi istemirse NULL sabiti kullanlr. Bu sabit derleyicide ASCII karakter tablosunun ilk karakteridir ve '\0' ile sembolize edilir.
int *ptr, a = 12; . . ptr = &a; /* ptr bellekte a deikenin sakland yeri gsteriyor */ . . ptr = NULL; /* ptr bellekte hi bir hcreyi gstermiyor */ *ptr = 8 /* hata! NULL gstericinin gsterdii yere bir deer atanamaz */

11.9 void Tipindeki Gstericiler


gstericiler herhangi bir veri tipine ait olmayan gstericilerdir. Bu zelliinden dolay, void gsterici genel gsterici (generic pointer) olarak da adlandrlr.
void void

gstericiler, void anahtar szc ile bildirilir. rnein:


void *adr;

gibi. gstericiler yalnzca adres saklamak iin kullanlr. Bu yzden dier gstericiler arasnda atama ilemlerinde kullanlabilir. rnein aadaki atamada derleyici bir uyar veya hata mesaj vermez:
void void *v; char *c; . . . v = c; /* sorun yok !*/

Program 11.10'de void tipindeki bir gstericinin, program iinde, farkl tipteki verileri nasl gsterecei ve kullanlaca rneklenmitir. nceleyiniz.

Program 11.10: void gsterici ile farkl tipteki verileri gsterme


01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: /* 10prg10.c: */ void gosterici (generic pointer) uygulamasi

#include <stdio.h> int main() { char kar = 'a'; int tam = 66; double ger = 1.2; void *veri; veri = &kar; printf("veri -> kar: veri %c gosteriyor\n", *(char *) veri); veri = &tam; printf("veri -> tam: simdi veri gosteriyor\n", *(int *) veri); karakter degerini

%d

tamsayi degerini

veri = &ger; printf("veri -> ger: simdi de veri %lf gercel sayi degerini gosteriyor\n", *(double *) veri); return 0; }

IKTI
veri -> kar: veri a karakter degerini gosteriyor veri -> tam: simdi veri 66 tamsayi degerini gosteriyor veri -> ger: simdi de veri 1.200000 gercel sayi degerini gosteriyor

Benzer olarak, fonksiyon parameterelerinin kopyalanmas srasnda da bu trden atama ilemleri kullanlabilir. Uygulamada, tipten bamsz adres ilemlerinin yapld fonksiyonlarda, parametre deikeni olarak void gstericiler kullanlr. rnein
void free (void *p) { . . . }

Parametresi void

*p

olan free fonksiyonu, herhangi trden gsterici ile arlabilir.

Yararlanlan Kaynaklar
1. 2. 3. 4. 5. " te C ", Dr. Rifat LKESEN, Beta Basm Yaym A., 1996 " A'dan Z'ye C Klavuzu ", Kaan ASLAN, Pusula Yaynclk ve iletiim, 1998 " A'dan Z'ye Turbo C ", Cemit BAHMENYAR, Trkmen Kitapevi, 1994 " C ile Programlama ", Yk.Mh. Hakan ERDUN, Byte Dergisi, ubat 1997 " Sams Teach Yourself C in 24 Hours ", Tony ZHANG, Macmillan Computer Publishing, 1997

Sayglarmla, Frat BKN

You might also like