Kod Dünyası

cpp etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
cpp etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

23 Ocak 2015 Cuma

Programın içinde sıkça yinelenmesi gerekebilecek küçük kod parçaları makrolar yardımıyla gerçeklenebilir. Örnekte kare alma işlemini yapmak üzere bir makro yazılmıştır. Makrolar da değişmez tanımlarına benzer şekilde #define sözcüğüyle yapılırlar. İşleyişleri de yine değişmez tanımlarına benzer şekilde olur, yani makronun adının geçtiği yere açılımı konur. Örnekteki
area = PI * sqr(radius);
komutu görülünce makro tanımında x yerine radius sözcüğü konarak kod
area = PI * ((radius) * (radius));
şekline getirilir (programcı kendisi bu şekilde yazmış gibi).
Bu işlem bir sözcük ya da sözcük grubunun yerine başka bir sözcük ya da sözcük grubunun yerleştirilmesi şeklinde yürüdüğünden kullanımına dikkat etmek gerekir. Örnekteki makro
#define sqr(x) x * x
şeklinde tanımlansa ve programda
sqr(radius + 1)
şeklinde kullanılsaydı yerine geçecek (yanlış) kod şu şekilde olurdu:
radius + 1 * radius + 1

22 Ocak 2015 Perşembe

system() Fonksiyonu
Bu kısımda standart bir derleyicinde bulunan, stdlib.h kütüphanesindeki system() fonksiyonu anlatılacaktır. Bu fonksiyon kendisine parametre olarak gelen ifadeyi UNIX, Linux veya MS-DOS komut satırına yazar ve çalıştırır. system() fonksiyonu ile, bilgisayarın tüm dosya ve çevre birimleri, küçük program parçaları sayesinde kontrol edilebilir. Genel yazım biçimi:
      system("işletim_sistemi_komutu");
Örneğin,
Windows dizininde bulunan tüm dosyaları listelemek için
      system("dir c:\\windows");
Bu fonksiyon Linux İşletim sisteminde de kullanımı aynıdır. Örneğin /root/bingul/www dizinindeki dosya ve alt dizinleri listelemek için
      system("ls -asl /root/bingul/www");
Program 19.1 D: sürücüsünde bulunan tüm dosyaları gizli ve salt okunur hale getirmek için kullanılır. Son olarak derleyicinin EXE kodu üreteceğini unutmayın. Bu EXE kodu her bilgisayarda çalışır.
Program 19.1 : D: sürücüsünde bulunan bütün dosyaları gizli ve salt-okunur hale getirir
1:  /* D: sürücüsündeki bütün dosyaları gizli ve salt-okunur hale getirir */
2:  #include <stdlib.h>
3:  main()
4:  {
5:     system("attrib d:\\*.* +h+r");
6:  }
Program 19.2 proramında autoexec.bat dosyasına DOSKEYin nasıl yükleneceği gösterilmiştir. Bunun için >> yönlendirme operatörü kullanılmıştır. Bu operatör MSDOS işletim siteminde olduğu gibi Linux işletim sisteminde de kullanımı aynıdır.
Program 19.2 : Bilgisayar açılışında DOSKEY in yüklenmesi
1:  /* autoexec.bat dosyasına 'doskey /insert' yazar */
2:  #include <stdio.h>
3:  #include <stdlib.h>
4:
5:  main()
6:  {
7:     system("echo. >> c:\\autoexec.bat");
8:     system("echo doskey /insert >> c:\\autoexec.bat");
9:     printf("DOSKEY açılışa yüklendi...\n");
10: }
DOSKEY açılışa yüklendi...
main() Fonksiyonuna Paremetre Aktarımı
Fonksiyon inşasına dayanan bir C programında, ana programın kendisi, main(), de bir fonksiyondur. Ana programa parametre aktarımı, derlenmiş bir program komut satırından (işletim sistemi ortamından) ilk çalıştırılacağı zaman yapılır. Aktarılacak parametreler, programın adı yazılıp bir boşluk bırakıldıktan hemen sonra yazılır. Parametreler, komut satırından sayısal olarak girilse bile program içinde karakter topluluğu (string) olarak gelir. Bu durumda, string ifadeleri sayısal değerlere çeviren fonksiyonlar (atoi(), atol(), atof(),...) kullanılmalıdır. Genel kullanım biçimi:
          ...
          main(arguman_sayisi,arguman_vektoru)
          int  arguman_sayısı;
          char *arguman_vektoru[];
          {
             .
             .
             .
             if(arguman_sayisi < ...){
                printf("Eksik parametre !\n");
                exit(0);
             }
             if(arguman_sayisi > ...){
                 printf("Çok fazla parametre !\n");
                 exit(0);
             }
             .
             ... arguman_vectoru[0] ... /* 1. eleman program adı  */
             ... arguman_vectoru[1] ... /* 2. eleman 1. parametre */
             ... arguman_vectoru[2] ... /* 3. eleman 2. parametre */
             .
         }
Program 19.3 i dikkatle inceleyin.
Program 19.3 : komut satırından girilen iki sayının toplamını hesaplar
1:  #include <stdio.h>
2:  #include <stdlib.h>
3:
4:  main(int argsay, char *argvek[])
5:  {
6:     int toplam;
7:
8:     if(argsay < 3){
9:       printf("Eksik parametre !\n");
10:      exit(0);
11:    }
12:    if(arguman_sayisi > 3){
13:       printf("Çok fazla parametre !\n");
14:       exit(1);
15:    }
16:
17:    toplam = atoi(argvec[1])+atoi(argvec[2]);
18:    printf("Toplamları %d\n",toplam);
19:
20:  }
Program 19.3 in derlendikten sonra MS DOS ve Linux ortamında çalıştırılması şöyledir:
MS DOS                      | UNIX / Linux
----------------------------+-----------------------
c:\>topla 1 2               |$ topla 1 2
Toplamları 3                |Toplamları 3
                            |
C:\>topla 9 5 8             |$ topla 9 5 8
Çok fazla parametre !       |Çok fazla parametre !
                            |
C:\>topla 5                 |C:\>topla 5
Eksik parametre !           |Eksik parametre !
                            |
Komut satırında yazılan dosya adı dahil toplam parametre sayısı 3 tür. Bunlar:
argsay = 3

      1            2            3
    -----        -----        -----
             
    topla          58           34

      ^            ^            ^
      |            |            |
   argvek[0]    argvek[1]    argvek[2]
şeklindedir.

20 Ocak 2015 Salı

Grafik sistemine geçmek için, initgraph() fonksiyonunu kullanmak gerekir. Tüm çizimler sadece DOS ortamında çalışır. Grafik fonksiyonlarının kullanılması için graphics.h başlık dosyası programın başına ilave edilmelidir. Grafik işlemleri için temel işlemler:
          #include <graphics.h>
          ...
          int surucu=DETECT,grmod;        /* DETECT grafik surucusunu otomatik secer */
          initgraph(&surucu,&grmod,"");   /* grafik ekranını başlatır */ 
          ...
          closegraph();                   /* grafik ekranını kapatır */
şeklindedir.
Bazı Grafik Fonksiyonları
Bu bölümde Turbo C grafik fonksiyonlarının bazıları tanıtılmıştır. Bunların dışında biçok fonsiyon vardır. Bu fonksiyonlar derleyicinin başvuru kitabından öğrenilebilir.
renkler : 0-15 arasında (0-Siyah,15-mor) renk kodları ile (yada ingilizce isimleri örneğin YELLOW gibi) tanımlıdır.
moveto(x,y);Son noktayı (x,y) noktasına taşır
lineto(x,y);Son noktadan (x,y) noktasına düz bir çizgi çizer.
line(x1,y1,x2,y2);(x1,y1) noktasından (x2,y2) noktasına düz bir çizgi çizer.
circle(x,y,r);Merkezi (x,y) olmak üzere yarıçapı r olan bir çember çizer.
arc(x,y,baş_açı,bit_açı,r);Merkezi (x,y) noktasında ve yarıçapı r olan, baş_açı açısından dan başlayıp bit_açı açısına kadar bir yay çizer.
ellipse(x,y,baş_açı,bit_açı,xr,yr);Elipsin bir parçası olan yayı, merkezi (x,y) ve yarıçapları xr, yr olacak biçimde baş_açı açısındandan başlayarak bit_açı açısına kadar bir yay çizer.
putpixel(x,y,renk);(x,y) noktasına verilen renkte bir nokta çizer.
rectangle(sol,üst,sağ,alt);Sol üst köşesi (sol,üst) ve sağ alt köşesi (sağ,alt) koordinatlarında olacak şekilde bir dikdörtgen çizer.
bar(sol,üst,sağ,alt);İki boyutlu ve taralı bir bar çizer.
bar3d(sol,üst,sağ,alt,derinlik,şapka);Üç boyutlu ön yüzeyi taralı bar çizer. Şapka 0 ise barın üst kısmı çizilmez.
setcolor(renk);Çizilen olan şeklin rengini belirler
setbkcolor(renk);Arka alanın rengini belirler.
outtext(*yazılacak ifade);Yazılacak bir ifadenin grafik ekranında yazdırmak için kullanılır.
outtextxy(x,y,*yazılacak ifade);Grafik ekranında yazılacak bir ifadeyi (x,y) ile belirlenen noktadan başlayarak yazar.
settextstyle(font,yazı yönü,yazı boyutu);Ekranda yazılacak olan bir karakterin font'unu, yönünü ve boyutunu belirler. Yön:0 ise yatay, 1 ise dikey yazar.
cleardevice();Ekranı temizler. DOS taki CLS komutu gibi.
closegraph();Grafik ekranını kapatıp normal yazı ekranına döner. (DOS ekranı).
Örnekler
Burada Bir önceki kısımda verilen fonksiyonların, bir kaç uygulaması verilmiştir.
Program 17.1 : Grafik ekranında; bir çizgi, bir çember, bir yay, bir dikdörtgen ve bir elips çizer
1: /* grafik1.c
2:    Bu program, bir çizgi, bir çember, 
3:    bir yay, bir dikdörtgen ve bir elips çizer.
4: */
5: #include <stdio.h>
6: #include <grphics.h>
7:
8: main(){
9:      int sur=DETECT,gmode;
10:      initgraph(&sur,&gmode,"");
11:  
12:      line(12,12,298,198);
13:      circle(200,100,75)  
14:      arc(200,100,90,180,50);
15:      rectangle(10,10,300,200);
16:      ellipse(320,240,0,180,50,70);  
17:
18:      getchar();
19:      closegraph();
20: return 0;  
21: }

