C Programlamaya Giriş

C programlama dili, sistem programlamadan gömülü sistemlere kadar geniş bir yelpazede kullanılan güçlü ve düşük seviyeli bir dildir. Bu serinin ikinci bölümünde, C'nin temel yapı taşlarını anlamaya başlayacağız: bir C programının dosya yapısı nasıldır, hangi veri tipleri kullanılır ve kullanıcıdan nasıl veri alınır veya ekrana nasıl çıktı verilir gibi konuları sade ve anlaşılır örneklerle ele alacağız.

Bu yazının sonunda:

  • Basit bir C programının iskeletini okuyup yazabileceksiniz.

  • int, float, char gibi temel veri tiplerini öğreneceksiniz.

  • printf() ve scanf() gibi giriş-çıkış fonksiyonlarını kullanabileceksiniz.

Hazırsanız, başlayalım 🚀

Dosya Yapısı

  • Source Dosyaları (.c): Algoritma oluşturulan dosya ortamı. ör: main.c

  • Header Dosyaları (.h): Kullanılacak araçları içeren dosya ortamı. ör: stdio.h

// main.c file
/* HEADER */
#include <stdio.h>
/***************
SPACE-1
Function Prototypes/Initializations
Function Definitions
Global Variables
***************/
/* MAIN FUNCTION */
int main() {
    // Main Code is Here
return 0; // We will return this point at Functions Topic 
}
/* SPACE-2 */
  • Header:

    • Sonsuz sayıda header eklenebilir.

    • Temel olarak kullanılacak word’leri (printf, scanf vs.) içeren kütüphaneler ana koda bu bölümde eklenir.

    • Bir nevi sözlük/kullanım kılavuzudur.

  • Space-1:

    • Fonksiyon tanımaları, fonksiyon prototipleri, global değişkenler vb burada tanımlanır.
  • Main Function:

    • Algoritmanın yazılacağı ana ortam burasıdır.

    • Değişken tanımlamaları, aritmetik veya mantıksal tanımlamalar, fonksiyon çağırmaları vb burada gerçekleştirilir.

    • **Dikkat! “**return 0;” kısmı fonksiyon tanımından dolayı hep eklenmelidir. Detaylı açıklama “Fonksiyonlar” başlığı altında açıklanacaktır.

  • Space-2:

    • Fonksiyon tanımlamaları burada yapılabilir. Dikkat! Fonksiyon tanımlamasını burada yapabilmek için Space-1 alanında fonksiyon prototipi tanımlanmalıdır. Detaylı açıklama “Fonksiyonlar” başlığı altında açıklanacaktı.

  • Komut Sırası: C programlamada komutlar main fonksiyondan başlayarak yukarıdan aşağıya doğru çalıştırılır.

  • Noktalı Virgül: Satır sonunu ifade eder. Her satırın sonunda bu “;” ifadesi kullanılır.

  • Süslü Parantez: İlgili kod bloğunun başlangıç ve bitişini sınırlarını göstermektedir.

  • Yorum Satırları: Yazılımcı kodun içerisine derleyicinin işleme almayacağı şekilde (kendisine notlar bırakmak veya yazılan bir kodu açıklamak vb amaçlarla) yorumlar bırakabilir. Bu işlem tek satırlıksa satır başına “//”, birden fazla satırdan oluşuyorsa satır başına “/”, satır sonuna “/” ifadeleri ile derleyiciye derlenmeyeceğini ifade edebilir.

Değişkenler - Variables

  • Programın çalışması sırasında değer saklamak için ayrılmış yapılardır.

  • Verileri geçici olarak tutmak, üzerinde işlem yapmak ve gerektiğinde güncellemek için kullanılır.

