Merhaba,
Sitemize giriş yapmak yada üye olmak için tıklayın.
 
KOUBM sitesi
1195166 kez
ziyaret edilmiştir.

admin@koubm.org

Makale
Kategori :
C & C++
Tarih :
13/10/2005
Gönderen :
KADIR IMAMOGLU
Okunma Sayısı :
8622
C ile Programlama

1. Giriş
2. İlk C Programı – Merhaba Dünya
3. Değişkenler ve Sabitler
4. Karar Yapıları.
5. Döngüler
6. İşaretçiler (Pointer)
7. Diziler
8. Karakter Dizileri (Dizgeler)
9. Fonksiyonlar
10. Yapılar
11. Metin ve veri dosyaları


1. Giriş

C nedir ve nasıl ortaya çıkmıştır


C programlama dili 1970'li yılların başlarında Bell Laboratuvarlarında Dennis Ritchie tarafından geliştirildi. C üst düzey ve yapısal bir programlama dilidir. Ve son derece esnektir. Bundan dolayı kod yazarken çok dikkatli olmak gerekir.


C ilk başta sistem yazılımları geliştirmek için kullanılmış fakat günümüzdeki birçok değişik program C de yazılmıştır. Unix işletim sisteminin geliştirilmesinde C programlama dili kullanılmıştır. Bazı programlama dillerinin ortaya çıkış tarihleri aşağıdaki gibidir.


Fortran  1954  IBM
COBOL 1959  Bu dille yazılmış epey ticari program vardır.
BCPL  1967  Martin Richards
B  1970  Ken Thompson Bell Laboratuvarı
Pascal  1971  Niklaus Wirth (Akademik kullanımlar için)
C  1972 Dennis Ritchie  Bell Laboratuvarı
C++  1980 Bjarne Stroustrup  AT & T


1983–1989 yılları arasında ANSI C' nin standart tanımı yapıldı ve 1990 da yayımlandı. (ANSI / ISO 9899:1990)


C'de Program Geliştirme Ortamları


C' de program yazabilmek için basit anlamda bir derleyici ve editor yeter. Kodlar ASCII metin dosyası formatında yazılır. Yazılan kodlar derlenir ve çalıştırılabilir dosya oluşur. Günümüzde C programlama dili ile ilgili birçok geliştirme ortamı bulunmaktadır. Bunlardan başlıcaları aşağıdaki gibidir.


1. Turbo C : Editör ve derleyici iç içedir. Borland firması tarafından geliştirildi. MS DOS ve Windows (NT, 95, 98, ME, 2000, XP, 2003) işletim sistemlerinde   çalışmaktadır.