Program 17.2 : Ekranda yatay ve dikey iki yazı yazar ve farklı kalınlıkta iki çizgi çizer
1: /* grafik2.c 
2:    Bu program ekranda yatay ve dikey iki yazı yazar ve
3:    farklı kalınlıkta iki çizgi çizer.
4: */
5: #include <graphics.h>
6: main(){
7:       int sur=DETECT,grmode;
8:       initgraph(&sur,&grmde,"");
9:
10:      outtext("Merhaba C.");   
11:      outtextxy(30,40,"Bu yazi YATAY");
13:
14:      settextstyle(2,1,5);   
15:      outtextxy(50,60,"Bu yazi DIKEY");
16:
17:      setlinestyle(0,0,3);
18:      line(320,240,500,350);
19:
20:      setlinestyle(1,1,3);
21:      circle(320,240,100);
23: }

Program 17.3 : y=f(x) ile belirlenen bir fonksiyonu çizer
1:  /* grafik3.c
2:     Bu program, [-20,+20] aralığında sin(x) 
3:     fonksiyonunun grafiğini çizer. 22: satırdaki fonksiyonu
4:     değiştirerek, başka fonksiyonlar da çizilebilir.
5:  */
6:
7:  #include <graphics.h>
8:  #include <math.h>
9:
10:  main(){       
11:      int sur=DETECT,grmode;
12:       float x,y,X,Y,olcek;
13:       initgraph(&sur,&grmde,"");
14:
15:       putpixel(320,240,5);
16:       line(0,240,640,240);
17:       line(320,0,320,480);
18:
19:       olcek=40.0;                    /* Ölçek değiştirilerek zoom yapılabilir.  */
20:
21:       setcolor(YELLOW);              /* Fonksiyonun rengi sarı                  */
22:
23:       for(X=-20.0;X<=20;X+=0.01){    /* X değerleri [-20,20] aralığında         */
24:           Y=sin(X);                  /* sin(x) fonksiyonu                       */
25:           x=320+X*olcek;             /* Dönüşüm denklemleri                     */
26:           y=240-Y*olcek;            
27:           line(x,y,x,y);             /* Fonksiyon çiziliyor...                  */
28:        }
29:
30:    getchar();
31:    closegraph();
32:    return 0;
33:  }

19 Ocak 2015 Pazartesi

C, kullanıcının kendi veri tipini tanımlamasına müsaade eder. Bu kısımda böyle veritiplerinin nasıl oluşturulacağı anlatılacaktır.
enum
Bu tip, değişkenin alabileceği değerlerin belli(sabit) olduğu durumlarda programı daha okunabilir hale getirmek için kullanılır. enum örnekleri Program 13.1 ve Program 13.2 de gösterilmiştir. Genel yazım biçimi:
          enum TipAdı{değer1,değer2,...,değerN}DeğişkenAdı;
TipAdı programcı tarafından verilen tip ismidir. DeğişkenAdı ise program içinde kullanılacak olan değişkenin adıdır. Eğer kullanılmazsa program içinde daha sonra enum ile birlikte kullanılır. Örneğin:
          enum bolumler{programcilik, donanim, muhasebe, motor};
tanımı ile derleyici programcilik için 0, donanim için 1, muhasebe için 2 ve motor için 3 değerini kabul ederek atamaları buna göre yapar. Değişken adı bildirilirse daha sonra enum kullanmaya gerek kalmaz.
          enum renkler{kirmizi,mavi,sari} renk;
          enum gunler{pazartesi,sali,carsamba,persembe,cuma,cumartesi,pazar};
Şimdi istenirse tanımlanan bu tipler program içinde kullanılabilir.
          enum bolumler bolum;
          enum gunler gun;

          bolum = muhasebe /* bolum = 2 anlaminda */
          gun   = cuma;    /* gun = 4 anlaminda   */
          renk  = kirmizi; /* renk = 0 anlaminda  */
Program 13.1 : 3 sabit renk için enum kullanımı
1:  /* enum1.c */
2:  enum renkler{kirmizi,sari,mavi};
3:
4:  main(){
5:       enum renkler renk;
6:       renk = sari;
7:       printf("\n%d",renk);
8:  }
Program 13.2 : 5 sabit bölüm için enum kullanımı
1:  /* enum2.c */
2:  enum bolumler{
3:    programcilik, donanim,   muhasebe, motor, buro
4:  }bolum;
5:
6:  main(){
7:     bolum = donanim;
8:     printf("\n%d",bolum);
9:     bolum +=2;  /* bolum=motor */
10:    printf("\n%d",bolum);
11: }
stuct
C dilinde standart tipler kullanılarak kendi tipinizi üretebilirsiniz. (struct örnekleri Program 13.3 , Program 13.4 ve Program 13.5 te gösterilmiştir). Bu yapının kullanımı:
          struct TipAdı{
       tip deg_ismi;
       tip deg_ismi;
       ...
          };
enum ile sabit bildirimi yapılırken struct ile değişken bildirimi yapılır. Bu yapının faydası, örneğin bir öğrenciye ait bilgileri bir çatı altında toplamak için:
          struct ogrenci{
       char  ad[10],soyad[20];
       long  no;
              short sinif;
          };
Bu tipte bir değişken tanımlama:
           struct ogrenci ogr1,ogr2;
şeklinde olmalıdır. ogr1 değişkeni ile tanımlanan 1. öğrencinin numarasına bir değer atama işlemi:
           ogr1.no = 2012597;
veya
           ogr1->no = 2012597;
şeklinde yapılır.
Program 13.3 : Bir öğrenciye ait bilgilerin tek bir çatı altında toplanması
1:  /* struct1.c */
2:  #include <stdio.h>
3:
4:  struct ogrenci{
5:      char ad[10],soyad[20];
6:      long no;
7:      int  sinif;
8:  }
9:
10: main(){
11:   struct ogrenci ogr;
12:   printf("Ogrenci nosu :");
13:   scanf("%ld",&ogr.no);
14:   if( ogr.no == 2248 )
15:   {
16:      ogr.no    = 2248;
17:      strcpy(ogr.ad,"Ahmet");
18:      strcpy(ogr.soyad,"Bingul");
19:      ogr.sinif = 1;
20:   }
21:   printf("\nNo    : %ld",ogr.no);
22:   printf("\nAdı   : %s ",ogr.ad);
23:   printf("\nSoyadı: %s ",ogr.soyad);
24:   printf("\nSınıfı: %d ",ogr.sinif);
25: }
Program 13.4 : Bir öğrenciye ait bilgilerin tek bir çatı altında toplanması
/* struct2.c */
#include <stdio.h>
struct ogrenci{
    char ad[10],soyad[20];
    long no;
    int  sinif;
}ogr;

main(){
   printf("Ogrenci nosu :");
   scanf("%ld",&ogr->no);
   if( ogr.no == 2248 )
   {
      ogr.no    = 2248;
      strcpy(ogr.ad,"Ahmet");
      strcpy(ogr.soyad,"Bingul");
      ogr.sinif = 1;
   }
   printf("\nNo    : %ld",ogr.no);
   printf("\nAdı   : %s ",ogr.ad);
   printf("\nSoyadı: %s ",ogr.soyad);
   printf("\nSınıfı: %d ",ogr.sinif);
}
Program 13.5 : bir topun x-y düzlemindeki zamana bağlı hareketi
1:  /* struct3.c */
2:  #include <stdio.h>
3:  #include <math.h>
4:
5:  struct koordinat{
6:    float x,y;
7:  }top;
8:
9:  main(){
10:   int i;
11:   float t;
12:
13:   for(t=0.0;t<10.0;t+=0.1){
14:     top->x = 10 - 9*cos(t);
15:     top->y = 5  + 2*sin(t);
16:     printf("%f\t%f",top->x,top->y);
17:   }
18:
19: }
tpyedef
struct ile oluşturulan yapıda typedef deyimi kullanılırsa, bu yapıdan değişken tanımlamak için tekrar struct deyiminin kullanılmasına gerek kalmaz.
         typedef struct kayit{
         char  ad[10],soyad[20];
         long  no;
         short sinif;
         }ogr1,ogr2;
bu kullanımın diğerlerinden farkı yoktur.
Bu deyimin başka kullanımı da vardır. C dilinde program kodları bu deyimle tamamen türkçeleştirilebilir. Örneğin:
          typedef int tamsayi;
şeklinde kullanılırsa programda daha sonra int tipinde bir değişken tanımlarken şu biçimde kullanılmasına izin verilir.
          tamsayi x,y; /* int x,y anlaminda */
union
Bir programda veya fonksiyonda değişkenlerin aynı bellek alanını paylaşması için ortaklık bildirimi union deyimi ile yapılır. Bu da belleğin daha verimli kullanılmasına imkan verir. Bu tipte bildirim yapılırken struct yerine union yazılır.
          union paylas{
                float f;
                int   i;
                char  kr;
          };
Dikkat: Yukarıdaki bildirim yapıldığında, bellekte bir yer ayrılmaz. Değişken bildirimi:
          union paylas bir,iki;
şeklinde yapılır. Üyelere erişmek aşağıdaki gibi olur:
          bir.kr= 'A';
          iki.f = 3.14;
          bir.i = 2000;
Program 13.6 : union x ve y nin aynı bellek alanını işgal ettiğinin kanıtı
1:  /* union1 */
2:  #include <stdio.h>
3:
4:  union paylas{
5:       int x;
6:       int y;
7:  }z;
8:
9:  main()
10: {
11:   int *X,*Y;
12:
13:    z.x = 10;
14:    X = &z.x;
15:    printf("\nTamsayı(x) : %d - bellek adresi %X",z.x,X);
16:
17:    z.y = 20;
18:    Y = &z.y;
20:    printf("\nTamsayı(y) : %d - bellek adresi %X",z.y,Y);
21: }
Tamsayı(x) : 10 - bellek adresi DF23
Tamsayı(y) : 20 - bellek adresi DF23

Çoğu programda, bazı verilerin disk üzerinde saklanmasına gerek duyulur. C programlama dilinde, disk dosyasına erişme (okuma ve yazma için) iki farklı yöntemle yapılır. Bunlar üst düzey ve alt düzey olarak adlandırılır. Bunlardan üst düzey G/Ç yöntemi ANSI tarafından desteklenmektedir. Alt düzey G/Ç ANSI tarafından desteklenmemektedir. Bu yüzden, burada Üst düzey G/Ç konu edilecektir.
Dosya Açma ve Kapama
Bir dosyaya okuma/yazma yapmak için onun açılması gerekir. Bunun için fopen() fonksiyonu kullanılır. Açılan dosya fclose() ile tekrar kapatılmalıdır. Genel olarak:
          ...
          FILE *dosya;
          ...
          dosya = fopen(dosya_adı,mod);
          ...
          fclose(dosya);
          ...