KategoriTiplerAçıklama
Temel (Primitive)int, char, float, double, void, boolTam sayılar, karakterler, ondalık ifadeler, mantıksal ifadeler
Modifyershort, long, signed, unsignedBoyut ve işaret bilgisi değiştirir
Diğerenum, struct, union, typedefKullanıcı tanımlı veya yapılandırılmış tipler
  • Değişken Tanımlama:

      int     yas;            // tam sayı
      unsigned int  portNo;   // negatif değer almaz
      long    kilometre;      // daha geniş aralık
      char    harf;           // tek bir karakter
      float   sicaklik;       // ondalıklı sayı (yaklaşık)
      double  vadeOrani;      // daha kesin ondalıklı sayı
    
  • Bildirim (Declaration) ve Başlatma (Initialization):

    • Bildirim: Derleyiciye “bu isimde bir değişken var” demektir.

    • Başlatma: Değişkene ilk değer atamak.

    int sayi;             // bildirim (declaration)
    sayi = 10;            // atama (assignment)

    int toplam = 0;       // bildirim + başlatma
    const int MAX = 100;  // sabit değişken
  • Değişkenler lvalue ve rvalue olarak ikiye ayrılır. Temel olarak eşittir ifadesinin solundaki ifadeler lvalue iken sağındaki ifadeler rvalue’dür. Ör. degiskenl = degiskenr; → degiskenl: lvalue, degiskenr: rvalue

    Değişkene atanacak sayısal değerler asla lvalue olamaz, her zaman rvalue’dur. Yani “10 = sayi” ifadesi her zaman hata verecektir. Doğru tanımlama “sayi = 10” şeklinde olmalıdır.


  • char:

    • Bellekte 1 byte yer tutar.

    • ASCII tablosunda gördüğümüz her karakter bu veri tipi ile tutulur. Ör. ‘C’, ‘d’, ‘2’, ‘-’

  • int:

    • Bellekte tuttuğu yer bilgisayardan bilgisayara değişir.

    • Tam sayılar bu veri tipi ile tutulur. Ör. 1, 4, 32323, 0

  • float:

    • Bellekte 4 byte yer tutar.

    • Ondalıklı/Virgüllü sayılar bu veri tipi ile tutulur. Ör: 1.34343, 3223.43, 1.000

    • float veri tipi bellekte nasıl saklanır? Örneğin char veri tipi için her bir karakterin bir sayısal karşılığı vardır. Virgüllü sayılar için virgül ifadesi nasıl belirtilir.

      IEEE754 yöntemi ile ondalık sayılar yeni bir formata çevrilir ve böyle bellekte tutulur.

      image.png

  • double:

    • Bellekte 8 byte yer tutar.

    • Ondalıklı/Virgüllü sayılar bu veri tipi ile tutulur. Ör: 1.32323234343 , 44444.444444444

    • float veri tipine göre daha ondalık kısmını hassas tutar.

    • double veri tipi bellekte nasıl saklanır?

      IEEE754 double precision yöntemi ile ondalık sayılar yeni bir formata çevrilir ve böyle bellekte tutulur.

      image.png

  • boolean (bool):

    • Bellekte genellikle 1 byte yer tutar.

    • Mantıksal değerleri tutar; sadece iki olası değeri vardır: true veya false. Ör. true, false

    • <stdbool.h> içinde tanımlı bool ile kullanılır.

  • void:

    • Bellekte yer tutmaz (boyutu tanımsızdır).

    • Fonksiyonların değer döndürmediğini belirtmek için dönüş tipi olarak kullanılır. Ör. void fonksiyonAdı(void)

    • Ayrıca void * ile herhangi bir türdeki veriye işaret eden generic (türsüz) işaretçi tanımlamak için kullanılır.

Değişkenlerin Yaşam Süresi (Lifetime) ve Kapsam (Scope)

  • Global Kapsam: Fonksiyon dışı, tüm dosyada görünür. Detaylı bilgi “Fonksiyonlar” başlığında verilecektir.

  • Local (Blok) Kapsam: { … } arasında tanımlanan, yalnızca o blokta geçerlidir. Blok kapandığı anda değişken silinecektir. Detaylı gözlem “Fonksiyonlar” başlığında yapılacaktır.

  • Dosya (File) Kapsamı: static ile işaretlenen global, sadece tanımlı olduğu dosyada görünür. Detaylı bilgi “Fonksiyonlar” başlığında verilecektir.

  • Extern: Başka dosyalarda tanımlı global bir değişkeni kullanmak için.

      // file1.c
      int sayi = 10;             // global, tüm proje
      static int gizli = 20;     // sadece file1.c içinde
    
      // file2.c
      extern int sayi;           // başka dosyadan sayi’yi al
    

Temel Giriş-Çıkış Fonksiyonları, Yer Tutucular ve Operatörler

printf()

  • Ekrana metin yazdırmak için kullanılan temel çıkış fonksiyonudur.

  • Ekrana karakterler her zaman soldan sağa ve yukarıdan aşağıya şeklinde yazılır.

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

Yer Tutucular - Place Holders

Ekrana sadece text yazdırmak değil, bir değişkenin değeri de yazdırılmak istenebilir. Bu durumda “Yer Tutucular” kullanılır.

Yer TutucuAnlamıÖrnekÇıktı
%d / %iİşaretli tamsayı (decimal)%d, 4242
%fOndalıklı (float veya double)%.2f, 3.143.14
%cTek bir karakter%c, 'A'A
%pİşaretçi (pointer) adresi%p, ptr0x7ffeefbff5c8

Peki bu yer tutucular nasıl kullanılır?

#include <stdio.h>
int main() {

    int age = 24;
    float average_grade = 98.32;
    char grade1 = 'A', grade2 = 'A';
    printf("%d yasindaki ogrenci Ugur Altinisik %f ortalama ile %c%c harf notunu almistir.", age, average_grade, grade1, grade2);
    return 0;
}

Pratik: Adınız ve soyadınızın ilk harflerini, ilgili dersin kodunu (BIL141 dersi için kodu 141 olarak almanız yeterli) ve almayı hedeflediğiniz sayısal notu ekrana yazdırın.