2. UNIX / Linux Editörleri : Burada herhangi bir editörde (vi, pico, emacs vb) kod yazılır. Emacs editöründe C komutları ve ifadeleri renkli olarak gözükür. Menülerden komut satırında yapılan işlemler yazılabilir. Aşağıdaki ilk satırda Linux ortamında GNU C derleyicisi olan gcc (http://gcc.gnu.org) ile program derlenir ve ikinci satırda derlenen program çalıştırılır.


gcc merhaba.c -o merhaba
./merhaba


3. Borland C Builder : Borland firması tarafından geliştirilmektedir. Hazır bileşen ve nesnelerin olduğu bir geliştirme ortamıdır. MS Windows işletim sistemlerinde çalışmaktadır.


4. Kylix : Borland firması tarafından geliştirilmekte ve Linux işletim sistemlerinde çalışmaktadır. Delphi ve C Builder benzeri bir geliştirme ortamıdır.


5. MS Visual C++ : Microsoft firması tarafından geliştirildi. MS Visual Stuido 6.0 paketi ile beraber gelmektedir. Windows işletim sistemlerinde çalışmaktadır.


6. Dev C++ : Bloodshed tarafından geliştirilmektedir. Windows işletim sistemlerinde çalışmaktadır. http://www.bloodshed.net/download.html adresinden ücretsiz olarak indirilebilir.


2. İlk C Programı – Merhaba Dünya


İlk C Programı


Öncelikle kullandığınız editörü (Emacs, notepad, vi vb) yada geliştirme ortamını (Kylix, C Builder, Visual C++ vb) açmanız gerekmektedir. Daha sonra aşağıdaki kodu aynen yazınız.


#include<stdio.h>
 
int main()
{
   printf("Merhaba Dünya ");
   return 0;
}


Programı yazdıktan sonra "merhaba.c" ismi ile kayıt ediniz. Ve komut satırına geçiniz. Windows ortamında Borland C Builder kullanıyorsanız ve gerekli ayarlar yapıldı ise aşağıdaki komutu giriniz.


C:>bcc32 hello.c


Linux kullanıcıları aşağıdaki komutu girmelidir.


$gcc merhaba.c –o merhaba


Buradaki –o parametresi derlenip oluşan dosyaya ad vermek için kullanılır. Eğer bu parametre kullanılmaz ise çıktı dosyası "a.out" ismi ile oluşturulur.


Bu komutlar C programınızı derler. Eğer programı yazarken herhangi bir hata yaptıysanız  derleyici size hatanın oluştuğu satırı söyleyecektir. Bu hatayı düzeltip çalıştırdığınızda ve başka bir hata yoksa program sorunsuz olarak derlenir. Windows ortamında komut satırına "merhaba.exe" yazarak, Linux ortamında "./merhaba" yazarak  derlenen programı çalıştırabilirsiniz. Eğer program çalıştırılırsa ekranda "Merhaba Dünya" yazısı görünür.


Şimdi yukarıdaki programı satır satır açıklıyalım.


#include <stdio.h> :
Bu satır programa "stdio.h" isimli kütüphane dosyasını ekler ve C programlama dilinde belli komutları kullanabilmemiz için bize gerekir. stdio Standard Input/Output' un kısaltılmışıdır. Klavyeden bilgi okuma yada ekrana yazdırma gibi komutları içerir. #include ile kullanılabilecek bazı kütüphaneler string.h, conio.h ve time.h şeklindedir. Kendimizde istersek kütüphane dosyası oluşturabiliriz.


int main() :
Bu satır programın başladığı yerdir. int ifadesi geri dönüş değeri olarak bilinir. Eğer program sorunsuz çalışırsa geri dönüş değeri 0 olur. "(" ve ")" parantezleri içerisine program dışarıdan parametre ile çalışacağı zaman gerekli tanımlamalar yapılabilir.


{ } :
Bu parantezlerin içerisine grupladığımız komutları yazarız. Burada "{" ve "}" ifadeleri arasında kalan komutların main fonksiyonuna ait olduğunu anlarız. Bu parantezler C de komutları ve ifadeleri gruplamak için çok sık kullanılır.


printf("Merhaba Dünya "); :
printf komutu ekrana yazı yazdırmak için kullanılır. Ekrana yazılmak istenen veri parantezler arasındaki çift tırnak işaretleri arasına konulur. ifadesi yeni satır karakteri diye geçer sanki Enter tuşuna basmış gibi alt satıra geçersiniz. Her komuttan sonra noktalı virgül konulması zorunludur. gibi yazıların biçimlenmesinde kullanılan bazı ifadeler aşağıdadır.


a Ses sinyalı
 Backspace
 Tab
 Yenisatır
v Vertical tab
 Yeni sayfa temiz ekran
 Carriage return


return 0; :
İşletim sistemine 0 değerini programın sorunsuz çalıştığını söylemek için döndürmemiz gerekmektedir. 0 değerini geri döndürmek için main fonksiyonun önünde int ifadesini kullandık. int ifadesi integer kelimesinin kısaltılmışıdır. Bu ifade komut olduğu için sonunda noktalı virgül vardır.


İçeriye Doğru Yazma


Yukarıdaki örnekte de gördüğünüz gibi printf ve return komutları sol taraftan içeriye doğru yazıldı. Bu şekilde kullanımın sebebi kodun daha anlaşılır olması içindir. Kodların içe doğru yazılmasını ilk başta çok zaman alan gereksiz bir iş olarak görebilirsiniz ama karmaşık programlarda bunların çok önemli olduğunu anlayacak ve ihtiyaç duyacaksınız.


Yorum Satırları


Yorum satırları programın ne iş yaptığı hakkında bilgi verir. Yorum satırları derleyici tarafından dikkate alınmaz sadece kodu inceleyen kişi tarafından kullanılır. Programın en üst kısmına programın ne iş yaptığını anlatan açıklama satırlarını koymalısınız. Çünkü ileride tekrar programı incelemek istediğinizde programı anlamanız daha kolay olacaktır. Program kodları içerisinde çok karmaşık kod parçacıklarını da yorum satırları ile açıklayınız. Yorum satırlarının nasıl kullanılacağı ile ilgili örnek aşağıdaki gibidir. Burada programın başında her programda olması gereken yazan kişinin adı, yazma tarihi, ve açıklama gibi alanlar bulunur.


/* Yazar: Adınız
   Tarih: gg/aa/yyyy
   Açıklama:
   Ekrana "Merhaba Dünya" yazısını yazar. */
 
#include<stdio.h>
 
int main()
{
   printf("Merhaba Dünya "); //ekrana "Merhaba Dünya" yazar
   return 0;
}


3. Değişkenler ve Sabitler


C programlama dilinde değişkenler isimleri ve atanmış değerleri olan hafıza konumlarıdır. Değişkenleri sonradan kullanmak amacı ile belleğe veri yüklemek için kullanırız. Sayı ve karakter tipinde olmak üzere 2 tip değişken vardır.
Sayısal Değişenler


Sayısal değişkenler tam sayı (integer) yada gerçel sayı (float) değerleri içerebilirler. Tam sayı değerlerinde virgüllü değerler yoktur. Gerçel sayılarda virgüllü değerler olabilir.
Karakter Değişkenler


Bu değişkenler alfabedeki harfler yada ASCII tablosundaki karakterleri barındırır. 0-9 arasındaki rakamlarda karakter olabilir. Karakterler tek tırnak işaretleri arasına konulur. Tırnak işaretleri arasındaki bir sayı ile tırnak işaretleri arasında olmayan bir sayı aynı değildir.
Sabitler


Değişkenler ve sabitler arasındaki fark şudur: değişkenlerin değerleri değişebilirken sabitlerin değerleri değişmez. Pi sayısı yada bir elektronun yükünü saklamada sabitler kullanışlıdır. Sabitler kullanılarak yanlışlıkla yapılabilecek değer değişikliği önlenir.
 
Değişkenleri Tanımlama


Değişkenleri tanımlarken önce değişkenin tipini daha sonrada değişenin adını yazarız. Aşağıdaki tabloda değişken tipleri ve alabildikleri değerlerin aralıkları görülmektedir.


Ad Tipi Byte Bit Aralık
int Sayısal – Tam Sayı 2 16 -32 768 - 32 767
short Sayısal – Tam Sayı 2 16 -32 768 - 32 767
unsigned short int Sayısal – Tam Sayı 2 16 0 – 65 535
long Sayısal – Tam Sayı 4 32 -2 147 483 648 to 2 147 483 647
float Sayısal – Gerçel Sayı 4 32 1.2 X 10-38 to 3.4 X 1038
double Sayısal – Gerçel Sayı 8 64 2.2 X 10-308 to 1.8 X 10308
char Karakter 1 8 Bütün ASCII karakterleri


Değişken isimleri harf, sayı yada alt çizgi karakterlerinden oluşur. Ve rakam ile başlamaz. Sadece Türkçe alfabede bulunan ç, Ç, ö, Ö, ş, Ş, Ğ, ğ, ü, Ü, İ ve ı harfleri değişken adlandırmada kullanılamaz. Değişkenleri 32 karakterden kısa tutmak kodların okunurluğu ve derleyici uyumluluğu açısından önemlidir. Aşağıda belirtilen C anahtar kelimeleri değişken adı olarak kullanılamaz.


auto breakcasecharconstcontinue default dodoubleelseenumextern floatfor gotoifintlong registerreturnshort signedsizeofstatic structswitchtypedeftypeid unionunsigned usingvoidvolatilewhile


Sizeof fonksiyonu ile değişkenlerin kapsadığı alan anlaşılabilir. Değişkenler kullanılmadan önce en üst kısımda tanımlanır. Şimdi a isminde bir sayısal ve b isminde bir karakter değişkeni tanımlayalım.


int main()
{
   int a;
   int b;
   return 0;
}


Aynı zamanda aşağıdaki gibi birden fazla değişkeni aynı satırda tanımlayabilirsiniz.


int main()
{
   int a, b, c;
   return 0;
}
Sabit Tanımlama


C programlama dilinde 3 değişik biçimde sabit tanımlayabiliriz. Bun tanımlamalar const, #define ve enum kullanılarak yapılır. Const biçiminde sabit tanımlamak için değişkenin önüne const ifadesini koymak ve bir değer atamak gerekir.


int main()
{
   const float pi = 3.14;
   return 0;
}


Sabit tanımlamada kullanılan #define direktifi ise aşağıdaki gibi kullanılabilir.


#define pi 3.1415
#define id_no 12345


enum direktifini sabitler kümesi tanımlamak istediğimizde kullanırız. C de enum tipleri sayıdır. Birçok #define kullanarak sabit tanımlama yerine tek bir enum ile kolay bir şekilde tanımlama yapılabilir.


enum gunler {Pazartesi=1,Sali,Carsamba,Persembe,Cuma,Cumartesi,Pazar};


ifadesinde Salı 2, Çarşamba 3 vb şeklinde değerlerini otomatik olarak alır.


enum RENK {KIRMIZI, MAVI, YESIL};


şeklindeki tanımlamada ise KIRMIZI 0, MAVI 1 ve YESIL 2 değerlerini alır.
İşaretli ve İşaretsiz Değişkenler


İşaretli ve işaretsiz değişkenler arasındaki fark, işaretli (signed) değişkenler negatif yada pozitif olabilirler fakat işaretsiz (unsigned) değişkenler sadece pozitif olurlar. İşaretsiz değişkenleri kullanarak en yüksek pozitif aralığa ulaşırsınız. İşaretsiz değişken tanımlamak için değişken tanımının önüne "unsigned", işaretli değişken tanımlamak için "signed" kelimesi eklenir.  İşaretli değişken tanımlamada değişkenin önüne "signed" yazma zorunlu değildir. Normal biçimde değişkeni tanımladığınızda otomatik olarak o değişken işaretli olur.


int main()
{
   unsigned short int a;
   signed int b;
   return 0;
}


Yukarıda tanımladığımız a işaretsiz değişeni 0 – 65535 aralığında değerler alabilir.
Hesaplamalarda Değişkenleri Kullanma


Bir değişkene değer atamak için  eşittir işareti kullanılır.


int main()
{
   int a;
   char b;
   a = 3;
   b = 'H';
   return 0;
}


Hesaplamalarda kullanılabilecek operatörler aşağıdaki gibidir.


Operatör İşlem
+ Ekleme
- Çıkarma
* Çarpma
/ Bölme
% Modül (Kalan Kısım)
 int main(){   int a,b;   a = 5;   b = a + 3;   a = a - 3;   return 0;}


Hesaplama yapmak için değişkenlere ihtiyaç duyarız. Değişkenler, normal sayılar yada karakterler ile bir arada kullanılabilir.
Değişkenleri okuma ve ekrana yazdırma


C Programlama dilinde giriş çıkış işlemleri gerçekte komutlar ile değil stdio.h kütüphane dosyasında bulunan fonksiyonlar ile gerçekleştirilir. Basit giriş/çıkış değişkenleri çoğunlukla tek karakter okuyan yada yazan fonksiyonlardır. Aşağıda giriş deyimlerine bir örnek verilmiştir.


char c;
...
c=getchar();


char c;
...
/* Enter tuşuna basılıncaya kadar tüm karakterleri bekler hepsini yansılar ancak sadece ilk karakteri okur */


c=getc();
c=getchar();


Aşağıda çıkış deyimi ile ilgili örnek vardır.


char c;
c=putchar();
Örnek :
Aşağıdaki program klavyeden girilen harfleri ekrana süzerek yazmaktadır. Şöyleki klavyeden girilen harflerden a harfini ekrana yazmamaktadır ve bu işlemi enter tuşuna basılıncaya kadar devam etmektedir.


#include <stdio.h>


main(){
char c;
while((c=getchar())!=' ')
 if (c!='a') putchar(c);
  printf(" ");
}


Bazen tek bir karakter değilde enter tuşuna basılıncaya kadar yada satır sonu işaretini buluncaya kadar tüm yazılanların okunmasını isteyebiliriz. Bunun için gets komutunu kullanırız. Ekrana yazı yazdırmak için puts komutu kullanılabilir.


gets(ad);//Bir karakter dizesini (satırı) klavyeden okur
puts(ad);//Bir karakter dizesini (satırı) ekrana yazar


Örnek :
Aşağıda klavyeden girilen bir karakter dizesinin tersi bulunarak ekrana yazdırılmaktadır.


#include <stdio.h>
#include <string.h>


main(){
 char ifade[100];
 int k,uzunluk;
 puts("Ifadenizi Giriniz ");
 gets(ifade);
 uzunluk=strlen(ifade);
 for(k=uzunluk-1;k>=0;k--)
  putchar(ifade[k]);
 putchar(' ');
}


Bir değişken klavyeden scanf komutu ile okutulur, printf komutu ile ekrana yazdırılır.


#include<stdio.h>
 
int main()
{
   int a;
   scanf("%d",&a);
   a = a * 2;
   printf("Cevap %d",a);
   return 0;
}


Buradaki %d ifadesi tamsayı (integer) değerleri okuma yada yazdırma amacı ile kullanılır. %d gibi diğer ifadeler aşağıda gösterilmiştir.


%d or %i int
%c char
%f float
%lf double
%s string


4. Karar Yapıları


If deyimi


Şimdiye kadar peş peşe komutlar ile nasıl program yapılacağını karar almayı kullanmadan gördük. If deyimi koşulları test etmek amacı ile kullanılır ve program akışını değiştirebilir. Aşağıda if deyimi için basit bir örnek vardır.


#include<stdio.h>
 
int main()
{
   int notu;
   char gec;
   scanf("%d",&notu);
   if (notu > 40)
      gec = 'e';
   return 0;
}


Yukarıdaki örnekte kullanıcı aldığı notu girer ve kontrol deyimi ile notunun 40'tan büyük olup olmadığına bakar. Eğer notu 40'tan büyük ise if deyimi çalışır. Şimdi de notun  40'tan küçük olduğu duruma da bakıldığı programı yazalım.


#include<stdio.h>
 
int main()
{
   int notu;
   char gec;
   scanf("%d",&notu);
   if (notu > 40)
      gec = 'e';
   else
      gec = 'h';
   return 0;
}


Eğer if deyiminde birden fazla komut çalıştırmak istiyorsak { ve } parantezlerini kullanmamız gerekmektedir. Bu parantezler komutları gruplamada kullanılır.


#include<stdio.h>
 
int main()
{
   int notu;
   char gec;
   scanf("%d",&notu);
   if (notu > 40)
   {
      gec = 'e';
      printf("Gectiniz");
   }
   else
   {
      gec = 'h';
      printf("Kaldiniz");
   }
   return 0;


if deyiminde VE (&&) ile VEYA (||) işleçleri kullanılabilir. Bu ifadelerin kullanıldığı örnek aşağıdaki gibidir.


#include<stdio.h>
 
int main()
{
   int a,b;
   scanf("%d",&a);
   scanf("%d",&b);
   if (a > 0 && b > 0)
      printf("Her iki sayıda pozitiftir. ");
   if (a == 0 || b == 0)
      printf("Sayılardan en az bir tanesi 0 dır. ");
   if (!(a > 0) && !(b > 0))
      printf("Her iki sayıda negatiftir. ");
   return 0;
}
Switch Deyimi


Switch deyimi if deyimi gibidir fakat switch deyiminde aynı anda birden fazla koşul ve buradaki koşulların komutları için bir ifade vardır. If deyiminden daha hızlı çalışır. Switch deyiminde önce kontrol edilecek değişken seçilir ve sonra her koşul için komutlar yazılır. Eğer hiç bir koşul sağlanmaz ise "default " ifadesini kullanabilirsiniz. Eğer birden fazla komut kullanırsanız, bu komutları { } parantezleri içerisine koymayı unutmayınız.


#include<stdio.h>
 
int main()
{
   char meyve;
   printf("Aşağıdakilerden hangisi sizing favori meyvenizdir: ");
   printf("a) Elmalar ");
   printf("b) Muzlar ");
   printf("c) Kirazlar ");
   scanf("%c",&meyve);
   switch (meyve)
   {
      case 'a':
         printf("Siz elmaları seviyorsunuz ");
         break;
      case 'b':
         printf("Siz muzu seviyorsunuz ");
         break;
      case 'c':
         printf("Siz kirazları seviyorsunuz ");
         break;
      default:
         printf("Geçersiz bir seçim yaptınız ");
   }
   return 0;
}
Mantıksal İfadeler


Sonucu doğru yada yanlış değer üreten ifadelere mantıksal ifade denir. Ancan C dili açısından doğru yada yanlış diye bir kavram bulunmaz. Onun yerine 0 ve 0'dan farklı değerler söz konusudur. Bu bakımdan 0 değeri yanlış olarak, diğer değerler doğru olarak algılanmalıdır. C programlama dilinde kullanılan mantıksal operatörler aşağıdaki gibidir.


== Eşittir
!= Eşit değildir
> Büyüktür
>= Büyük eşittir
< Küçüktür
<= Küçük eşittir
&& Ve
|| Yada
! Değil


5. Döngüler


Bazen birşeyi birçok kez yapmak isteyeceksiniz. Örneğin ekranda her satırın başına bir karakter yazdırmak  isteyebilirsiniz. Normalde bu işi bir sürü printf komutu ile yapmak zorunda kalırız ama döngü kullanırsak tek printf komutu ile yapmış oluruz. Üç çeşit döngü tipi vardır. Bunlar for döngüsü, while döngüsü ve do while döngüsüdür.
For döngüsü


For döngüsü size bir sayıdan diğer sayıya kadar her seferinde tanımlı miktar kadar artarak  döner. For döngüsü aşağıdaki yapıyı kullanır.


for (başlangıç sayısı;bitiş koşul;artış değişkeni)
   komut;


Eğer birden fazla komut kullanmak isterseniz parantezler arasına girebilirsiniz. Aşağıdaki örnekte for döngüsü ile ekrana 24 kez 'H' karakteri yazılır.


#include<stdio.h>
 
int main()
{
   int i;
   for (i = 1;i == 24;i++)
      printf("H ");
   return 0;
}


Buradaki i++ ifadesi i = i + 1 ifadesi ile aynıdır. Burada ayrıca ++i de kullanabilirdiniz. i++ ile ++i arasındaki fark birinde artırma sonra diğerinde önce yapılır.
While döngüsü


While döngüsü for döngüsünden farklıdır. Bu döngüyü döngünün kaç kez döneceği belli olmadığında kullanırız. While döngüsününde döngü'ye girmeden önce döngü değişkenine başlangıç değeri verilir ve bu değer döngü içerisinde değiştirilir.


#include<stdio.h>
 
int main()
{
   int i,times;
   scanf("%d",&times);
   i = 0;
   while (i <= times)
   {
      i++;
      printf("%d ",i);
   }
   return 0;
}


Do While Döngüsü


Do while döngüsü aynı while döngüsüne gibidir. Burada koşul kontrolü döngünün sonundadır.


#include<stdio.h>
 
int main()
{
   int i,times;
   scanf("%d",&times);
   i = 0;
   do
   {
      i++;
      printf("%d ",i);
   }
   while (i <= times);
   return 0;
}


Break ve Continue


Döngü çalışmasını sonlandırmak istediğimiz zaman break komutunu kullanırız. Bu komutu kullandığımız yerde döngünün kalan komutları işletilmeden hemen döngü dışarısına çıkılır.


#include<stdio.h>
 
int main()
{
   int i;
   while (i < 10)
   {
      i++;
      if (i == 5)
         break;
   }
   return 0;
}


continue komutunda döngünün geri kalan komutları işletilmeden döngünün bir sonraki adımı için döngü başına gidilir.


#include<stdio.h>
 
int main()
{
   int i;
   while (i < 10)
   {
      i++;
      continue;
      printf("Merhaba ");
   }
   return 0;
}


6. İşaretçiler (Pointer)


İşaretçiler hafıza adreslerini tutan değişkenlerdir. Hafıza adresini sakladığı için işaretçinin değeri hafıza adresinin gösterdiği yere bakılır.


İşaretçiler tipli yada tipsiz olabilirler. Tipli işaretçi tamsayı gibi belirli değişken tipine işaret eder. Tipsiz işaretçi herhangi bir veri tipini işaret edebilir. İşaretçi tanımlayabilmek için değişken adından önce * karakterinin konulması gerekir. Burada işaretçinin nasıl tanımlandığı ile ilgili örnek bulunmaktadır.


int main()
{
   int *p;
   void *up;
   return 0;
}


Bir tamsayı değişkeninin adresi tamsayı tipinde bir işaretçiye & karakterini kullanarak atanabilir.


int main()
{
   int i;
   int *p;
   i = 5;
   p = &i;
   return 0;
}


İşaret edilen bir tamsayı değişkeninin değerine işaretçinin geri referans (dereferencing) yapılması ile erişilebilir. * karakteri geri referans için kullanılmıştır.


int main()
{
   int i,j;
   int *p;
   i = 5;
   p = &i;
   j = *p; //j = i
   *p = 7; //i = 7
   return 0;
}


Bu ifade j = i işlemini yapar.


7. Diziler


Şimdiye kadar 5 tane değişken tanımlamak istediğimizde aşağıdaki gibi bir ifade kullanıyorduk.


int i1,i2,i3,i4,i5;


Eğer 100 tane değişken tanımlamak istenirse bu işlem epey zaman alacaktır. Dizi kullanırsak tek bir değişken adı ile istediğimiz kadar değişken tanımlayabiliriz. Diziler değişkenler gibi tanımlanır, sadece değişken adından sonra köşeli parantez konulur ve bu parantezin içersine kaç tane değişken tanımlanmak istenirse yazılır.


int a[5];


Dizinin bir elemanının değerine ulaşmak için değişken adı ve değişken adından sonra köşeli parantez içerisinde ulaşılmak istenen  elemanın numarası yazılır. Dizilerin sıra numarası 0'dan başlar. Örneğin 3 elemanlı bir dizi aşağıdaki gibi tanımlanır ve kullanılır.


int a[4];
a[0] = 12;
a[1] = 23;
a[2] = 34;
printf("%d",a[0]);
Dizileri döngülerde kullanma


Dizilerden en çok döngülerde kullanılırken yararlanılır. Çünkü dizilerde elemanlar birbirlerini izler. Bir dizi tanımlandığında ilk değer 0 olmaz. Bunun için diziyi sıfırlamak yani başlangıç değerlerini atama işlemini yapmamız gerekir.


int a[10];
for (i = 0;i < 10;i++)
   a[i] = 0;
Çok boyutlu diziler


Şimdiye kadar kullandığımız diziler tek boyutlu idi.


Tek boyutlu dizi 2-boyutlu dizi
0 1
1 2
2 3
   0 1 2
0 1 2 3
1 4 5 6
2 7 8 9



Üç yada daha büyük boyutlu dizileri kullanabilirsiniz. Aşağıda  iki boyutlu dizinin nasıl tanımlandığı ve nasıl kullanıldığı gösterilmektedir. Burada dizimiz iki boyutlu olduğu için iç içe 2 tane for döngüsü kullanılmıştır.


int a[3][3],i,j;
for (i = 0;i < 3;i++)
   for (j = 0;j < 3;j++)
      a[i][j] = 0;
 
Dizi Sıralama


Dizileri sıralamak için birçok algoritma vardır. Bunlardan bazıları Bubble Sort, Quick Sort ve Sequential Sort dır. Aşağıdaki program 100 elemanlı bir dizinin elemanlarını ekrandan okuyacak, azalan sırada sıraladıktan sonra tekrar ekrana yazacaktır.


#include<stdio.h>


int temp, dsay, k, l, dizi[100];


main(){
 printf("Girilecek eleman sayisini Veriniz? ");
 scanf("%d",&dsay);
 for(k=0;k<dsay;k++){
  printf("%d. sayiyi giriniz",k);
  scanf("%d",&dizi[k]);
 }


 for(k=0;k<dsay-1;k++)
  for(l=k+1;l<dsay;l++)
   if (dizi[k]<dizi[l]){
    temp=dizi[k];
    dizi[k]=dizi[l];
    dizi[l]=temp;
   }
 for(k=0;k<dsay;k++)
  printf("%d",dizi[k]);
}
Dizi'de Eleman Arama


Bir grup eleman içerisinde bir takım şeyler aramak zorunda kalacağımız durumlar olacaktır. Bu durumlarda aşağıdakine benzer algoritmalar kullanabiliriz. Bu programda 100 elemanlı dizinin dolu olduğu varsayılmıştır.


#include <stdio.h>


int deger, k, dizi[100];


main(){
 printf("Aranacak Değer? ");
 scanf("%d", &deger);
 for (k=0;k<100;k++)
  if (dizi[k]=deger){
   printf("Öğe dizi içerisinde %d sıradadır. ", k);
   exit;
  }


 printf("Aranan Öğe Bulunamadı ");
}


8. Karakter Dizileri (Dizgeler)


Dizge (string) karakterlerden oluşan bir dizidir. Dizgeler en son karakterinden sonra 0 yada null değerini alarak karakter dizisinin nerede bittiğini anlarlar. Null karakteri karakter dizisine dahil değildir. Dizgeleri kullanmanın iki yöntem vardır. Birinci yöntem karakter dizisi, ikinci yöntem dizge işaretçisi (string pointer) şeklindedir. Bir dizge normal bir dizi gibi tanımlanır.


char ca[10];


Burada dizinin her elemanına bir değer atamak ve son karaktere 0 girmek gerekmektedir. Dizgeleri ekrana yazarken "%s" ifadesini kullanabilirsiniz.


char ca[10];
ca[0] = 'M';
ca[1] = 'e';
ca[2] = 'r';
ca[3] = 'h';
ca[4] = 'a';
ca[5] = 'b';
ca[6] = 'a';
ca[7] = 0;
printf("%s",ca);


Dizge işaretçileri karakter işaretçisi gibi tanımlanır.


char *sp;


Bir karakter işaretçisine bir değer atadığınız zaman o otomatik olarak karakter dizilerindeki gibi 0 değerini koyar.


char *sp;
sp = "Merhaba";
printf("%s",sp);


scanf komutunu kullanarak bir dizgeyi bir karakter dizisi olarak okutabilir, dizge işaretçisi olarak okutamayız. Eğer bir dizge işaretçisi olarak okutmak isterseniz onun karakter dizisine işaret etmesini sağlamalısınız.


char ca[10],*sp;
scanf("%s",ca);
sp = ca;
scanf("%s",sp);
Dizge (String) fonksiyonları


String.h kütüphane dosyası dizgilerle çalışan bazı yararlı fonsiyonlara sahiptir. Çok sık kullanacağınız bazı fonksiyonlar aşağıdaki gibidir.


strcpy(hedef, kaynak) :
C programlama dilinde dizge1 = dizge2 şeklinde bir ifade kullanamazsınız. Bir dizgeyi başka bir dizgeye atamak için strcpy komutunu kullanmanız gerekmektedir. strcpy komutu kaynak dizgeyi hedef dizgeye kopyalar.


s1 = "abc";
s2 = "xyz";
strcpy(s1,s2); // s1 = "xyz"


strcat(hedef, kaynak) :
Kaynak ile hedef dizgeleri birleştirir bunları hedef dizgenin içerisine koyar.


s1 = "abc";
s2 = "xyz";
strcat(s1,s2); // s1 = "abcxyz"


strcmp(birinci, ikinci) :
Birinci ve ikinci dizgeleri karşılaştırır. Eğer birinci dizge daha büyük ise 0 dan büyük bir sayı geri döner. Eğer birinci dizgi ikincisinden daha küçük ise 0 dan küçük bir sayı geri döner. Eğer her iki dizge birbirlerine eşit ise 0 değer geri döner.


s1 = "abc";
s2 = "abc";
i = strcmp(s1,s2); // i = 0


strlen(string) :
Dizgedeki karakter sayısını geri döndürür.


s = "abcde";
i = strlen(s); // i = 5


9. Fonksiyonlar


Fonksiyonlar alt programlardır. İlk yazdığımız programda bir fonksiyon olan main fonksiyonunu kullandık. Her zaman bir fonksiyonu çağrıldığı yerden önce tanımlamanız gerekmektedir. main fonksiyonu bizim yazacağımız fonksiyonları çağıracağı için programın en alt kısmına koyduk.


Bir fonksiyon tanımlanırken sırası ile tip, fonksiyon adı ve parantezler içersinde gerekirse parametreler yazılır. Fonskiyonlar geri değer döndürebilir. Bu değer karakter yada tamsayı tipinde olabilir. Eğer fonksiyonun geri değer döndürmesini istemiyorsanız tip olarak "void" ifadesini kullanırsınız.


#include<stdio.h>
 
void Merhaba()
{
   printf("Merhaba ");
}
 
int main()
{
   Merhaba();
   return 0;
}
Parametreler


Parametereler fonksiyonlara hesaplama yapmak için gönderilen değerlerdir. Örneğin yukarıdaki programda kullandığımız "Merhaba " ifadesi printf fonksiyonuna gönderilen bir parametredir.


Parametreleri fonksiyon adından sonraki parantezin içerisinde fonksiyona gönderilen değerleri almak için tanımlamak gerekmektedir. Aşağıda iki sayıyı toplayan ve sonucu geri döndüren fonksiyon bulunmaktadır.


#include<stdio.h>
 
int Topla(int a,int b)
{
   return a + b;
}
 
int main()
{
   int cevap;
   cevap = Topla(5,7);
   return 0;
}


İsterseniz değişkenin adresini fonksiyona gönderebilirsiniz böylece kopyalama yapılmamış olur. Bu iş için işaretçilere ihtiyaç duyarız.


#include<stdio.h>
 
int Topla(int *a,int *b)
{
   return *a + *b;
}
 
int main()
{
   int cevap;
   int sayi1 = 5;
   int sayi2 = 7;
   cevap = Topla(&sayi1,&sayi2);
   printf("%d ",cevap);
   return 0;
}
Global ve yerel değişkenler


Yerel değişkenler bir fonksiyon içerisinde tanımlanır ve sadece o fonksiyon içerisinde kullanılabilir. Eğer bütün fonksiyonlarda kullanılabilecek bir değişken tanımlamak istiyorsanız global değişken tanımlamanız gerekecektir.


#include<stdio.h>
 
// Global değişkenler
int a;
int b;
 
int Topla()
{
   return a + b;
}
 
int main()
{
   int cevap; // Yerel değişken
   a = 5;
   b = 7;
   cevap = Topla;
   printf("%d ",cevap);
   return 0;
}
Komut satırı parametreleri


Bazen komut satırından programa parametre geçmek gerekebilir. Örneğin;


$ benimprogram -A


Komut satırında girilen parametrelere erişebilmek için main fonksiyonundaki parantezler içerisinde değişken tanımları yapmak gerekmektedir. Birinci parametre programa gönderilen parametre sayısıdır. Programın adı da bir parametre olarak gider ve 0'ncı değerden ulaşılabilir.


#include<stdio.h>


int main(int argc,char *argv[])
{
   int i;
   printf("Toplam: %d ",argc);
   if (argc > 0)
   {
      printf("Parametreler: ");
      for (i = 0;i < argc;i++)
         printf("%s ",argv[i]);
   }
   return 0;
}


10. Yapılar


Aynı tipte gruplanmış birçok değişkeni dizilerde aynı isim altında tanımlamayı gördük. Yapılarda aynı diziler gibidir fakat aynı ad altında değişik veri tipindeki değişkenleri barındırabilirler. Örneğin karakter tipinde isim ve tamsayı tipinde bir yaş değişkenlerini kisi yapısı altında oluşturabilirsiniz. Bu kisi yapısı C programlama dilinde aşağıdaki gibidir.


struct kisi
{
   char *isim;
   int yas;
};


Yukarıda sadece tipin tanımlaması var. Şimdi bu tipte bir değişken tanımlamamız gerekiyor. Aşağıda p adlı değişkeni kisi tipinde nasıl tanımladığımızı görmekteyiz.


#include<stdio.h>
struct kisi
{
   char *isim;
   int yas;
};
 
int main()
{
   struct kisi p;
   return 0;
}


Bu yapıdaki dizge yada tamsayı değerine ulaşabilmek için yapı adından sonra nokta koyup değişken adını yazmamız yeterlidir.


#include<stdio.h>
 
struct kisi
{
   char *isim;
   int yas;
};
 
int main()
{
   struct kisi p;
   p.isim = "Halil Mutlu";
   p.yas = 29;
   printf("%s",p.isim);
   printf("%d",p.yas);
   return 0;
}
Tip tanımlamaları


Tip tanımı ile belirlediğimiz bir adı değişkene verebilirsiniz. Aşağıda intptr isminde tamsayı tipinde bir işaretçinin nasıl tanımlandığını görüyoruz.
#include<stdio.h>
 
typedef int *intptr;
 
int main()
{
   intptr ip;
   return 0;
}
Yapılar için tip tanımlamaları


Yapı değişkeni oluştururken struct kelimesini kullanmak istemiyorsanız yapı için tip tanımı oluşturabilirsiniz. Yapının tip tanımının adı genellikle büyük harflerle verilir.
#include<stdio.h>
 
typedef struct kisi
{
   char *isim;
   int yas;
} KISI;


int main()
{
   KISI p;
   p.isim = "Halil Mutlu";
   p.yas = 29;
   printf("%s",p.isim);
   printf("%d",p.yas);
   return 0;
}
İşaretçilede Yapılar


İşaretçilerde yapıları kullandığımız zaman nokta (.) yerine -> ifadesini kullanmamız gerekmektedir.


#include<stdio.h>
 
typedef struct kisi
{
   char *isim;
   int yas;
} KISI;
 
int main()
{
   KISI p;
   KISI *pptr;
   pptr = &p;
   pptr->isim = "Halil Mutlu ";
   pptr->yas = 29;
   printf("%s",pptr->isim);
   printf("%d",pptr->yas);
   return 0;
}
Union' lar


Union ifadeleri yapılar gibidir sadece hafızada daha az yer kaplarlar. Eğer 8 byte'lık bir double ve 4 byte' lık bir integer tipinde bir yapı oluşturursanız toplam boyut 8 byte olacaktır. Çünkü onlar birbirlerinin üstündedirler.Eğer double tipindeki değişkenin değerini değiştirirseniz integer tipindeki değişkeninde değeri değişir. Aynı şekilde integer tipindeki değişkenin değerini değiştirirseniz double tipindeki değişkeninde değeri değişir.


#include<stdio.h>
 
typedef union sayi
{
   double d;
   int i;
} SAYI;
 
int main()
{
   SAYI n;
   n.d = 3.14;
   n.i = 5;
   return 0;
}


11. Metin ve veri dosyaları


Dosyalar verilerinizi harddisk gibi yükleme birimlerinde sonra kullanmak amacı ile saklar. Metin ve veri dosyaları olmak üzere iki tipte dosyalar vardır.
Metin Dosyaları


Metin dosyaları karakter dizilerini dosyaya koymak için kullanılır. Metin dosyası oluşturmak için bir dosya işaretçisi tanımlamak gerekmektedir.


#include<stdio.h>
 
int main()
{
   FILE *f;
   return 0;
}


Sonra fopen fonksiyonunu kullanarak dosyayı açmalısınız. fopen fonksiyonu dosya adı ve açma modu olmak üzere 2 adet parametre alır. fopen fonksiyonu geri dosya işaretçisi döndürür.


#include<stdio.h>
 
int main()
{
   FILE *f;
   f = fopen("test.txt","w");
   return 0;
}


Yukarıdaki örnekte test.txt isminde bir dosya oluşturuluyor. "w" dosyanın yazma için açıldığını, dosya yoksa oluşturulacağını belirtir. Diğer dosya açma modları aşağıdaki gibidir.


r Okuma için aç
r+ Okuma ve yazma için aç
w Yazma için aç ve eğer dosya yok ise oluştur. Eğer dosya var ise boş bırak.
w+ Okuma ve yazma için aç ve eğer dosya yok ise oluştur. Eğer dosya var ise boş bırak.
a Dosyanın sonuna ekleme yapmak için aç, dosya yok ise oluştur
a+ Okuma ve dosyaya ekleme yapmak için aç, dosya yok ise oluştur.


Bir karakter dizisini dosyaya yazma için fprintf komutu kullanılır. fprintf komutu printf gibidir. Burada sadece dosya işaretçisini ilk parametre olarak tanımlamak gerekir.


#include<stdio.h>
 
int main()
{
   FILE *f;
   f = fopen("test.txt","w");
   fprintf(f,"Merhaba");
   return 0;
}


Dosyaya yazma işlemini bitirdiğiniz zaman dosyanızı kapatmalısınız. Eğer dosyanınız kapatmaz iseniz bazı veriler dosyaya yazılamayabilir. Dosyaları kapatmak için fclose komutu kullanılır.
#include<stdio.h>
 
int main()
{
   FILE *f;
   f = fopen("test.txt","w");
   fprintf(f,"Merhaba");
   fclose(f);
   return 0;
}


fgets komutu dosyadan bilgi okurken kullanılır. Dosyadan okunan karakterleri yüklemek için tampon (buffer) şeklinde öncelikle bir karakter dizisi tanımlamalısınız. fgets' in 3 parametresi tampon değişkeni, tamponun boyutu ve dosya işaretçisidir.
#include<stdio.h>
 
int main()
{
   FILE *f;
   char buf[100];
   f = fopen("test.txt","r");
   fgets(buf,sizeof(buf),f);
   fclose(f);
   printf("%s ",buf);
   return 0;
}
Veri Dosyaları


Bir veri dosyası tamsayı gibi verileri yüklemek için kullanılır. Veri dosyasını açtığınız zaman fopen' nın dosya açma moduna b parametresini eklemeniz gerekmektedir.


#include<stdio.h>
 
int main()
{
   FILE *f;
   f = fopen("test.dat","wb");
   fclose(f);
   return 0;
}
fwrite dosyaya veri yazmak için kullanılır. fwrite'ın birinci parametresi dosyaya yazmak istediğiniz değişkenin işaretçisidir. İkinci parametre değişkenin boyutu, üçüncüsü yazılacak değişkenin sayısı ve sonuncusuda yazılacak olan dosyanın işaretçisidir.


#include<stdio.h>
 
int main()
{
   FILE *f;
   int buf;
   f = fopen("test.dat","wb");
   buf = 100;
   fwrite(&buf,sizeof(buf),1,f);
   fclose(f);
   return 0;
}


fread dosyadan veri okumak için kullanılır, fwrite komutu gibidir burada veri değişkene yazmak yerine değişkene okutulur.


#include<stdio.h>
 
int main()
{
   FILE *f;
   int buf;
   f = fopen("test.dat","rb");
   fread(&buf,sizeof(buf),1,f);
   printf("%d ",buf);
   fclose(f);
   return 0;
}
Yapılarda veri dosyalarının kullanımı


Yapıları diğer veri tiplerinde olduğu gibi veri dosyalarına yazabilir yada okuyabilirsiniz
#include<stdio.h>
 
struct
{
   char name[100];
   int age;
} p;
 
int main()
{
   FILE *f;
   strcpy(p.name,"John");
   p.age = 25;
   f = fopen("test.dat","wb");
   fwrite(&p,1,sizeof(p),f);
   fclose(f);
   return 0;
}

 
   

 
Kocaeli Üniversitesi Bilgisayar Mühendisliği Mezunları Copyright © 2000-2010