mod ile açılacak olan dosyanın ne amaçla açılacağı belirlenir. Bunlar:
          r    (read only) yalnızca okuma için açar. 
          w    (write only) yalnızca yazma için açar.
          a    (append) ekleme yapmak için açar.
          r+   Okuma/yazma için açar.
          w+   Okuma/yazma için açar.
          a+   Okuma/yazma için açar.
deneme.txt adlı bir dosyanın, yazmak için açılıp açılmadığını test etmek için aşağıdaki kod kullanılır:
          #include <stdio.h>
          ...
          FILE *yaz; /* dosya işaretçisi */
          ...
          yaz = fopen("deneme.txt","w");

          if( yaz == NULL)
          {
                 puts("bu dosya acilmiyor...");
                 exit();
          }

          /* açılırsa! dosya işlemleri */
         ...
         fclose(yaz);
         ...
Dosya Fonksiyonları
  Fonksiyon     Görevi
  fopen()       Dosya oluşturur, açar
  fclose()      Dosyayı kapatır
  putc()        Dosyaya karakter yazar
  getc()        Dosyadan karakter okur
  feof()        Dosya sonuna gelindiğini sorgular
  fprintf()     Dosyaya formatlı veri yazar
  fscanf()      Dosyadan formatlı veri okur
  fputs()       Dosyaya katar yazar
  fgets()       Dosyadan katar okur
  fwrite()      Dosyaya dizi yazar
  fread()       Dosyadan dizi okur
Örnekler
Program 12.1 : Bu program klavyeden girilen iki tamsayı ve toplamını deneme.txt adlı bir dosyaya yazar.
1:/* dosya1.c */
2: #include <stdio.h>
3:
4: main()
5: {
6: FILE *yaz;
7: int x,y,z;
8:
9: yaz = fopen("deneme.txt","w");
10: if( yaz== NULL)
11: {
12:  puts("Dosya acilamiyor...\a\n");
13:  exit();
14: }
15:
16: printf("Toplanacak iki sayı girin : ");
17: scanf("%d %d",&x,&y);
18: z = x+y;
19:
20: fputs( "Bu dosya iki sayının toplamsını gösterir!\n",yaz );
21: fprintf(yaz,"%d + %d = %d",x,y,z);
22: fclose(yaz);
23:
24: puts("Bilgiler kaydedildi. Devam etmek için ENTER tuşuna basın.");
25: getchar();
26: }
Toplanacak iki sayı girin : 5 6
Bilgiler kaydedildi. Devam etmek için ENTER tuşuna basın.

+-----------------------------------------------
| Bu dosya iki sayının toplamsını gösterir!
| 5 + 6 = 11
|
Not: deneme.txt dosyası daha önce oluşturulmuşsa Program 12.1 önceki verileri silip yerine yeni verileri yazacaktır. Ekleme yapmak için fopen() fonksiyonunu 'a' modu ile kullanılmalıdır.