#include <stdio.h>
int main() {

    char name = 'U', surname = 'A';
    int lecture_code = 141;
    float grade = 100;
    printf("%c%c isim,soyisimli ogrenci %d kodlu dersten %d notunu almayi hedeflemektedir.",name, surname, lecture_code, grade);
    return 0;
}

  • Ekrana metin yazdırmak için alt satıra geçmek, tab karakteri kullanmak vb işlemler için özel karakterler bulunmaktadır. Bunlara “kaçış dizileri - escape sequences” denir.

    | Kaçış Dizisi | Anlamı | Açıklama / Örnek | | --- | --- | --- | | \\n | Yeni satır (newline) | İmleci bir sonraki satır başına taşır | | \\t | Sekme (horizontal tab) | İmleci bir sonraki tab konumuna taşır | | \\\\ | Ters eğik çizgi (backslash) | Bir adet \\ karakteri yazdırır | | \\' | Tek tırnak (single quote) | Bir adet ' karakteri yazdırır | | \\" | Çift tırnak (double quote) | Bir adet " karakteri yazdırır | | \\a | Alarm (bell) | Sistem zil sesi / ekran uyarısı | | \\b | Geri silme (backspace) | İmleci bir karakter geri alır | | \\f | Form besleme (form feed) | Sayfa sonuna gitme | | \\r | Satır başı (carriage return) | İmleci satır başına taşır | | \\v | Dikey sekme (vertical tab) | İmleci bir sonraki dikey tab konumuna taşır | | \\0 | Null karakter | Karakter dizisinin sonunu işaretler |

    • Kaçış dizilerini amacı gibi değil, olduğu gibi yazdırmak isteme durumlarında (örneğin alt satıra geçmek yerine “\n” ifadesi ekrana bastırmak istiyorsak) kaçış dizisinden önce kaçış karakteri (\) kullanılır.

        #include <stdio.h>
        int main() {
      
            printf("Bu cumle 2 satır olarak yazilacaktiir\\nikinci satir da budur.");
            printf("son printfte alt satira gec komutu kullanilmadigi icin yeni satira gecilmemistir.");
            printf("\\n alt satira gecmek icin printf icinde \\\\n ifadesi kullanilmalidir");
            return 0;
        }
      

  • Pratik: Aşağıdaki çıktıyı veren kodu yazın.

#include <stdio.h>
int main() {

    int age = 24;
    char name = 'U', surname = 'A';
    int student_id = 181201033;
    printf("Name-Surname: %c%c\\n", name, surname);
    printf("Age: %d\\n", age);
    printf("Student ID: %d\\n", student_id);
    return 0;
}

Aritmetik Operatörler

  • Toplama: “+” sembolü ile ifade edilir. İki veri tipini birbirine ekleyerek sonucu verir.

      #include <stdio.h>
      int main() {
    
          int first = 7;
          int second = 3;
          int result = first + second;
          return 0;
      }
    
  • Çıkarma: “-” sembolü ile ifade edilir. İki veri tipini birbirinden çıkararak sonucu verir.

      #include <stdio.h>
      int main() {
    
          int first = 7;
          int second = 3;
          int result = first - second;
          return 0;
      }
    
  • Çarpma: “*” sembolü ile ifade edilir. İki veri tipini birbiri ile çarparak sonucu verir.

      #include <stdio.h>
      int main() {
    
          int first = 7;
          int second = 3;
          int result = first * second;
          return 0;
      }
    
  • Bölme: “/” sembolü ile ifade edilir. İki veri tipini birbirine bölerek sonucu verir.

      #include <stdio.h>
      int main() {
    
          int first = 7;
          int second = 3;
          int result = first / second;
          return 0;
      }
    
  • Mod Alma: “%” sembolü ile ifade edilir. İki veri tipinin birbirine bölümünden kalanı verir.

      #include <stdio.h>
      int main() {
    
          int first = 7;
          int second = 3;
          int result = first % second;
          return 0;
      }
    

  • Aritmetik Operatörlerle işlem yaparken bazı kısa yollar mevcuttur.

    • Artırma / Azaltma Operatörleri

      • Ön ek (prefix): ++x veya -x

        • Değişkenin değerini önce 1 artırır/azaltır, sonra ifadede o yeni değeri kullanır.
      • Son ek (postfix): x++ veya x--

        • İfadede önce mevcut değeri kullanır, sonrasında değişkenin değerini 1 artırır/azaltır.
        #include <stdio.h>

        int main(void) {
            int x, y;

            y = 5;
            x = y++;    // postfix: önce x=5; sonra y→6
            printf("x = %d, y = %d\\n", x, y);  // x=5, y=6

            y = 5;
            x = ++y;    // prefix: önce y→6; sonra x=6
            printf("x = %d, y = %d\\n", x, y);  // x=6, y=6

            y = 5;
            x = y--;    // postfix decrement
            printf("x = %d, y = %d\\n", x, y);  // x=5, y=4

            y = 5;
            x = --y;    // prefix decrement
            printf("x = %d, y = %d\\n", x, y);  // x=4, y=4

            return 0;
        }

Birleşik Atama (Compound Assignment) Operatörleri

#include <stdio.h>