Bilgisayarın c:\deneme dizininde bulunan tipler.dat adlı bir dosyaya sahip olduğumuzu varsayalım, ve bu dosyanın içeriği aşağıdaki gibi olsun.
+-------------------------------
|Ahmet
|d
|1256
|65489878
|0.822
|
Buradaki veri tipleri sırasıyla katar, karakter, tamsayı, uzun tamsayı ve reel sayı şeklindedir. dosya2.c programı bu verilerin nasıl okunacağını göstermektedir.
Program 12.2 : Bu program bir dosyaya formatlı yazılmış olan verileri okur ve ekrana basar
1: /* dosya2.c */
2: #include <stdio.h>
3: main()
4: {
5: FILE  *oku;
6: char  ktr[10],kr;
7: int   tam;
8: long  uzun_tam;
9: float reel;
10:
11: if( (oku=fopen("c:\\deneme\\tipler.dat","r")==NULL ){
12:  puts("Dosya açılmadı !\n");
13:  exit();
14: }
15:
16: fscanf(oku,"%s\n%c\n%d\n%ld\n\%f",
17:     ktr,&kr,&tam,&uzun_tam,&reel);
18:  fclose(oku);
19:
20: puts("Dosyadan okunan veriler sırasıyla:");
21: printf(%s\n%c\n%d\n%ld\n\%f",ktr,kr,tam,uzun_tam,reel);
22: 
23: }
Dosyadan okunan veriler sırasıyla:
Ahmet
d
1256
65489878
0.822

Elimizde aşağıdaki gibi bir dosya olsun. Bu dosyadan istediğimiz bir öğrencinin numarasını girerek ona ait bilgilere ulaşılmak istensin. Program 12.3 basit bir veritabanı uygulamasıdır. Bu program öğrencilere ait bilgilerin bulunduğu bir dosyadan veri okur. 16. satırda Öğrencinin numarası istenir. Eğer böyle bir numara varsa öğrenciye ait bilgiler ekrana basılır. Aksi durumda "Kayıt bulunamadı" şelinde bir ileti ekrana basılır.
+------------------------------------------------
|NO     ADI     SOYADI  mt1     mt2     fin
|---    ------- ------  ---     ---     ---
|251 Ahmet   Bingul 100 100     100
|597    Meltem  Bingul  100 100     100
|569    Metin   Celen   54      65      89
|987    Teoman Burak   45      87      65
|
Program 12.3 : Basit bir veritabanı
1: /* dosya3.c */
2: #include <stdio.h>
3:
4: main()
5: {
6: FILE  *notlar;
7: int   i,numara,no,mt1,mt2,final;
8: char  gecici[10],ad[10],soyad[10];
9:
10: if( (notlar=fopen("notlar.js","r")==NULL ){
11:  puts("Dosya açılmadı !\n");
12:  exit(0);
13: }
14:
15: printf("Numara girin: ");
16: scanf("%d",&numara);
17:
18: for(i=0;i<12;i++)
18:  fscanf(notlar,"%s",gecici);
19: 
20: no = 0;
21:
22: while( !feof(notlar) )
23: {
24:  fscanf(notlar,"%d\t%s\t%s\%d\t%d\t%d\n",
25:         &no,ad,soyad,&mt1,&mt2,&final);
26:  if( no==numara ) break;
27: }
28: fclose(oku);
29: if( no ){
30:  puts("Öğrenci Bilgileri:");
31:  printf("Numarası : %d",no);
32:  printf("Adı      : %s",ad);
33:  printf("Soyadı   : %d",soyad);
34:  printf("1.Vize   : %d",mt1);
35:  printf("2.Vize   : %d",mt2);
36:   printf("2.Vize   : %d",mt3);
37: }
38: else
39:  puts("Kayıt bulunamadı");
40:
41: }/*main*/

Bazı uygulamalarda, daha önce bir şekilde hazırlanmış olan bir dosyanın içeriğini değiştirmek gerekebilir. Program 12.4 , eski.dat dosyasındaki verileri yeni.dat dosyasına aşağıdaki çevirir. Program kodları bir dosyadan diger bir dosyaya, bir verinin nasıl taşınacağına dair bir örnek teşkil eder.
    dosya 1                    dosya 2
 _______________           ________________
|X-degerleri    |         |                |
|1.0            |         |X      Y        |
|2.0            |         |1.0    0.0      |
|3.0            |         |2.0    2.5      |
|4.0            |         |3.0    4.9      |
|5.0            |  --->   |4.0    3.2      |
|Y-degerleri    |         |5.0    1.8      |
|0.0            |         |                |
|2.5            |         |                |
|4.9            |         |                |
|3.2            |         |                |
|1.8            |         |                |
|_______________|         |________________|
Program 12.4 : dosya1 in içindeki alt alta olarak yazılmış olan verileri, dosya2 ye şekildeki gibi yan yana yazar
1: /* dosya4.c */
2: #include <stdio.h>
3:
4: main()
5: {
6:       FILE  *oku,*yaz;
7:       float x[5],y[5];
8:       char  dosya1[12],dosya2[12],gecici[10];
9:       int   i;
10:
11:        printf("Verilerin okunacağı dosyanın adı");
12:        scanf("%s",dosya1);
13:        if( (oku==fopen(dosya1,"r"))==NULL ){
14:                printf("%s dosyası acilamiyor...",dosya1);
15:                exit();
16:        }
17:
18:        printf("Verilerin yazılacağı dosyanın adı");
19:        scanf("%s",dosya2);
20:        if( (yaz==fopen(dosya1,"w"))==NULL ){
21:  printf("%s dosyası acilamiyor...",dosya2);
22:  exit();
23:         }
24:
25:     /*dosya1 den verileri oku, bu verileri x[] ve y[] dizilerine sakla */
26:        fscanf(oku,"%s",gecici);  /* rakamlarin disindaki degerleri okumak icin */
27:
28:        for(i=0;i<5;i++)  fscanf(oku,"%f\n",&x[i]);
29:
30:        fscanf(oku,"%s",gecici);
31:
32:        for(i=0;i<5;i++)  fscanf(oku,"%f\n",&y[i]);
33:
34:      fclose(oku); /* verilerin bulundugu dosyayi kapat */
35:
36:      /* dizileri dosya2 ye yaz */
37: fprintf(yaz,"X\tY");
38: for(i=0;i<5;i++)
39:             fprintf(yaz,"%f\t%f",x[i],y[i]);
40:      fclose(yaz); /* verilerin yazildigi dosyayi kapat */
41:
42:        printf("%s --> %s dönüştürme işlemi gerçekleşti.",dosya1,dosya2);
43:
44: return 0;
45:}
Bilgisayarın ana belleği (RAM) sıralı kaydetme bölgelerinden(gözlerinden) oluşmuştur. Her göze bir adres atanmıştır. Bu adreslerin değerleri 0 ila RAMe bağlı olarak MAX arasında değerler alabilir.
Programlama dillerinde bir değişken tanımlandığında, o değişkene tipine bağlı olarak RAMden bir bölge ayrılır. Örneğin rate adlı bir değişken tanımladığımızı varsayalım. Bu değişken bellekte Şekil 10.1 deki bir yere yazılır.
Bir değişkenin bellek gözündeki yeri
Şekil 10.1 : rate adlı değişkenin bellekteki adresi
Pointer(işaretçi), bellek alanındaki bir gözün adresinin saklandığı değişkendir. Pointerlara, veriler(yani değişkenlerin içeriği) değil de, o verilerin bellekte saklı olduğu bellek gözlerinin başlangıç adresleri atanır. Bir pointer, diğer değişkenler gibi, sayısal bir değişkendir. Bu sebeple kullanılmadan önde program içinde bildirilmelidir. Pointer değişkenler şöyle tanımlanır:
          tipadı *ptradı;
Burada tipadı herhangi bir C tip adı olabilir. Değişkenin önüne konan * karakteri indirection operatörü olarak adlandırılır ve tipadı ile bildirilen ptradı değişkenini işaret eder. Örneğin:
          char *kr1;          /* karakter için */
          int *x;             /* tamsayı için */
          float *deger,sonuc; /* deger pointer tipinde sonuc sıradan bir reel değişkenler */
Yukarıda bildirilen pointer değişkenlerden; kr bir karakterin, x bir tamsayının ve deger bir gerçel sayının bellekte saklı olduğu yerlerin adreslerini tutar. Fakat sonuc adlı float değişken sıradan bir gerçel sayıdır.
Bir pointera, bir değişkenin adresini atamak için & adres-operatörü kullanılır. Bu operatör bir değişkenin önüne konursa, o değişkenin içeriği ile değilde adresi ile ilgileniliyor anlamına gelir. Örneğin karakter tipindeki rate adlı bir değişken ve p_rate ise pointer tipinde, rate değişkenini işaret eden bir değişken olsun. Bu durum Şekil 10.2 de gösterilmektedir:
Bir değişken ve onun işaterçisi
Şekil 10.2 : rate adlı sıradan bir değişken ve onu işaret eden p_rate adlı pionter değişkeninin bellekteki dizilimi
Derleyicide şöyle ifade edilir:
          char rate;
          char *p_rate;
          ...
          p_rate = &rate;
Yani p_rate pointeri rate değişkeninin saklandığı adresi işaret etmektedir. Program Program 10.1 pointer kavramını anlamak için oldukça önemli bir örnektir.
Program 10.1 : ilk Pointer programı
/*ptr01.c*/
1: main()
2: {
3:  int x, *isaret;
4:
5:  x = 888;
6: isaret = &x;
7:
8: printf("x in degeri = %d\n",x);
9: printf("x in adresi = %x\n",isaret);
10: printf("x in değeri = %d\n",*isaret);
11: printf("x in adresi = %x\n",&x);
12: }
x in degeri = 888
x in adresi = ffde
x in degeri = 888
x in adresi = ffde
Özetle, eğer ptr adında bir pointera, deg adlı bir değişkene sahipseniz ve ptr = & deg; şeklinde bir atama yapmışsanız:
  • *ptr ve deg, deg adlı değişkenin içeriği ile ilgilidir.
  • ptr ve & deg, deg adlı değişkenin adresi ile ilgilidir.
  • * indirection opreratörü olarak adlandırılır.
  • & adres operatörüdür.
Dinamik Diziler
Bir dizi daha önce anlatıldığı gibi, programın başında kaç elemanlı olduğu belirtilerek bildirilirse, derleyici o dizi için gerekli bellek alanını program sonlandırılıncaya kadar saklı tutar ve o alan başka amaçlar için kullanılmaz. Dizilerde dinamik çalışma, programın çaklıştırılması sırasında gerekli bellek alanının işletim sisteminden istenmesi ve işi bittiğinde bu alanın geri verilmesidir. Bu amaçla standart kütüphanede malloc(), calloc(), realloc() ve free() fonksiyonları vardır. Bu şekilde dizileri kullanmak için:
          ...
          tip *ptr;
          ...
          ptr = malloc(50); /* herbiri 8 bit olan 50 elemanlık yer isteniyor */
          .
          .                 /* kullanılıyor */
          .
          free(ptr);        /* geri veiliyor */
          ...
Program 10.2 ile basit olarak dinamik bir dizinin kullanımı gösterilmiştir.
Program 10.2 : Dinamik bir dizinin kullanımı
1:  #include <stdio.h>
2:  #include <stdlib.h>
3:
4:  main(){
5:          int *x,i,N,toplam=0;
6:          float ortalama;
7:
8:         printf("Eleman sayısı ");
9:         scanf("%d",&N);
10:
11:        x = (int *) malloc(N*sizeof(int)); /* N tane int gözü 
12:                                              isteniyor (Nx2 byte) */
13:
14:         puts("Elemanları girin:");
15:         for(i=0;i<N;i++){
16:           printf("%d.eleman = ",i+1);
17:           scanf("%d",&x[i]);  /* x[i] ile *(x+i) aynı anlamda !... */
18:           toplam += x[i];
19:         }
20:
21:         free(x);  /* ayrılan yer boşaltılıyor... */
22:
23:         ortalama = (float) toplam/N;
24:
25:         printf("Bu %d sayının ortlaması %f dir\n",N,ortalama);         
26:
27: }
5. satırda x değişkeni pointer tipinde tanımlanmıştır. N sayısı 9. satırda klavyeden okutlmuştur. 11. satırda x pointeri için malloc() fonksiyonu ile bellekten N tane int tipinde bellek gözü istenmiştir. malloc() fonksiyonu bellekten istenen yerin başlangıç adresini x değişkenine aktarır. N tane yer istendiğine göre, x, artık N elemanlı bir dizidir. Buna göre x[0] ayrılan bölgenin ilk adresindeki değişkeni temsil eder. Benzer olarak diğer elemanlar da, bellekte peşpeşe sıralanır. Bu yüzden, x 17. satırda bir dizi gibi okutulmuştur. Eğer x bir dizi gibi ifade edilmek istenmiyorsa i. eleman x[i]*(x+i) şeklinde de kullanılabilir. x in elemanların toplamı toplam adlı değişkene 18. satırda aktarılmaktadır. 21. satırda x için ayrılan bellek alanı free fonksiyonu ile serbest bırakılmıştır.
Program 10.2 sıradan bellek kullanımından oldukça farklıdır. Eğer x bir pointer değil de, sıradan bir dizi gibi bildirilseydi, programın başında x in eleman sayısı mutlaka belirtilmesi gerekirdi. Bu bize, pointer kullanımın ne kadar önemli olduğunu gösterir.
Pointer Tipindeki Fonksiyonlar
Bir fonksiyon tanımlanırken, parametreleri pointer olabileceği gibi, tipi de pointer olabilir. Bu, o fonksiyonun kendisini çağırana bir adres göndereceği anlamına gelir. Bu tip uygulamalar özellikle string uygulamalarında sık kullanılır.
Program 10.3 de, geri dönüş değeri int tipinde olan bir pointer fonksiyon örneği verilmiştir. Bu fonksiyon iki sayının toplamının saklandığı toplam adlı değişkenin adresini, çağırılan yere gönderir.
Program 10.4 : Geri dönüş değeri, pointer olan bir fonksiyon
1:  #include <stdio.h>
2:
3:  int *topla(int,int);
4:
5:  main(){
6:    int a,b;
7:    int *p;
8:
9:    a = 2;
10:   b = 4;
11:
12:   p = topla(a,b);
13:
14:  printf("Toplam : %d (adresi %p)\n",*p,p);
15: }
16:
17: int *topla(int x,int y)
18: {
19:   int *ptr,toplam;
20:
21:   toplam = x+y;
22:   ptr = &toplam;
23:
24:   return ptr;
25: }
Toplamları 6 (adresi 0xbbb7fc4)


Dizi bir kümedir. Aynı tipte verilere tek bir isimle erişmek için kullanılır. Bir dizinin bütün elemanları bellekte peşpeşe saklanır.
Dizi Tipi             Genel bildirimi                                  Örnek
Tek boyutlu diziler   tip ad[eleman_sayısı]                            int veri[10];
İki boyutlu diziler   tip ad[satir_say][sutun_say]                float mat[5][4];
Çok boyutlu diziler   tip ad[boyut_1][boyut_2][boyut_3]...[ boyut_n]   double x[2][4][2];
Aşağıda dizilerin kullanımı il ilgili 10 adet örnek sunulmuştur. Örnekleri dikkatle inceleyin.
Program 9.1 : Dizi elamanlarına erişim.
1:  main(){
2:     int i,x[5];
3:     x[0]=5;
4:     x[1]=25;
5:     x[2]=-40;
6:     for(i=0;i<3;i++)
7:       printf("%d\n",x[i]);
8:  }
Program 9.2 : Dizilere başlangıç değeri verme
1:  main(){
2:     int i,x[5]={5,0,6};
3:     int y[]={1,5,9};
4:     puts("X  Y");
5:     for(i=0;i<3;i++)
6:       printf("%d  %d\n",x[i],y[i]);
7:  }
Program 9.3 : Karakter dizisi (String)
1:  main(){
2:     int   i;
3:     char  ad[][15]  ={"Ahmet",
4:                       "Mehmet","Can"};
5:     int   kilo[]={70,60,52};
6:     float boy[] ={1.70,1.85,1.45};
7:     puts("\nISIM\tKILO\tBOY");
8:     for(i=0;i<3;i++)
9:        printf("%s\t%d\t%1.3f\n",ad[i],kilo[i],boy[i]);
10: }
Program 9.4 : Beş sayının ortalama hesabı
1:  main(){
2:      int   i,x[5],toplam =0;
3:      float ort;
4:      for(i=0;i<5;i++){
5:        printf("%d. eleman : ",i+1);
6:        scanf("%d",&x[i]);
7:        toplam += x[i];
8:      }
9:      ort = (float) toplam/5;
10:     printf("ortalamalari : %f",ort);
11: }
Program 9.5 : Dizilerin fonksiyonla kullanma
1:  void yaz(int x[]);
2:  main(){
3:      int x[10];
4:      yaz(x);
5: }
6:
7:  void yaz(int x[]){
8:     int i;
9:     for(i=0;i<10;i++)
10:      printf("%d\n",x[i]);
11: }
12:
Program 9.6 : Dizinin bellekte kapladığı alan
1:  main(){
2:     char   dizi1[10];
3:     int    dizi2[10];
4:     float  dizi3[10];
5:     double dizi4[10];
6:     printf( "%d\n",sizeof(dizi1) );
7:     printf( "%d\n",sizeof(dizi2) );
8:     printf( "%d\n",sizeof(dizi3) );
9:     printf( "%d\n",sizeof(dizi4) );
10: }
Program 9.7 : On elemanlı bir diziye ait elamanların sırlanaması
1:  main(){
2:    int x[10],i,j,gec;
3:    puts("5 tane sayi gir:");
4:    for(i=0;i<5;i++)
5:    {
6:      printf("%d.sayi : ",i);
7:      scanf("%d",&x[i]);
8:    }
10:
11:   for(i=0;i<4;i++)
12:   {
13:       for(j=i+1;j<5;j++)
14:       {
15:    if( x[j]<x[i] )
16:       {
17:          gec = x[i];
18:          x[i] = x[j];
19:          x[j] = gec;
20:  }
21:   }
22: }
23:
24:
25:   for(i=0;i<5;i++)
26:    printf("\n%d",x[i]);
27:
28:  }
Program 9.8 : İki matrisin toplamı
1:  main(){
2:     int i,j,A[3][3],B[3][3],C[3][3];
3:     puts("iki matrisin toplami:");
4:     puts("A matrisinin elemanlarini girin:");
5:     for(i=0;i<3;i++){
6:        for(j=0;j<3;j++){
7:           printf("A(%d,%d)=",i+1,j+1);
8:      scanf("%d",&A[i][j]);
9:        }
10:   }
11:
12:   puts("B matrisinin elemanlarini girin:");
13:   for(i=0;i<3;i++){
14:      for(j=0;j<3;j++){
15:         printf("B(%d,%d)=",i+1,j+1);
16:      scanf("%d",&B[i][j]);
17:      }
18:   }
19:
20:   puts("A+B matrisinin elemanlari:");
21:   for(i=0;i<3;i++){
22:      for(j=0;j<3;j++){
23:         C[i][j] = A[i][j] + B[i][j];
24:         printf("C(%d,%d)=%d\n",i+1,j+1,C[i][j]);
25:      }
26:   }
27:
28: }
Program 9.9 : Elemanları (0,100) arsında olan rasgele dizi
1:  #include <time.h>
2:  #include <stdlib.h>
3:  main(){
4:     int i,x[10];
5:     randomize();    /* rasgele sayı üretecini başlatır */
6:     for(i=0;i<10;i++)
7:     {
8:       x[i]=random(100);       /* 0-100 arasında rasgele sayı seçiliyor */
9:       printf("%d\n",x[i]);
10:    }
11: }
Program 9.10 : Dizi elemanlarının bellekteki sıralanış adresleri
1:  main(){
2:    int i,x[10];
3:    puts("x dizisinin elemanlarının sıralanışı");
4:    for(i=0;i<10;i++)
5:     printf("%p\n",&x[i]);
6:  }
Bu tip deyimler bir kümenin belli bir koşul altında yinelenmesi için kullanılır. whiledo...while ve for olmak üzere üç tip döngü deyimi vardır. C de diğer programlama dillerinde olduğu gibi, bu deyimlerle istenildiği kadar iç-içe döngü yapısı kullanılabilir.
while
Tekrarlama deyimidir. Bir küme ya da deyim while kullanılarak bir çok kez yinelenebilir. Yinelenmesi için koşul sınaması çevrim başında yapılır. Koşul olumlu olduğu sürece çevrim yinelenir. İki veya daha çok koşul mantıksal operatörler birleştirilerek verilebilir. Bu deyimin kullanımı Program 8.1 de gösterilmiştir. Genel yazım biçimi:
      while(koşul)
      {
       ...
        döngüdeki deyimler; [küme]
       ...
      }
Program 8.1 : while döngüsünün kullanımı
1:  /* while kullanımı */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:
7:     int x=0;
8:
9:     while(x <= 10)
10:      printf("%d\n",x++);
11:
12:  return 0;
14:  }
0
1
2
3
4
5
6
7
8
9
10
Program 8.1 in amacı, 0-10 arasındaki sayıları ekrana yazdırmaktır. 9. satırdaki while ifadesinden sonra { işareti kullanılmamıştır. Bu durumda, sadece takip eden satır (10. satır) döngü nün içine dahil edilir.
do ... while
Bu deyim while dan farkı, koşulun döngü sonunda sınanmasıdır. Yani koşul sınanmadan çevrime girilir ve döngü kümesi en az bir kez yürütülür. Koşul olumsuz ise döngüden sonraki satıra geçilir. Bu deyimin kullanımı Program 8.2 de gösterilmiştir. Genel yazım biçimi:
      do
      {
        ...
        döngüdeki deyimler;
        ...
      }while(koşul);
Program 8.2 : do-while döngüsünün kullanımı
1:  /* do-while kullanımı */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:      int sayi;
7:
8:      do
9:      {
10:        printf("Bir sayı girin : ");
11:        scanf("%d",&sayi);
12:        printf("Bu sayının iki katı : %d\n",2*sayi);
13:
14:     }while( sayi>0 );   /* koşul */
15:
16:     puts("Çevrim sona erdi.");
17:
18: return 0;
19: }
Bir sayı girin : 2
Bu sayının iki katı : 4
Bir sayı girin : 5
Bu sayının iki katı : 10
Bir sayı girin : 9
Bu sayının iki katı : 18
Bir sayı girin : 0
Bu sayının iki katı : 0
Çevrim sona erdi.
14. satırdaki koşul olumlu olduğu sürece (klavyeden girilen sayi > 0 olduğu sürece), klavyeden yeni bir değer 11. satırda okunur. Aksi takdirde sayi <=0 ise çevrimin sona erdiğine dair mesaj 16. satırdaki puts fonksiyonu ile verilir.
for
Diğer döngü deyimleri gibi bir öbeği bir çok kez tekrarlamakta kullanılır. Koşul sınaması while da olduğu gibi döngüye girmeden yapılır. Bu döngü deyimin içinde diğerlerinden farklı olarak başlangıç değeri ve döngü sayacına sahip olmasıdır. Bu deyimin kullanımı Program 8.3 de gösterilmiştir Genel yazım biçimi:
      for( başlangıç ; koşul ; artım )
      {
       ...
        döngüdeki deyimler;
       ...
      }
Program 8.3 : for döngüsü ile faktoriyel hesabı
1:  /* for döngüsünün kullanımı */
2:  #include <stdio.h>
3:
4:  long faktoriyel(int n);
5:
6:  main()
7:  {
8:       int x;
9:
10:      printf("\nFaktoriyeli hesaplanacak sayı girin : ");
11:      scanf("%d",&x);
12:
13:      if(x<0)
14:          printf("Sayı 0 dan hüçük; faktoriyeli hesaplanamaz.");
15:      else
16:          printf("faktoriyeli : %ld dir",faktoriyel(x));
17:
18:  return 0;
19: }
20:
21: /* n! değerini hesaplar */
22: long faktoriyel(int n)
23: {
24:     long i,fact=1;
25:
26:    /* bu döngu ile fact = n! = 1*2*3*...*n değeri hesaplanır */
27:    for(i=1;i<=n;i++)
28:    {
29:      fact *= i;
30:    }
31:
32:    return fact; /* geri dönüş değeri long tipinde */
33: }
Faktoriyeli hesaplanacak sayı girin : 3
faktoriyeli : 6 dir
Faktoriyeli hesaplanacak sayı girin : 10
faktoriyeli : 3628800 dir
Faktoriyeli hesaplanacak sayı girin : 0
faktoriyeli : 1 dir
Faktoriyeli hesaplanacak sayı girin : -4
Sayı 0 dan hüçük; faktoriyeli hesaplanamaz.
11. satırda okunan x tamsayısının faktoriyeli 16. satırda ekrana yazdırılır. Eğer x < 0 ise 14. satırdaki mesaj ekrana çıkar. faktoriyel() fonksiyonu kendisine parametre olarak gelen değişkenin, facktoriyelini 27. satırdaki for döngüsünü kullanarak hesaplar. Fonksiyonun geri dönüş değeri long tipinde tanımlanmıştır. Çünkü faktoriyel değeri 2 bayt tan büyük bir tamsayı olabilir.
Bir programda birden çok döngü yapısı iç içe kullanılabilir. İç içe döngülerin kullanımı Program 8.4 de gösterilmiştir.
Program 8.4 : iç-içe for döngülerinin kullanılması
1:   /* iç-içe for döngüleri */
2:
3:   #include <stdio.h>
4:
5:   void kutu_ciz( int, int);
6:
7:   main()
8:   {
9:       kutu_ciz( 8, 35 );
10:
11:      return 0;
12:  }
13:
14:  void kutu_ciz( int satir, int sutun )
15:  {
16:      int sut;
17:      for ( ; satir > 0; satir--)
18:      {
19:          for (sut = sutun; sut > 0; sut--)
20:              printf("X");
21:
22:          printf("\n");
23:      }
24:  }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Program 8.4 de sadece 20. satır defalarca işleme konur. Program çalıştırıldığında 8*35=280 adet X, ekrana bastırılır. 5. satırda kutu_ciz() fonksiyonunun prototipi tanımlanmıştır. Bu fonksiyonun parametreleri (satir, sutun) ile çizilecek olan kutunun ebatları belirlenir. 8 satır ve 35 sütun için main() fonsiyonundan 9. satırda çağırılmıştır. 17. satırda ilk for döngüsü çevrime başlar. Fakat bir başalangıç değeri belirtilmemiştir, çünkü bu değer(satir) fonksiyondan buraya aktarılır. 19. satırda ikinci for döngüsü çevrime başlar ve 20. satır bu döngünün içinde değerlendirilir. Yani satir'in herbir değeri için, bütün sutun değerleri tekrarlanır. İkinci döngü tamamlandığında 22. satırda alt satıra geçilir ve birinci çevrim yeni bir değer için yinelenir.
printf() fonksiyonu ile desimal(taban-10) syılarıların nasıl yazdırılacağı bundan önceki kısımlarda gösterilmişti. Program 8.5 de Hexadesimal(taban-16) sayıların bu fonksiyon kullanılarak yazdırılması gösterilmiştir.
Program 8.5 : Desimal ve heksadecimal sayıların bastırılması
1:  /* 0-15 desimal sayıların, hexadesimal sayı sistemine çevrilmesi.
2:  ** %d -> desimal , 10 tabanındaki sayı
3:  ** %x -> hexadesimal (küçük_harf), 16 tabanındaki sayı
4:  ** %X -> hexadesimal (büyük_harf), 16 tabanındaki sayı
5:  */
6:  #include <stdio.h>
7:
8::  main()
9:  {
10:    int i;
11:
12:    printf("Hex(büyük harf)   Hex(küçük harf)   Desimal\n");
13:    for (i=0; i<16; i++){
14:    printf("%X                %x                %d\n", i, i, i);
15:    }
16: return 0;
17: }
Hex(büyük harf)  Hex(küçük harf)  Desimal
0                0                0
1                1                1
2                2                2
3                3                3
4                4                4
5                5                5
6                6                6
7                7                7
8                8                8
9                9                9
A                a                10
B                b                11
C                c                12
D                d                13
E                e                14
F                f                15
Sonsuz Döngü
Bir döngü işlemini sonsuz kere tekrarlarsa bu döngü sonzuz döngü olarak adlandırılır. Böyle bir döngü için, koşul çok önemlidir. Örneğin while döngüsü için:
          ...
          while(1)
          {
             printf("Sonsuz döngü içindeyim...\n");
          }
          ...
yada
          ...
          while(7>3)
          {
             printf("Sonsuz döngü içindeyim...\n");
          }
          ...
Her iki durumda da çevrimler, sonsuz döngü durumundadır. Çünkü while(1) ve while(7>3) deki ifadelerde, koşul hep olumludur. Bu, durumda çevrim sonsuz döngüye girer.
for döngüsünde, başlangıç, koşul ve artım parametrelerinden herhangi birini kullanmak isteğe bağlıdır. Her hangi biri verilmediğinde döngünün nasıl davranacağı iyi yorumlanmalıdır. Örneğin for döngüsünün hiçbir parametresi verilmezse, döngü sonsuz çevrime girer. Yani:
          for(;;)
              printf("Sonsuz döngü içindeyim...\n");
gibi.
Break
Bir C programında, bir işlem gerçekleştirilirken, işlemin sona erdirilmesi bu deyim ile yapılır. Örneğin, döngü deyimleri içindekiler yürütülürken, çevrimin, koşuldan bağımsız kesin olarak sonlanması gerektiğinde bu deyim kullanılır. Örneğin:
          ...
          do{
              scanf("%d",&x);
              if(x==0) break;
              printf("%d",x);
          }while(1);
          ...
yukarıdaki program parçasında, do ... while döngüsünün koşu hep olumludur. Bu durumda döngü sonnsuzdur. Fakat döngü içinde if deyimindeki koşul gerçekleşirse, dögü koşuluna bakılmaksızın döngü terkedilir. bu işlemi sağlayan break deyimidir.
Continue
Bir döngü içerisinde continue deyimi ile karşılaşılırsa, ondan sonra gelen deyimler atlanır. Yani döngü, bir sonraki çevrime girer. Örneğin:
          ...
          for(x=-50;i<=50;x++){
              if(x<0) continue;     /* x<0 ise alttaki satırı atla */
              printf("%f",sqrt(x));
          }
          ...
Program parçasının çıktısı:
          0.000000
          1.000000
          1.414213
          1.732050
          .
          .
          .
          7.071067


C dilinde ifswitch ve ? olmak üzere üç tip karşılaştırma işlemi yapılır. Ancak ? bir operatördür. if karşılaştırma deyimi ile, diğer programlarda olduğu gibi if-else yapısı kurulabilir. switch deyimi, bir değişkenin içeriğine göre program akışını yönlendirme işlemini yapar.
if, if-else Yapısı
Bu deyimler koşullu işlem yapma deyimidir. if ve else tek bir karşılaştırma deyimi olup else kullanımı isteğe bağlıdır. Eğer bu koşul olumlu ise if den sonraki bölüm yürütülür ve else den sonraki bölüm atlanır. Koşul olumsuz ise if den sonraki küme atlanır ve eğer varsa, else den sonraki kümedeki işlemler gerçekleştirilir.
      if(koşul)
      {
        ...                     
         deyimler; (küme)      
        ...                    
      }                       
Program 7.1 de basit olarak if deyiminin kullanımı gösterilmiştir. Programda bu deyim kullanılırken kümenin başngıcı ce bitişini gösteren, küme parantezleri kullanılmamıştır. Eğer if deyiminden sonra icra edilecek deyimler tek satırdan oluşuyorsa, bu işaretlerin kullanılmasına gerek yoktur. Yada if deyimden sonra { ve } işaretleri kullanılmamışsa, bu deyimi takip eden sadece ilk satır işleme konur.
Program 7.1 : if deyiminin kullanımı
1:   /* if deyiminin kullanımı */
2:
3:   #include <stdio.h>
4:
5:   int x, y;
6:
7:   main()
8:   {
9:       /* test etmek için iki değer girin */
10:
11:      printf("\nBir tamsayı değeri girin, x: ");
12:      scanf("%d", &x);
13:      printf("\nBir tamsayı değeri girin, y: ");
14:      scanf("%d", &y);
15:
16:      /* değerleri karşılaştır ve sonucu ekrena yaz */
17:
18:      if (x == y)
19:          printf("x, y ye eşit\n");
20:
21:      if (x > y)
22:          printf("x, y den büyük\n");
23:
24:      if (x < y)
25:          printf("x, y den küçük\n");
26:
27:      return 0;
28:  }
Bir tamsayı değeri girin, x: 100
Bir tamsayı değeri girin, y: 10
x, y den büyük
Bir tamsayı değeri girin, x: 10
Bir tamsayı değeri girin, y: 100
x, y den küçük
Bir tamsayı değeri girin, x: 10
Bir tamsayı değeri girin, y: 10
x, y ye eşit
5. satırında global olarak bildirilen x ve y tamsayı değişkenleri, 12 ve 14. satırlarda scanf fonksiyonu ile klavyeden okutulmuştur. 18, 21 ve 24. satırlarda kullanılan if deyimlerindeki koşul ifadeleri (Bkz Tablo 2.5) ile x, y sayıları karşılaştırılmış ve sonuç ekrana uygun bir biçimde gösterilmiştir.
if deyiminin else ile birlikte kullanımı şu şekildedir:
      if(koşul)
      {
       ...
        deyimler;(küme1)
       ...
      }
   
     else
     {
      ...
       deyimler;(küme2)
      ... 
     }

Program 7.2 de if-else yapısı irdelenmiştir. Bu program dijital elektronikte kullanılan VEYA mantık kapısının bir similasyonudur. İki girişli VEYA kapısının davranışı; eğer girişlerin her ikisi de 0 ise çıkış 0, aksi takdirde sonuç 1 olacak şeklindedir. VEYA kapısının görevini veya_kapisi(x,y) fonksiyonu üslenmiştir. Burada x ve y giriş değişkenleridir. Fonksiyonun geri dönüş değeri iki tanedir. Çünkü kapının çıkışı, girişlerdeki dijital seviyelere bağlı olarak, iki durumludur, (1-0).
Program 7.2 : if-else yapısı
1:  /* Dijital VEYA kapısı simulasyonu */
2:
3:  #include <stdio.h>
4:
5:  int veya_kapisi( int x,int y );
6:
7:  int x,y,z;
8:
9:  main()
10: {
11:      x = 1;  /* mantıksal 1 */
12:      y = 0;  /* mantıksal 0 */
13:
14:      z = veya_kapisi(x,y);  /* VEYA işlemi yapılıyor... */
15:
16:      printf("%d ve %d nin VEYA işlemi : %d dir\n",x,y,z);
17:
18: return 0;
20: }
21:
22: int veya_kapisi(x,y)
23: {
24:     if( x==0 && y==0 ) return 0;
25:     else return 1;
26: }
11. ve 12. satırlarda tamsayı olarak tanımlanan x ve y değişkenlerine sırasıyla 1 ve 0 değerleri atanmıştır. z değişkenine ise veya_kapisi(x,y) fonksiyonun geri dönüş değeri atanmıştır. 24. satırda, Tablo 2.5 te verilen mantıksal VE operatörü ile iki farklı durum tek koşul yapısında birleştirilmiştir. Bu şekilde bütün mantık kapıları tanımlanırsa, bir çok dijital elektronik devryi tasarlamak mümkün olur. Bu yolla 8x1 Multiplexer oluşturabilirmisiniz?
Eğer program içinde kullanılacak koşulların sayısı 2 den çok ise şu yapı kullanılır:
      if(koşul)
      {
       ...
        deyimler;(küme1)
       ...
      }
   
     else if
     {
      ...
       deyimler;(küme2)
      ... 
     }
     else if
     {
      ...
       deyimler;(küme3)
      ... 
     }
     .
     .
     .
     else
     {
      ...
       deyimler;(kümeN)
      ... 
     }
Program 7.3 , ikinci dereceden bir polinomun köklerini hesaplamaktadır. Programda delta değerinin 0 dan küçük olması durumda köklerin karmaşık sayıya dönüşeceğide göz önüne alınmıştır. Bu program ifelse if veelse yapısı göstermek için oldukça iyi bir örnektir.
Program 7.3 : if, else if, else yapısı
1:  /* Diskirminant hesabı. 
2:  ** ax^2 + bx + c = 0 denkleminin, 
3:  ** karmaşık sayılı kökler dahil, çözümü.
4:  */
5:   #include <stdio.h>
6:   #include <math.h>   /* sqrt için */
7:   
8:   float a,b,c,delta,x1,x2,x,kok_delta;
9:   main()
10:  {
11:        printf("a, b, c değerlerini girin:\n");
12:        scanf("%f %f %f",&a,&b,&c);
13:
14:        delta = b*b - 4*a*c;
15:
16:        if( delta > 0.0 )
17:        {
18:               x1 = ( -b + sqrt(delta) )/( 2*a );
19:               x2 = ( -b - sqrt(delta) )/( 2*a );
20:
21:               printf("\nReel kökler :");
22:               printf("\nx1 = %f ve x2 = %f",x1,x2);
23:        }
24:
25:        else if( delta < 0.0 )
26:        {
27:               kok_delta = ( sqrt(-delta) ) / (2*a);
28:               x = -0.5*b/a;
29:
30:               printf("\nKarmaşık kökler :");
31:               printf("\nx1 = %f + %fi  ve  x2 = %f - %fi",x,kok_delta,x,kok_delta);
32:        }
33:
34:        else
35:        {
36:               x = -0.5*b/a;
37:
38:               printf("\nKökler eşit :");
39:               printf("\nx1 = x2 = %f",x);
40:        }
41:
42:  return 0;
43:  }
a, b, c değerlerini girin:
2. 3.5 -4.89
Reel kökler :
x1 = 0.916822 ve x2 = -2.666822

a, b, c değerlerini girin:
4. 4. 1.
Kökler eşit :
x1 = x2 = -0.500000

a, b, c değerlerini girin:
1. 1. 1.
Karmaşık kökler :
x1 = -0.500000 + 0.866025i  ve  x2 = -0.500000 - 0.866025i
12. satırda denklemin reel katsayıları a, b ve c klavyeden okunmaktadır. Daha sonra delta değerinin üç farklı durumu için elde edilecek kökler hesaplanır. 25. satırdaki delta değerinin 0 dan küçük olduğu durum, reel olmayan kökleri hesaplamak için kullanılır.
switch - case Yapısı
Bu deyim bir değişkenin içeriğine bakarak, programın akışını bir çok seçenekten birine yönlendiren bir deyimdir. case(durum) deyiminden sonra değişkenin durumu yazılır ve akabinde gelen satır işlenir. Bütün durumların aksi söz konu olduğunda gerçekleştirilmesi istenen deyimler default deyiminden sonraki kısımda bildirilir. Genel yazım biçimi;
      switch(degisken)
      {
             case sabit1:
                ...
                deyimler;
                 ...
             case sabit2:
                 ...
                 deyimler;
                 ...
             .
             .
             .
             case sabitN :
                 ...
                 deyimler;
                 ...
             default:
                 ...
                 varsayılan_deyimler;
                 ...
      }
Program Program 7.4 te switch fonksiyonun basit bir kullanımı gösterilmiştir.
Program 7.4 : switch-case yapısının kullanımı
1:  /* switch - case yapısının kullanımı */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     char kr;
7:
8:     printf("Lütfen bir karakter girin\n");
9:     kr = getchar(); /* tek bir karakterin okunması */
10:
11:    switch (kr){
12:       case 'a':
13:          printf("a harfine bastınız\n");
14:       case 'b':
15:          printf("b harfine bastınız\n");
16:       default:
17:          printf("a veya b ye basmadınız\n");
18:    }
19: return 0;
20: }
Lütfen bir karakter girin
c
a veya b ye basmadınız

Lütfen bir karakter girin
a
a harfine bastınız
b harfine bastınız
a veya b ye basmadınız

Lütfen bir karakter girin
b
b harfine bastınız
a veya b ye basmadınız
Program 7.4 te klavyeden okunan tek bir karakter değişkenin içeriğine bakılıp uygun dallanmalar yaptırılmıştır. 9. satırda değişken getchar() fonksiyonu ile okutulmuştur. Eğer a veya b karakterlerinden biri girilirse, ekrana bu harflerin girildiğine dair mesaj yazılacak, aksi takdirde bu karakterin dışında bir karakterin giriş olarak kullanıldığı gösteren bir mesaj yazılacaktır. Örneğin c karakteri klavyeden girilmiş ise a veya b ye basmadınız gibi. Fakat a karakterleri girildiğinde ekrana her üç durumda yazdırılmaktadır. Bunun sebebi, case 'a': durumunda sırasıyla 13, 15 ve 17. satırların işleme konmasıdır. Bunu engellemek için 13. satırdan sonra programın başka bir yere yönlendirilmesi gerekir. Bu yönlendirme bir sonraki derste anlatılacak olan break deyimi ile yapılır. break bir işlemin sona erdirilmesi için kullanılan bir deyimdir. (Bkz Program 7.5 ).
Program 7.4 te case 'a': durumu için 13, 15 ve 17. satırlar da işleme konumuştu. Eğer klavyeden a değişkeni girip ekrana sadece a harfine bastınız iletisi yazdırılmak isteniyorsa, 13. satıra break deyimi ilave edilmelidir.break deyiminin kullanımı Program 7.5 te verilmiştir.
Program 7.5 : switch-case yapısı ve break kullanımı
1:  /* switch - case yapısı ve break kullanımı */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     char kr;
7:
8:     printf("Lütfen bir karakter girin\n");
9:     kr = getchar(); /* tek bir karakterin okunması */
10:
11:    switch (kr){
12:       case 'a':
13:          printf("a harfine bastınız\n");break;
14:       case 'b':
15:          printf("b harfine bastınız\n");break;
16:       default:
17:          printf("a veya b ye basmadınız\n");break;
18:    }
19: return 0;
20: }
Lütfen bir karakter girin
a
a harfine basırınız
Program 7.5 in Program 7.4 ten farkı 13, 15 ve 17. satırların sonuna break deyimlerinin konmuş olmasıdır. Derleyici bu deyim ile karşılaştığında, bulunduğu yapının içinden koşulsuz olarak ayrılır ve takip eden işleme başlar. Program 7.5 te break ile switch - case yapısı terkedilmiştir.
Program 7.6 switch-case yapısın fonksiyonlarla kullanımı ile ilgili önemli bir örnektir. Programda, menü puts fonksiyonları kullanılarak ekrana yazdırılmış ve arkasından bir karakter okunarak, menüden hangisinin seçildiği kr değişkenine aktarılmıştır; switch-case yapısı ile uygun olan fonksiyonlara dallandırılmıştır.
Program 7.6 : switch-case yapısının fonksiyonlarla kullanımı
1:  /* switch-case yapısının fonksiyonlarla kullanımı */
2:
3:  #include <stdio.h>
4:
5:  char menu(void);
6:  int topla( int a,int b );
7:  int carp( int a,int b );
8:
9:  main()
10: {
11:      char oku;
12:      int x,y,sonuc;
13:
14:      x = 10;  /* x e bir değer atanıyor */
15:      y = 20;  /* y e bir değer atanıyor */
15:
16:      oku = menu();
17:      switch( oku )
18:      {
19:            case '1':
20:                 sonuc = topla(x,y);
21:                 printf("Toplamları : %d",sonuc);
22:                 break;
23:            case '2':
24:                 sonuc = carp(x,y);
25:                 printf("Çarpımları : %d",sonuc);
26:                 break;
27:            case '3':
28:                 printf("Program sonu...");
29:                 exit();
30:      }
31:  }
32:
33: /* menu fonksiyonu */
34: char menu(void)
35: {
36:      char kr;
37:      puts("[1]. Toplama");
38:      puts("[2]. Carpma");
39:      puts("[3]. Çıkış");
40:      puts("Seçiminiz ?");
41:
42:      kr = getchar();
43:      return kr;
44: }
45:
46: /* topla fonksiyonu */
47: int topla( int a,int b )
48: {
49:   return (a+b);
50: }
51:
52: /* carp fonksiyonu */
53: int carp( int a,int b )
54: {
55:  return (a*b);
56: }
[1]. Toplama
[2]. Çarpma
[3]. Çıkış
Seçiminiz ?
1
Toplamları : 30
Program 7.6 da 14. ve 15. satırlarda tanımlanan x ve y tamsayılarına başlangıç değerleri atanmıştır (x ve y scanf fonksiyonu ile klavyeden okutulabilirdi). oku karakter değişkenine menu fonksiyonunun geri dönüş değeri (kr) atanmış ve switch fonksiyonuna 17. satırda parametre olarak aktarılmıştır. 19. satırdaki durum gerçekleştiğinde x ve y sayılarının toplamları topla fonksiyonu ile sonuc değişkenine aktarılmıştır. Bu değişkenin içeriği 21. satırda ekrana yazılmıştır. 22. satırdaki break deyimi ile switch-case yapısı terkedilmiştir. Yani switch deyiminden sonraki satır (main fonksiyonuna ait } işareti) işleme konuştur. Program sonlanmıştır. Aynı şeyler 23. satırdaki durum içinde geçerlidir. 27. satırdaki durum gerçekleştiğinde ekrana Program sonu... ifadesi yazılır ve exit() fonksiyonu ile şartsız olarak program sonlandırılır.
Karşılaştırma Operatörü
C dilinde if-else karşılaştırma deyiminin yaptığı işi sınırlı olarak yapan bir operatördür. Genel yazım biçimi:
      (koşul) ? deyim1 : deyim2;
İlk önce koşul sınanır. Eğer koşul olumluysa (1 ise) deyim1 aksi takdirde deyim2 değerlendirilir. deyim1 ve deyim2 de atama işlemi yapılamaz. Ancak koşul deyiminde atama işlemi yapılabilir. deyim1 ve deyim2 yerine fonksiyon da kullanılabilir. Aşağıda bu deyimin kullanımına ait örnekler verilmiştir.
      x = ( a > b ) ? a : b;
Yukarıdaki ifadede koşul a'nın b'den büyük olmasıdır. Eğer olumluysa x adlı değişkene a, değilse b değeri atanır. Bu şekilde kullanım if-else yapısı ile kurulmak istenirse:
     if( a > b )  x = a;
     else         x = b;
şeklinde olacaktır.
Program 7.7 : ? - if-else yapısının kullanımı
1:  /* ? ve if-else yapısının kullanımı */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:       int x,y,z;
7:
8:       printf("x : ");scanf("%d",&x); /* x okunuyor */
9:       printf("y : ");scanf("%d",&y); /* y okunuyor */
10:
11:      if( x )  /* x 0 dan farklı mı? */
12:        z = ( y > x ) ? x*y : x+y;   /* y>x ise z=x*y, değilse z=x/y */
13:      else
14:        z = 0;
15:
16:      printf("z = %d",z);
17:
18: return 0;
19: }
x : 0
y : 6
z = 0