int main(void) {
    int x = 10, y = 4;

    x += 3;     // x = x + 3 → x = 13
    printf("x += 3 ➔ %d\\n", x);

    x *= y;     // x = x * y → x = 13 * 4 = 52
    printf("x *= y ➔ %d\\n", x);

    x -= 2;     // x = x - 2 → x = 50
    printf("x -= 2 ➔ %d\\n", x);

    x /= 5;     // x = x / 5 → x = 10
    printf("x /= 5 ➔ %d\\n", x);

    // Ayrıca başka kombinasyonlar:
    x = 7;
    y = 3;
    x %= y;     // x = x % y → x = 7 % 3 = 1
    printf("x mod y (x %%= y) ➔ %d\\n", x);

    return 0;
}

Pratik: Aşağıdaki C kodunun çıktısı ne olacaktır?

#include <stdio.h>

int main(void) {
    int x = 5;

    x = x + 5;
    printf("1- x: %d\\n", x);

    x += 5;
    printf("2- x: %d\\n", x);

    x -= 3;
    printf("3- x: %d\\n", x);

    x--;
    printf("4- x: %d\\n", x);

    printf("5- x: %d\\n", x + 1);
    printf("6- x: %d\\n", x++);
    printf("7- x: %d\\n", ++x);

    return 0;
}

1 x: 10

2- x: 15

3- x: 12

4- x: 11

5- x: 12

6- x: 11

7- x: 13

Pratik: Aşağıdaki çıktıları veren kodları yazın

  • 233 + 322 = 555

      #include <stdio.h>
      int main() {
    
          int first = 233;
          int second = 322;
          int result = first + second;
          printf("%d + %d = %d", first, second, result);
          return 0;
      }
    
  • 222.320007 + 322 = 544.320007

      #include <stdio.h>
      int main() {
    
          float first = 222.320007;
          int second = 322;
          float result = first + second;
          printf("%f + %d = %f", first, second, result);
          return 0;
      }
    
  • 22 x 3 = 66

      #include <stdio.h>
      int main() {
    
          int first = 22;
          int second = 3;
          int result = first * second;
          printf("%d x %d = %d", first, second, result);
          return 0;
      }
    
  • 707 / 7 = 101

      #include <stdio.h>
      int main() {
    
          int first = 707;
          int second = 7;
          int result = first / second;
          printf("%d / %d = %d", first, second, result);
          return 0;
      }
    
  • 332 / 6 = 55.333332

      #include <stdio.h>
      int main() {
    
          int first = 332;
          int second = 6;
          float result = (float) first / second;
          printf("%d / %d = %f", first, second, result);
          return 0;
      }
    

Tip Dönüşüm - Type Casting

Tip dönüştürme ya da “type casting”, bir değerin bellekteki temsilini başka bir veri tipine uyacak şekilde değiştirme işlemidir. Tam sayı ifadeyi ondalıklı ifadeye dönüştürmek, char ifadeyi tam sayı ifadeye dönüştürmek (ASCII tablosu karşılığı) tip dönüşümüdür.

int    i = 10;
double d;

// i’yi double’a dönüştürüp atama
d = (double) i;       

// double’ı int’e dönüşüm (kırpma truncate edilecek)
i = (int) 3.99;      // i == 3

// karma işlemler
int     a = 5, b = 2;
double  div1 = a / b;               // 2.0  (çünkü a/b integer, sonra float’a dönüştürülür)
double  div2 = (double)a / b;       // 2.5  (a önce 5.0, sonra bölüm float)
double  div3 = a / (double)b;       // 2.5
double  div4 = (double)a / (double)b; // 2.5
  • Pratik: Aşağıdakiçıktıları veren kodları yazın

  • 221.000000 / 3.000000 = 73.000000

      #include <stdio.h>
      int main() {
    
          float first = 221.000000;
          float second = 3.000000;
          float result = (int) (first / second);
          printf("%f / %f = %f", first, second, result);
          return 0;
      }
    
  • 52 / 8 = 6.50

      #include <stdio.h>
      int main() {
    
          int first = 52;
          int second = 8;
          float result = (float) first / second;
          printf("%d / %d = %.2f", first, second, result);
          return 0;
      }
    

Genişlik ve Hassaslık Parametreleri

  • Pratik: Aşağıdaki çıktıları veren kodları yazın

  • 52 % 8 = 4

      #include <stdio.h>
      int main() {
    
          int first = 52;
          int second = 8;
          int result = first % second;
          printf("%d %% %d = %d", first, second, result);
          return 0;
      }
    
  • A sembolunden 4 sonraki sembol E'dir ve bu sembolun ASCII degeri 69'dir

      #include <stdio.h>
      int main() {
    
          char letter = 65;
          int count = 4;
          char result = letter + count;
          printf("%c sembolunden %d sonraki sembol %c'dir ve bu sembolun ASCII degeri %d'dir", letter, count, result);
          return 0;
      }
    

Karşılaştırma Operatörleri ve Mantıksal Operatörler

  • İki veri tipi karşılaştırmak için karşılaştırma operatörleri kullanılır. Herhangi bir karşılaştırmanın sonucu True / False olarak sadece iki sonuç vermektedir. Dolayısı ile karşılaştırma operatörlerinin sonucu her zaman bool tipinde bir veridir.

  • İki koşulu mantıksal ifadeler ile birbirine bağlayarak yeni bir koşul ifadesi üretebiliriz. Koşul ifadeleri her zaman True / False olarak sadece iki sonuç barındırmaktadır. Dolayısı ile koşul ifadeleri her zaman bool tipinde bir veridir. İki koşul ifadesinin mantıksal ifadeler ile birbirine bağlanmasının sonucu da her zaman True / False olarak sadece iki sonuç vermektedir. Dolayısı ile mantıksal operatörlerin sonucu her zaman bool tipinde bir veridir.

A KoşuluB KoşuluA && B
false- 0false- 0false- 0
false- 0true- 1false- 0
true- 1false- 0false- 0
true- 1true- 1true- 1

| A Koşulu | B Koşulu | A || B | | --- | --- | --- | | false- 0 | false- 0 | false- 0 | | false- 0 | true- 1 | true- 1 | | true- 1 | false- 0 | true- 1 | | true- 1 | true- 1 | true- 1 |

A Koşulu!A
false- 0true- 1
true- 1false- 0
  • Karşılaştırma Operatörleri ve Mantıksal Operatörler “Karar Verme Yapıları” konusunda pratik olarak anlam kazanacaktır.

scanf()

  • Kullanıcıdan veri almak için kullanılan temel giriş fonksiyonudur.

  • Şu ana kadar öğrendiğimiz veri tiplerine ek olarak string adlı bir veri tipi daha bulunmaktadır. char karakterleri tutarken string birden çok karakteri, başka bir deyişle kelimeleri/cümleleri tutar. String konusunu “Diziler” bölümünde detaylıca inceleyeceğiz.

#include <stdio.h>
int main() {

    char name[50];
    printf("İsim: ");
    scanf("%s", name);
    int age;
    printf("Yas: ");
    scanf("%d", &age);
        printf("Merhaba %s, yasiniz %d", name, age);
    return 0;
}

Dikkat! Derleyici arka planda sadece değişken isimleriyle değil aynı zamanda değişkenlerin kaydedildiği adreslerle de çalışır. Bu adreslere erişim & sembolü ile sağlanır. scanf fonksiyonu da alınan veriyi direkt adrese kaydeden bir fonksiyon tipidir. Bu sebepten scanf kullanımında değişken adından önce mutlaka & sembolü kullanılmalıdır. string bir veri tipi için ise bu durum istisnadır. string bir veri tipi scanf içerisinde direkt değişken ismi verilir & sembolü kullanılmaz. Bu adreslemeler ve string için & ifadesinin kullanılmaması konuları “İşaretçiler” ve “Diziler” bölümlerinde detaylıca incelenecektir.

  • scanf fonksiyonu veriyi özel bir bellek alanından okur. İşlem sırası scanf fonksiyonuna geldiğinde, eğer bu bellek alanında veri yoksa programı durdurur. Kullanıcının veri girmesini ve <enter>’a basmasını bekler. Bellek alanını soldan başlayarak (kullanıcının girdiği ilk veriden başlayarak) işlemeye başlar. scanf yer tutucuların tipine ve aşağıdaki kurallara göre veriyi işler: Girilen her veriyi yer tutucudaki tipe uygun mu diye kontrol ederek okur. Eğer uygun olmayan bir veri ile karşılaşırsa okumayı durdurur ve fonksiyondan çıkar (return).

  • int veri tipinin kuralları:

    • Girilen veride bir dizi rakam veya +/- işaretlerini takip eden bir dizi rakam arar.

    • Rakam bulmaya devam ettiği sürece okumaya devam eder; rakam dışında bir karakter (ör: boşluk, enter, tab) bulduğu an, o karakteri geri bırakır ve elindeki veriyi ilgili değişkene atar.

    • Varsa sıradaki yer tutucuya geçer.

  • float veri tipinin kuralları:

    • Girilen verinin başında +/- işaretleri olan/olmayan; içinde/başında nokta işareti olan/olmayan bir dizi rakam arar.

    • Rakam bulmaya devam ettiği sürece okumaya devam eder; rakam dışında bir karakter bulduğu an, o karakteri geri bırakır ve elindeki veriyi ilgili değişkene atar.

    • Varsa sıradaki yer tutucuya geçer.

  • char veri tipinin kuralları yoktur; sıradaki karakteri okur ve değişkene atar

  • scanf sayıları okumaya başlarken, sayıların başında olan «space», «tab», «new line» gibi karakterleri (whitespace characters) ihmal eder.

  • Pratik: Aşağıdaki kod parçalarının çıktılarını yazın.

// Klavye Girişi: 1-20.3-4
#include <stdio.h>