x : 5
y : 9
z = 45

x : 8
y : 2
z = 10
Program 7.7 nin 6. satırda tamsayı olarak tanımlanan x,y,z değişkenleri 8. ve 9. satırlarda okutulmuştur. 11. satırdaki if deyimindeki koşul biraz farklıdır. Genel olarak koşul bu şekilde bildirilirse, koşulun 0 dan farklı olup olmadığı sınanır.
Yani if( x ) ile if( x!=0 ) aynı anlamdadır. Bu kullanım çok yagındır. Eğer x 0 dan farklı ise koşul olumlu olarak değerlendirilecektir. 12. satırda ? ile bir sınama yapılmaktadır. Eğer y, x den büyük ise z değişkenine x*y, aksi takdirde x+y değeri atanmaktadır. Eğer x=0 ise 14. satırda z değişkenine 0 değeri atanmaktadır. if ve else deyimlerinden sonra { ve } karakterlerinin kullanılmadığına dikkat edin. Eğer bu şekilde kullanılırsa, bu deyimlerden sonra gelen ilk satır işleme konur. 11. satırdaki koşul doğru ise 12. satır, aksi takdirde 14. satır işleme konur.
Temel giriş/çıkış fonksiyonları kullanılırken stdio.h başlık dosyası programın başına eklenmelidir. Bu fonsiyonlardan en çok kullanılanlar aşağıda verillmiştir. Fakat bunların dışında olan bir kaç fonksiyon daha vardır.
printf() Fonksiyonu
Standart C kütüphanesinin bir parçası olan printf() fonksiyonu, değişkenlerin içeriğini veya bit mesajı ekrana bir düzenle(formatla) standart çıkışa(stdout) yazmak için belki de en çok kullanılan fonksiyondur. Daha önce yazılan örnek programlarda printf() fonksiyonu kullanılmıştı. Şimdi bu fonsiyonun nasıl kullanıldığı açıklanacaktır.
Basit olarak eğer ekrana Hata oluştu!.. şeklinde bir mesaj yazdırmak için, printf fonksiyonu çağırmak ve fonksiyon içinde, çift tırnaklar arasına, bu iletiyi yazmak yeterli olacaktır. Yani:
      printf("Hata Oluştu!..");