int main(void) {
    int   i, j;
    float x, y;

    // Kullanıcıdan dört değer okumaya çalışıyoruz
    scanf("%d%d%f%f", &i, &j, &x, &y);
    printf("i = %d\\n", i);
    printf("j = %d\\n", j);
    printf("x = %.2f\\n", x);
    printf("y = %.2f\\n", y);

    return 0;
}
  • Klavye Girişi: 1-20.3-4↵

    • “1” değerinden hemen sonra bir sembol yani “-” girişi gelmiş → i=1 olarak kaydedilir.

    • “-” sembolünden hemen sonra bir rakam yani “2” girişi gelmiş → okumaya devam edilir.

    • “-2” sayısından hemen sonra bir rakam yani “0” girişi gelmiş → okumaya devam edilir.

    • “-20” sayısından hemen sonra bir sembol yani “.” girişi gelmiş → j, int tipinde bir veri olduğu için j=-20 olarak kaydedilir.

    • “.” sembolünden hemen sonra bir rakam yani “3” girişi gelmiş → okumaya devam edilir.

    • “.3” sembollerinden hemen sonra bir sembol yani “-” girişi gelmiş → x, float tipinde bir veri olduğu için x=0.3 olarak kaydedilir.

    • “-” sembolünden hemen sonra bir rakam yani “4” girişi gelmiş → okumaya devam edilir.

    • “-4” sayısından hemen sonra ↵ girişi gelmiş → y=-4 olarak kaydedilir.

#include <stdio.h>

int main(void) {
    int   a;
    char  c;
    float f;

    // Kullanıcıdan bir tam sayı, bir karakter ve bir ondalıklı sayı okumaya çalışıyoruz
    scanf("%d%c%f", &a, &c, &f);

    printf("a = %d\\n", a);
    printf("c = '%c'\\n", c);
    printf("f = %.2f\\n", f);

    return 0;
}
  • Klavye Girişi: 256X-3.14↵

    • “2” değerinden hemen sonra bir rakam yani “5” girişi gelmiş → okumaya devam edilir.

    • “25” sayısından hemen sonra bir rakam yani “6” girişi gelmiş → okumaya devam edilir.

    • “256” sayısından hemen sonra bir sembol yani “X” girişi gelmiş → a, int tipinde bir veri olduğu için a = 256 olarak kaydedilir.

    • “X” sembolü, %c yer tutucusu ile okunur → c = 'X' olarak kaydedilir.

    • “X” karakterinden hemen sonra bir işaret yani “-” girişi gelmiş → okumaya devam edilir.

    • “-” sembolünden hemen sonra bir rakam yani “3” girişi gelmiş → okumaya devam edilir.

    • “-3” sayısından hemen sonra bir sembol yani “.” girişi gelmiş → ondalık kısm için nokta olarak kabul edilir.

    • “-3.” sembollerinden hemen sonra bir rakam yani “1” girişi gelmiş → okumaya devam edilir.

    • “-3.1” sayısından hemen sonra bir rakam yani “4” girişi gelmiş → okumaya devam edilir.

    • “-3.14” sayısından hemen sonra ↵ girişi gelmiş → f, float tipinde bir veri olduğu için f = -3.14 olarak kaydedilir.

#include <stdio.h>

int main(void) {
    int   i, j;
    float x, y;

    // Aşağıdaki girdi satır satır aşağıdaki gibi:
    // 1
    // -20    .3
    //     -4.0
    scanf("%d%d%f%f", &i, &j, &x, &y);

    printf("i = %d\\n",   i);
    printf("j = %d\\n",   j);
    printf("x = %.1f\\n", x);
    printf("y = %.1f\\n", y);

    return 0;
}
  • 1↵-20 .3↵ 4.0↵

    • “1” değerinden hemen sonra “↵” girişi gelmiş → i, int tipinde bir veri olduğu için i = 1 olarak kaydedilir.

    • ↵ girişinden hemen sonra bir işaret yani “-” girişi gelmiş → okumaya devam edilir.

    • “-” sembolünden hemen sonra bir rakam yani “2” girişi gelmiş → okumaya devam edilir.

    • “-2” sayısından hemen sonra bir rakam yani “0” girişi gelmiş → okumaya devam edilir.

    • “-20” sayısından hemen sonra bir boşluk veya tab karakteri gelmiş → j, int tipinde bir veri olduğu için j = -20 olarak kaydedilir.

    • Boşluk ve tab karakterleri yok sayılır, sonra bir sembol yani “.” girişi gelmiş → okunmaya devam edilir.

    • “.” sembolünden hemen sonra bir rakam yani “3” girişi gelmiş → okunmaya devam edilir.

    • “.3” sayısından hemen sonra ↵ girişi gelmiş → x, float tipinde bir veri olduğu için x = 0.3 olarak kaydedilir.

    • ↵ girişinden hemen sonra bir işaret yani “-” girişi gelmiş → okunmaya devam edilir.

    • “-” sembolünden hemen sonra bir rakam yani “4” girişi gelmiş → okunmaya devam edilir.

    • “-4” sayısından hemen sonra bir sembol yani “.” girişi gelmiş → ondalık kısmı belirtir, okunmaya devam edilir.

    • “-4.” sembollerinden hemen sonra bir rakam yani “0” girişi gelmiş → okunmaya devam edilir.

    • “-4.0” sayısından hemen sonra “↵” girişi gelmiş → y, float tipinde bir veri olduğu için y = -4.0 olarak kaydedilir.

getch()

  • Kullanıcıdan veri almak için kullanılan temel giriş fonksiyonudur.

  • scanf() fonksiyonunda kullanıcının yaptığı giriş ekranda gözükürken getch() fonksiyonunda gözükmez. Bu sayede kullanıcıdan veriler (şifre vb.) gizlilikle alınabilir. Ekrana yazılan ger karakter char tipinde bir değişkende tutulur. (getch: get char)