Çoğu zaman ekrana, programda kullanılan bir değişkenin değeri yazdırılmak istenebilir. Örneğin ekranda bir alt satıra geçerek bir x değişkeninin sayısal değerini ekrana yazdırma işlemini gerçekleştirmek istediğinizi varsayalım. Bu durumda printf() fonksiyonun kullanımı şu şekilde olacaktır:
      printf("\nx in değeri %d dir",x);
x=12 için bu işlemin sonucunda ekrana şu ileti çıkacaktır:
      x in değeri 12 dir
Bu örnekte printf fonsiyonuna iki parametre aktarılmıştır. Birincisi ekranda gösterilecek ve çift tırnaklar arasına yazılan ifadeler, ikincisi ise ekranda sayısal değeri gösterilmek istenen değişken(x). Ayrıca bir alt satıra geçme işlemi \n ile gerçekleştirilmiştir. Daha genel bir ifade ile printf fonksiyonu iki kısımdan oluşur. Şöyle ki:
      printf("karakter dizisi formatı",değişkenler);
Burada, birinci parametre karakter dizisi formatıdeğişkenler kısmı ise ikinci parametredir. karakter dizisi formatı üç kısımdan oluşmaktadır:
  • Düz metin(literal string): yazdırılmak istenen ileti.
  • Konrol karakterleri(escape squence): değişkenlerin ve sabitlerin nasıl yazılacağını belirtmek ve imlecin alt satıra geçirilmesi gibi bazı basit işlemlerin gerçekleştirilmesi için kullanılır. Bu karakterler Tablo 5.1 de listelenmiştir.
  • Tip belirleyici(conversion specifier): % işaretinden oluşur(%d gibi). Ekrana yazdırılmak istenen değişkenin tipi, % işaretinden sonra belirtilir (Bkz. Tablo 5.2 ). Yani % işaretinin hemen ardına yazılan bir veya bir kaç karakter, ilgili değişken ve sabitin nasıl yazılacağını düzenleme bilgisidir.