Sabitler - Makrolar

Program boyunca değişme ihtimali olmayan ve birçok yerde kullanılabilecek bir takım değerler olması muhtemeldir. Örneğin pi sayısı bunlardan birisidir. Her yerde aynı değeri kullanabilmek ve bunu kalıcı bir değere sabitlemek adına bu değer bir isim ile sabitlenebilir. Bu durumu gerçekleştirebilmek için #define makro ifadesi kullanılır.

#include <stdio.h>
#define PI 3.14
int main() {

    int yaricap = 5;
    float alan = PI * yaricap * yaricap; // Derleyici PI ifadesi gördüğü yerde 3.14 değerini yazar.
    printf("Dairenin alani: %f", alan);
    return 0; 
}

Yukarıdaki örnekte 3.14 sayısı PIadı ile özdeşleştirilmiştir. Bu kapsamda kod içerisinde pi sayısının kullanılacağı herhangi bir yerde PI ifadesi kullanılabilir. Görmüş olduğumuz veri tiplerinden değiştirilemez sabit bir değer olmasıdır. Ek olarak değişken tanımı bellekte yer kaplarken #define tanımlaması bellekte yer kaplamaz, süreç derleyici tarafından yürütülür. Dolayısıyla #define tanımlamaları bellekte yer işgal etmez, masrafsızdır.

Sorular

  • Kullanıcıdan alınan iki adet int tipi değişkenin değerlerini birbiriyle değiştiren kod parçasını yazınız.

      #include <stdio.h>
    
      int main(void) {
          int a, b, temp;
    
          /* Kullanıcıdan iki tamsayı oku */
          printf("İki tam sayı girin (örn. 5 10): ");
          scanf("%d %d", &a, &b)
    
          /* Takas etmeden önce */
          printf("Önce: a = %d, b = %d\\n", a, b);
    
          /* Değerleri geçici değişkenle takas et */
          temp = a;
          a    = b;
          b    = temp;
    
          /* Takas işleminden sonra */
          printf("Sonra: a = %d, b = %d\\n", a, b);
    
          return 0;
      }
    
  • Aşağıdaki kodun çıktısı ne olur?

      #include <stdio.h>
    
      int main(void) {
          int   x = 6;
          float y = 7.5;
          int   z = 3;
    
          x = y / 3;      
          y = x / 4.0;    
          z = x * y;      
    
          printf("%d %.2f\\n%d", x, y, z);
          return 0;
      }
    