Tablo 5.1 : Kontrol karakterleri
KarakterAnlamı
\aSes üretir(alert)
\bimleci bir sola kaydır(backspace)
\fSayfa atla. Bir sonraki sayfanın başına geç(formfeed)
\nBir alt satıra geç(newline)
\rSatır başı yap(carriage return)
\tYatay TAB(Horizontal TAB)
\vDikey TAB(vertical TAB)
\"Çift tırnak karakterini ekrana yaz
\'Tek tırnak karakterini ekrana yaz
\\\ karakterini ekrana yaz
%%% karakterini ekrana yaz
Tablo 5.2 : Tip karakterleri
Tip KarakteriAnlamıTip
%ctek bir karakterchar
%dişaretli ondalık tamsayıint, short
%lduzun işaretli ondalık tamsayılong
%uişaretsiz ondalık tamsayıunsigned int, unsigned short
%fGerçel sayıfloat, double
%skarakter dizisi (string)char
%luişaretsiz uzun tamsayıunsigned long
Tip karakterlerini kullanarak, not=12, pi=3.14 ve kr='A' değişkenleri printf() fonksiyonu ile ekrana yazdırılmak istensin. Bunun için:
      ...
       int not=12;
       float pi=3.14;
       char kr='A';
      ...
       printf("Not=%d , pi=%f ve kr=%c dir",not,pi,kr);
      ...
printf() fonksiyonu ile yazdırabilecek ifadeler için bir sınır yoktur. parametreler herhangi bir C deyimi olabilir. Örneğin x ve nin toplamı söyle yazılabilir:
      z = x + y;
      printf("%d",z);
Bu ifade şu şekilde de yazılabilir:
      z = x + y;
      printf("%d",x+y);
printf fonksiyonu kullanımı Program 5.1 te verilmiştir.
Program 5.1 : printf() fonksiyonunun kullanımı
1:  /* sayısal değerleri ekrana yazdırmak için printf fonksiyonunun kullanımı */
2:  #include <stdio.h>
3:  
4:  /* global değişken tanımlamaları */
5:  int a = 2, b = 10, c = 50;
6:  float f = 1.05, g = 25.5, h = -0.1 ,yuzde;
7:
8:  main()
9:  {
10:      printf("\nTAB kullanılmadan yazılan tamsayılar : %d %d %d", a, b, c);
11:      printf("\nTAB kullanılarak yazılan tamsayılar  : \t%d \t%d \t%d", a, b, c);
12:
13:      printf("\nÜç reel sayının tek satırda  yazılması : %f\t%f\t%f", f, g, h);
14:      printf("\nÜç reel sayının üç satırda  yazılması: \n \n\t%f\n\t%f\n\t%f", f, g, h);
15:
16:      yuzde = (25/220)*100.0;
17:      printf("\n220 ün %%25 i %f dir", yuzde);
18:      printf("\n%f/%f işleminin sonucu = %f\n", g, f, g / f);
19:
20:      printf("\n program sonunda beep sesi çıkar...\a");
21:
22:  return 0;
23:  }
TAB kullanılmadan yazılan tamsayılar :  2 10 50
TAB kullanılarak yazılan tamsayılar  :        2       10      50
Üç reel sayının tek satırda  yazılması : 1.050000        25.500000        -0.100000
Üç reel sayının üç satırda  yazılması: 
        1.050000
        25.500000
        -0.100000
220 nin %25 i 11.363636 dir
25.500000/1.050000 işleminin sonucu = 24.285715
program sonunda beep sesi çıkar...
Program 5.1 , printf() fonksiyonu ile değişkenlerin ekrana nasıl yazıldığını ve kontrol karakterlerinin kullanımını göstermektedir. 5. ve 6. satırda değişkenler global olarak bildirilmiştir. 10. ve 11. satırlarda üç tamsayının ekrana sırasıyla yanyana TABlı(\t) TABsız olarak yazdırılmıştır. 13. ve 14. satırlarda ise üç reel sayının yan yana ve alt alta kullanımı gösterilmiştir. 17. satırda yüzde değişkenine atanan değerin nasıl yazılacağı görülmektedir. 18. satırda g/f oranının başka bir değişkene aktarılmadan da yazdırılabileceğine dair bir örnektir. Program sonlanmadan önce beep sesinin duyulmasını 20. satırdaki \a kontrol karakteri sağlamıştır.
Bazen bir reel sayı ekrana sadece üç basmak hassasiyetle yazdırılmak istenebilir. Bunun için %f tip karakterinden önce hassasiyet(virgülden öce ve sonra) yazılır. Şöyle ki:
float x = 12.123548;
printf("%f in üç basamak hassasiyetli hali %5.3f dür.",x,x);

12.123548 in üç basamak hassasiyetli hali 12.124 dür.
puts() Fonksiyonu
#include <stdio.h>
puts( katar );
katar olarak belirtilen karakter topluluğunu ekrana yazdıktan sonra, imleci alt satıra geçirir. Örneğin:
puts("puts() fonksiyonunun gösterimi!");
şekinde kullanılırsa çıkış şöyle olacaktır.
puts() fonksiyonunun gösterimi!
puts() fonksiyonu Tablo 2.7 de verilen kontrol karakterleri ile kullanılabilir.
puts("Bu birinci satır...\nBu ikinci satır...");

Bu birinci satır...
Bu ikinci satır...
scanf() Fonksiyonu
Birçok programda ekrana verilerin yazılmasının yanı sıra klavyeden veri okunması gerekebilir. scanf() fonksiyonu bu amaçla kullanılan fonksiyondur. printf() gibi scanf() fonksiyonuda Tablo 5.1 ve Tablo 5.2 de verilen karakterleri kullanır. Örneğin klavyeden bir x tamsayısı
scanf("&d",&x);
satırını yazmak yeterli olacaktır. burada & işareti adres operatörü olarak adlandırılır ve Pointerler kısmında ayrıntılı olarak açıklanacaktır. Klavyeden iki farklı sayı okunmak istendiğinde scanf() fonksiyonu şöyle kullanılır:
scanf("%d %f",&x,&y);
veriler
16 1.568
yada
16        1.568
veya
16 
1.568
şekilinde okunabilir. Program 5.2 te scanf() fonksiyonunun kullanımı gösterilmiştir.
Program 5.2 : scanf() fonksiyonun kullanımı
1:   /* scanf() fonksiyonu ile int, char ve float tipindeki verilerin okunması */
2:   #include <stdio.h>
3:
4:   main()
5:   {
6:       int   x;
8:       float y;
9:       char  kr;
10:
11:      printf("Bir tamsayı girin :");
12:      scanf("%d",&x);
13:      printf("Bir karakter girin :");
14:      scanf("%c",&kr);
15:      printf("Bir reel sayı girin :");
16:      scanf("%f",&y);
17:
18:      printf("tamsayı :%d\nkarakter :%c\nreel sayı :%f olarak girdin.");
19:
20:  return 0;
21:  }
gets() Fonksiyonu
Klavyeden bir karakter topluluğu, katar, okumak için kullanılır. Okuma işlemi yeni satır karakteriyle karşılaşılıncaya kadar sürer. puts()-gets() arsındaki ilişki, printf()- scanf() arasındaki gibidir. puts() ile ekrana bir katar yazdırılırken, gets() ile okunur. Örneğin:
  ...
  char ktr[10];
  puts("Bir şeyler yazın:");
  gets(ktr);
  ...
Yukarıdaki program parçası, klavyeden girilen karakterlerin, gets() fonksiyonu ile ktr katarına aktarmak için kullanılır. ktr[10] şeklindeki kullanım girilen katarın içerisinden ilk 10 karakteri değerlendir manasındadır. Bu kullanım daha sonra açıklanacaktır.
getchar() Fonksiyonu
Standart girişten bir karakter okur. Programı istenen bir yerde durdurup, bir karakter girinceye kadar bekletir.Örneğin:
  ...
  for(i=0;i<10;i++)
  {
    getchar();
    printf("%d\n",i);
  }
  ...
Yukarıdaki program parçası 0-9 arası sayıları sırasıyla ekranda göstermek için kullanılır. Fakat her rakamı yazdırılmadan önce klavyeden herhangi bir karakter girip ENTER tuşuna basılması beklenir. Bu bekleme getchar()fonksiyonu ile gerçekleştirilir.