2 0.50 1

  • Klavyeden girilen 4 basamaklı bir sayıyı okuyan ve tüm basamaklardaki rakamların toplamını bulan kodu yazınız.

      #include <stdio.h>
    
      int main(void) {
          int n;
          int d1, d2, d3, d4;
          int toplam;
    
          /* Klavyeden 4 basamaklı sayıyı oku */
          printf("4 basamaklı sayıyı girin: ");
          scanf("%4d", &n);
    
          /* Basamakları ayıkla */
          d1 = n / 1000;         // binler basamağı
          d2 = (n / 100) % 10;   // yüzler basamağı
          d3 = (n / 10) % 10;    // onlar basamağı
          d4 = n % 10;           // birler basamağı
    
          /* Basamakların toplamını hesapla */
          toplam = d1 + d2 + d3 + d4;
    
          /* Sonucu yazdır */
          printf("Girdi: %d\\n", n);
          printf("Basamaklar toplamı: %d\\n", toplam);
    
          return 0;
      }
    
  • Kullanıcıdan saniye bilgisini alan ve bunu saat, dakika ve saniye cinsinden yazan kodu yazınız.

      #include <stdio.h>
    
      int main(void) {
          int totalSeconds;
          int hours, minutes, seconds;
          int remainder;
    
          /* Kullanıcıdan saniye cinsinden toplam süreyi al */
          printf("Saniye cinsinden bir değer girin: ");
          scanf("%d", &totalSeconds);
    
          /* Saat, dakika ve saniyeye dönüştür */
          hours     = totalSeconds / 3600;
          remainder = totalSeconds % 3600;
          minutes   = remainder / 60;
          seconds   = remainder % 60;
    
          /* Sonucu yazdır */
          printf("%d saat, %d dakika, %d saniye\\n",
                 hours, minutes, seconds);
    
          return 0;
      }
    
  • Kullanıcıdan aa/gg/yyyy şeklinde tarih bilgisi alan ve bunu yyyyaagg şekline çeviren programı yazınız

      #include <stdio.h>
    
      int main(void) {
          int month, day, year;
    
          /* Kullanıcıdan aa/gg/yyyy formatında bir tarih oku */
          printf("Tarih girin (aa/gg/yyyy): ");
          scanf("%d/%d/%d", &month, &day, &year);
    
          /* yyyy aagg formatında yazdır */
          printf("%d%d%d\\n", year, month, day);
    
          return 0;
      }
    
  • Bir sinema salonu işletmecisi, yetişkin biletini 20 TL’ye, çocuk biletini 12 TL’ye satmaktadır. Kullanıcıdan satılan yetişkin ve çocuk bileti sayısını alıp toplam geliri hesaplayan programı yazınız.

      #include <stdio.h>
    
      int main(void) {
          int adultCount, childCount;
          int adultPrice = 20;   // TL
          int childPrice = 12;   // TL
          int totalRevenue;
    
          /* Kullanıcıdan yetişkin ve çocuk bileti sayısını oku */
          printf("Kaç yetişkin bileti satıldı? ");
          scanf("%d", &adultCount);
          printf("Kaç çocuk bileti satıldı? ");
          scanf("%d", &childCount);
    
          /* Toplam geliri hesapla */
          totalRevenue = adultCount * adultPrice + childCount * childPrice;
    
          /* Sonucu yazdır */
          printf("Toplam gelir: %d TL\\n", totalRevenue);
          return 0;
      }
    
  • Bir sürücü 350 km yol katetmiş ve 28.5 L benzin harcamıştır. 100 km başına düşen yakıt tüketimini (L/100 km) hesaplayan programı yazınız.

      #include <stdio.h>
    
      int main(void) {
          float distanceKm, fuelL;
          float consumption;
    
          /* Kullanıcıdan toplam mesafe ve harcanan yakıtı al */
          printf("Toplam mesafe (km): ");
          scanf("%f", &distanceKm);
          printf("Harcanan yakıt (L): ");
          scanf("%f", &fuelL);
    
          /* 100 km başına tüketim = (harcanan yakıt / kat edilen mesafe) * 100 */
          consumption = (fuelL / distanceKm) * 100.0f;
    
          /* Sonucu yazdır */
          printf("Yakıt tüketimi: %.2f L/100km\\n", consumption);
          return 0;
      }
    
  • Bir mağazada toplam alışveriş tutarı üzerinden %10 indirim yapılmaktadır. Kullanıcıdan orijinal tutarı alıp, indirimli fiyatı hesaplayın.

      #include <stdio.h>
    
      int main(void) {
          float originalPrice;
          float discountedPrice;
          const float discountRate = 0.10f;  // %10
    
          /* Kullanıcıdan orijinal fiyatı al */
          printf("Alışveriş tutarı (TL): ");
          scanf("%f", &originalPrice);
    
          /* İndirimli fiyat = orijinal × (1 − oran) */
          discountedPrice = originalPrice * (1.0f - discountRate);
    
          /* Sonucu yazdır */
          printf("İndirimli fiyat: %.2f TL\\n", discountedPrice);
          return 0;
      }
    
  • Bir fabrikada üretilen silindir şeklindeki kapların hacmi ve yüzey alanı sıkça hesaplanmaktadır. Aşağıdaki bilgileri kullanarak bir C programı yazınız:

    • Kapların yarıçapı ve yüksekliği kullanıcı tarafından girilecektir.

    • PI sabitini 3.14159 olarak tanımlayınız.

    • Silindirin:

      • Hacmi = PI * r * r * h

      • Yüzey Alanı = 2 * PI * r * (r + h)

formüllerini kullanarak hesaplayınız.

    #include <stdio.h>

    #define PI         3.14159f
    #define ONE_THIRD  (1.0f/3.0f)

    int main(void) {
        float r, h;
        float volume, surfaceArea;

        /* Kullanıcıdan yarıçap ve yükseklik okuma */
        printf("Yariçap (cm): ");
        if (scanf("%f", &r) != 1) {
            printf("Geçersiz giriş!\\n");
            return 1;
        }
        printf("Yukseklik (cm): ");
        if (scanf("%f", &h) != 1) {
            printf("Geçersiz giriş!\\n");
            return 1;
        }

        /* Hesaplamalar */
        volume      = PI * r * r * h;
        surfaceArea = 2 * PI * r * (r + h);

        /* Sonuçları yazdırma */
        printf("\\nSilindir Hacmi: %.2f cm^3\\n", volume);
        printf("Silindir Yüzey Alanı: %.2f cm^2\\n", surfaceArea);

        return 0;
    }
0
Subscribe to my newsletter

Read articles from Uğur Altınışık directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Uğur Altınışık
Uğur Altınışık

[tr] TOBB Ekonomi ve Teknoloji Üniversitesi Elektrik-Elektronik Mühendisliği mezunuyum. Embedded software (gömülü yazılım) geliştirme alanında çalışıyor; C ve C++ programlama dillerinde sistem seviyesinde uygulamalar geliştiriyorum. Gerçek zamanlı işletim sistemleri (RTOS), mikrodenetleyiciler ve donanım-yakın yazılım mimarisi konularında deneyim sahibiyim. Performans ve bellek optimizasyonu odaklı çözümler üretmeyi, düşük seviye sistemlerle çalışmayı ve teknik bilgimi paylaşmayı seviyorum. [en] I’m an embedded software developer with a strong foundation in C and C++, graduated from TOBB University of Economics and Technology. My work focuses on real-time systems, microcontroller programming, and hardware-oriented software development. I enjoy building efficient, low-level applications and sharing practical insights from the embedded world.