---
title: "C'nin Konumu"
source: 'https://academia.sh/tr/kurslar/c-temelleri/cnin-konumu'
course: 'C Temelleri'
language: tr
updated: '2026-09-13T05:07:33+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Dört derleme aşamasını (ön işlemci, derleyici, bağlayıcı, koşum) tanımlar ve ayırt eder'
    - 'Üç dosyalık ölçüm çekirdeğini koşturarak on dört gözlemin aşamalara dağılımını doğrular'
    - 'Aynı türden bir kararın kaynakta hangi aşamada verildiğini örnekler üzerinden gösterir'
---

# C'nin Konumu

C'de bir kaynağın çalışan bir programa dönüşmesi tek adım değildir: dört aşamadan geçer ve her aşama ayrı bir soruya bakar. Üç dosyalık bir ölçüm çekirdeği bu dört aşamayı tek koşumda gösterir ve on dört gözlemin 4'ünü ön işlemciye, 4'ünü derleyiciye, 3'ünü bağlayıcıya, 3'ünü koşuma yazar.

Rust müfredatı beş kursla kapandı ve son kursu tek bir soru sordu: derleyicinin verdiği
güvence nerede bitiyor (M10/K05). C'de bu sorudan önce gelen bir soru var. Bir kaynak dosya
çalışan bir programa dönüşene kadar kaç kez el değiştiriyor? Yanıt tek bir adım değil,
dörttür — ve bu kurs boyunca sorulacak tek soru, bir kararın hangi elde verildiğidir.

Rust'ta bu tür bir soru tek bir yerde sorulmuştu: kaynakta yazılan bir satır bir değer mi
üretiyor (M10/K01). C'de aynı tür soru dört kez sorulur, çünkü kaynak programa dönüşene kadar
dört ayrı eli geçiyor ve her el kendi kararını kendi bildiği şeye bakarak veriyor. Bu ders o
dört eli adlandırıyor ve aralarındaki farkı tek bir programı derleyip çalıştırarak gösteriyor.

## Dört Aşama

Bir C kaynağı programa dönüşürken sırayla dört elden geçer. Kurs boyunca bu dört ad değişmez:

| Sınıf | Tanım |
|---|---|
| ön işlemci (preprocessor) | Derleyici kaynağı görmeden önce, metin düzeyinde karara bağlanır |
| derleyici (compiler) | Tek bir birim çevrilirken, tiplerden ve sabitlerden karara bağlanır |
| bağlayıcı (linker) | Birimler bir araya gelirken, hangi tanımın kullanılacağı belli olur |
| koşum (runtime) | Ancak program çalışırken, veriye bakılarak belli olur |

Bu dört adın ortak noktası, hepsinin aynı soruya farklı bir yanıt vermesidir: "bu kararı
vermek için hangi bilgiye ihtiyaç var?" Ön işlemci yalnız metne bakar, tip diye bir şey
bilmez. Derleyici tek bir çeviri birimini (translation unit) görür, ama o birimin dışındaki
hiçbir şeyi bilmez. Bağlayıcı birden çok birimi bir araya getirir, ama hiçbirinin içeriğini
yorumlamaz — yalnız adları eşler. Koşum ise yalnız veriye bakar; kaynağın kendisi artık
elinde bile değildir.

Bu ölçü, M08/K05'teki "bir tipin hangi sınıf yolunda bulunması gerektiği" sorusuyla ve
M09/K05'teki "bir bilginin kaynağının ne olduğu" (kaynak, araç, koşum) sorusuyla karışmaz.
Orada ölçülen bir bağımlılığın nerede arandığı ya da bir bilginin kimden geldiğiydi; burada
ölçülen bir kararın hangi aşamada verildiği ve aşama sayısının dört olduğudur.

## Aşamalar Neden Görünür

Bu dört aşamanın görünür olması dilin donanıma yakınlığının bir sonucudur. C, kaynaktan
çalışan bir ikiliye giden yolun hiçbir adımını programcıdan gizlemez: ön işlemcinin ürettiği
metin okunabilir bir ara çıktıdır, derleyicinin ürettiği nesne dosyası incelenebilir,
bağlayıcının hangi tanımı seçtiği izlenebilir. Bu görünürlük bir eksiklik değil, dilin kendi
tasarım kararıdır — ve kursun geri kalanında tekrar tekrar karşımıza çıkacaktır.

C standardı (C17) kaynaktan ikiliye giden yolu sekiz çeviri aşamasına (translation phase)
ayırır. Bu kurs o sekiz aşamayı üç sınıfta toplar — ön işlemci, derleyici, bağlayıcı — ve
üstüne dördüncü sınıf olarak **koşumu** ekler; koşum standardın çeviri aşamalarına dahil
değildir, ayrı bir maddede yürütme ortamı olarak tanımlanır. Programcının kendi verdiği
kararlar bu dört noktada toplanır. Standardın sekiz aşaması arasındaki ayrımlar — örneğin
metin kodlamasının çözülmesiyle satır sonlarının birleştirilmesi ayrı aşamalardır — bu kursun
ölçtüğü kararları
etkilemez; onlar için tek isim yeter: ön işlemci.

## Ölçüm Çekirdeği

Kursun geri kalanında kullanılacak çekirdek üç dosyadır. Bağlayıcı sınıfını ölçmek birden
fazla birim gerektirdiği için çekirdek baştan çok birimlidir: bir başlık dosyası, iki kaynak
dosyası. İlk dosya yalnız bildirim taşır — hiçbir tanım içermez.

```c
// asama.h — baska birimlerde tanimli adlarin bildirimi
#ifndef ASAMA_H
#define ASAMA_H

/* Bu iki islev baska bir birimde tanimli: cagrilari baglama asamasinda cozulur. */
int kimlik(void);
const char *birim_adi(void);

/* Bu degisken de baska bir birimde tanimli. */
extern int birim_sayaci;

#endif
```

İkinci dosya bu bildirimlerin karşılığını taşıyor. `secim.c` kendi başına derlenebilir bir
birimdir ve `asama.c`'nin hiçbir satırını bilmez.

```c
// secim.c — ikinci birim: tanimlar burada, cagrilar baglamada cozulur
#include "asama.h"

int birim_sayaci = 2;

int kimlik(void) {
    return 7;
}

const char *birim_adi(void) {
    return "secim";
}
```

Üçüncü dosya asıl ölçümü taşıyor. On dört ayrı gözlemi bir tabloya yazıyor, her satırın
hangi aşamada karara bağlandığını da yanına ekliyor.

```c
// asama.c — bir kararin hangi asamada verildigini olcen cekirdek
#include <stdio.h>
#include <string.h>
#include "asama.h"

#define KAT 3
#define BIRLESTIR(a, b) a##b

enum Renk { KIRMIZI = 1, YESIL = 2, MAVI = 4 };

static int BIRLESTIR(topla, _uc)(int x) {
    return x + 3;
}

static void gozle(const char *ad, const char *sinif, const char *kanit) {
    printf("%-30s%-14s%s\n", ad, sinif, kanit);
}

int main(void) {
    char tampon[64];
    int on_islemci = 0, derleyici = 0, baglayici = 0, kosum = 0;

    printf("%-30s%-14s%s\n", "gozlem", "asama", "kanit");

    /* --- on islemci --- */

    snprintf(tampon, sizeof tampon, "KAT metni %d olarak konuldu", KAT);
    gozle("makro degeri", "on islemci", tampon);
    on_islemci++;

#ifdef AYRINTILI
    gozle("kosullu govde", "on islemci", "ayrintili govde derlemeye girdi");
#else
    gozle("kosullu govde", "on islemci", "kisa govde derlemeye girdi");
#endif
    on_islemci++;

    snprintf(tampon, sizeof tampon, "uretilen ad %d verdi", BIRLESTIR(topla, _uc)(4));
    gozle("ad birlestirme", "on islemci", tampon);
    on_islemci++;

    gozle("baslik metni", "on islemci", "bildirimler kaynaga metin olarak kopyalandi");
    on_islemci++;

    /* --- derleyici --- */

    snprintf(tampon, sizeof tampon, "sizeof(char) == %d", (int)sizeof(char));
    gozle("tip boyutu birimi", "derleyici", tampon);
    derleyici++;

    int sabit_dizi[2 * 3 + 1];
    snprintf(tampon, sizeof tampon, "eleman sayisi %d", (int)(sizeof sabit_dizi / sizeof sabit_dizi[0]));
    gozle("sabit ifade katlamasi", "derleyici", tampon);
    derleyici++;

    snprintf(tampon, sizeof tampon, "MAVI sabiti %d", (int)MAVI);
    gozle("numaralandirma sabiti", "derleyici", tampon);
    derleyici++;

    int tam = 7 / 2;
    double kesirli = 7 / 2.0;
    snprintf(tampon, sizeof tampon, "tam %d kesirli %.1f", tam, kesirli);
    gozle("islecin tipe gore secimi", "derleyici", tampon);
    derleyici++;

    /* --- baglayici --- */

    snprintf(tampon, sizeof tampon, "cagri %d verdi", kimlik());
    gozle("baska birimdeki islev", "baglayici", tampon);
    baglayici++;

    snprintf(tampon, sizeof tampon, "birim %s olarak bildirildi", birim_adi());
    gozle("baska birimdeki ad", "baglayici", tampon);
    baglayici++;

    snprintf(tampon, sizeof tampon, "sayac %d", birim_sayaci);
    gozle("baska birimdeki degisken", "baglayici", tampon);
    baglayici++;

    /* --- kosum --- */

    int veri[] = {4, 8, 15, 16};
    int toplam = 0;
    for (size_t i = 0; i < sizeof veri / sizeof veri[0]; i++) {
        toplam += veri[i];
    }
    snprintf(tampon, sizeof tampon, "toplam %d", toplam);
    gozle("veriden hesaplanan deger", "kosum", tampon);
    kosum++;

    const char *metin = "merhaba dunya";
    snprintf(tampon, sizeof tampon, "uzunluk %d", (int)strlen(metin));
    gozle("dizgi uzunlugu", "kosum", tampon);
    kosum++;

    const char *karar = (toplam > 40) ? "buyuk" : "kucuk";
    gozle("veriye bagli dallanma", "kosum", karar);
    kosum++;

    printf("\n%-14s%d\n", "on islemci", on_islemci);
    printf("%-14s%d\n", "derleyici", derleyici);
    printf("%-14s%d\n", "baglayici", baglayici);
    printf("%-14s%d\n", "kosum", kosum);
    printf("toplam gozlem: %d\n", on_islemci + derleyici + baglayici + kosum);
    return 0;
}
```

```
gozlem                        asama         kanit
makro degeri                  on islemci    KAT metni 3 olarak konuldu
kosullu govde                 on islemci    kisa govde derlemeye girdi
ad birlestirme                on islemci    uretilen ad 7 verdi
baslik metni                  on islemci    bildirimler kaynaga metin olarak kopyalandi
tip boyutu birimi             derleyici     sizeof(char) == 1
sabit ifade katlamasi         derleyici     eleman sayisi 7
numaralandirma sabiti         derleyici     MAVI sabiti 4
islecin tipe gore secimi      derleyici     tam 3 kesirli 3.5
baska birimdeki islev         baglayici     cagri 7 verdi
baska birimdeki ad            baglayici     birim secim olarak bildirildi
baska birimdeki degisken      baglayici     sayac 2
veriden hesaplanan deger      kosum         toplam 43
dizgi uzunlugu                kosum         uzunluk 13
veriye bagli dallanma         kosum         buyuk

on islemci    4
derleyici     4
baglayici     3
kosum         3
toplam gozlem: 14
```

## Ölçümün Okunuşu

Tablonun dört bölümü dört ayrı bakış açısını gösteriyor. Ön işlemci bölümündeki dört satır
tip bilmez, yalnız metin bilir: makro değeri kaynağa metin olarak kondu, hangi koşullu
gövdenin derlemeye gireceği derleyici kaynağı görmeden belli oldu, iki parçadan yeni bir ad
üretildi ve başlık dosyasının bildirimleri kaynağa kopyalandı. Derleyici bölümündeki dört
satır ise yalnız tek bir birime bakarak karar veriyor: tip boyutunun birimi, sabit ifadenin
katlanması, numaralandırma sabitinin değeri ve bölme işlecinin hangi anlamı taşıyacağı hepsi
`asama.c`'nin kendi içinde çözüldü — hiçbiri `secim.c`'ye bakmadı.

Bağlayıcı bölümündeki üç satır bunun tam tersini gösteriyor: üçü de `secim.c`'de tanımlı bir
adı çağırıyor ve üçü de ancak iki birim bir araya gelince bir anlam kazanıyor. Tek başına
`asama.c` bu üç satırı derleyebilir, ama çalıştıramaz — eksik olan tanımlar yalnız bağlama
aşamasında tamamlanıyor. Koşum bölümündeki üç satır ise yalnız veriye bakıyor: toplam, dizgi
uzunluğu ve veriye bağlı dallanma hiçbiri kaynakta sabit bir sayı olarak durmuyor, üçü de
`main` çalışırken hesaplanıyor. Aynı kaynak farklı bir `veri` dizisiyle çalıştırılsaydı bu
üç satırın sonucu değişirdi; önceki üç bölümde bu mümkün değil, çünkü onların sonucu
kaynağın kendisinden — koşulmadan önce — bellidir.

**DD1.** `gozle` işlevi, `tampon` arabelleği ve dört sayaç (`on_islemci`, `derleyici`,
`baglayici`, `kosum`) çekirdeğin kendi tasarım kararıdır, C'nin bir düzeneği değildir. C'nin
kendisinde "bu satır hangi aşamaya ait" diye soran bir işlev yoktur; hangi satırın hangi
sınıfa girdiğine karar veren şey satırın kaynaktaki konumu ve biçimidir, `gozle` çağrısı
yalnız bu kararı bir satıra yazıp on dört gözlemi tek koşumda karşılaştırılabilir kılar.

**DD2.** Sayaçların dördü de sıradan `int` değişkenidir ve elle artırılır. C'nin çalışma
zamanı, bir satırın derlenirken hangi aşamaya ait olduğunu tutan bir kayıt taşımaz — bu
bilgi koşum başladığında zaten geçmişte kalmıştır. Dağılımı saymanın tek yolu, her gözlemin
yanına doğru sayacı elle eklemektir; sayım da bu yüzden çekirdeğin kaynağında, yani ön
işlemci ile derleyicinin göreceği metinde durur.

On dört gözlemin dördü ön işlemcide, dördü derleyicide, üçü bağlayıcıda, üçü koşumda karara
bağlandı ve çıktı bu dağılımı doğrudan basıyor. Bu sayılar kursun geri kalanı için bağlayıcıdır:
hiçbir ders bu dağılımı değiştirmez, yalnız kendi kesitini alır.

## Aynı Karar, Dört Yer

Çekirdeğin on dört satırı rastgele seçilmedi; her biri aynı türden bir soruyu farklı bir
aşamada yanıtlıyor: **bir değerin ne olduğu**. `KAT` sabitinin değeri ön işlemcide belli
oluyor, çünkü `#define` bir metin değiştirme kuralıdır ve derleyici kaynağı görmeden önce
uygulanır. `MAVI` sabitinin değeri derleyicide belli oluyor, çünkü bir numaralandırma
(`enum`) üyesi derleme zamanı sabitidir ve tek bir birime bakılarak çözülür. `birim_sayaci`
değişkeninin değeri bağlayıcıda belli oluyor, çünkü değişken `secim.c`'de tanımlı ve
`asama.c` ona yalnız `extern` bir bildirimle erişiyor — ikisi ancak bağlanınca aynı adresi
paylaşıyor. `toplam` değişkeninin değeri ise koşumda belli oluyor, çünkü bir dizinin
elemanları üzerinde döngü yürütülmeden hesaplanamaz.

**DD3.** `enum Renk` üyelerine `1`, `2`, `4` değerlerinin açıkça verilmesi de bir kaynak
kararıdır, dilin zorunlu kıldığı bir şey değildir. Değer verilmeseydi C, üyeleri sıfırdan
başlayarak birer birer artırırdı (`0`, `1`, `2`); burada üyeler bilinçli olarak ikinin
kuvvetleri seçildi ki her biri ayrı bir bit temsil edebilsin. Bu, dördü değil, tek bir
kararı — bir sabitin sayısal değerini — ilgilendiriyor ve o karar da yine derleyici
aşamasında veriliyor.

Dördü de "bir değerin ne olduğu" sorusuna yanıt veriyor, ama dördü de farklı bir yerde
yanıtlıyor. Aynı soruyu sorduğun her seferde hangi aşamanın yanıt vereceğine karar veren
şey, o değeri kaynakta **nasıl yazdığındır**: bir `#define` yazarsan ön işlemci yanıtlar,
bir `enum` yazarsan derleyici yanıtlar, başka bir birimde tanımlı bir ad kullanırsan
bağlayıcı yanıtlar, bir diziyi dolaşırsan koşum yanıtlar. Programcı bu dördü seçebiliyor;
dilin kendisi hiçbirini dayatmıyor.

Bu örüntü kursun ilerleyen derslerinde başka biçimlerde tekrar karşımıza çıkacak. Aynı işi
gören bir hesap Ön İşlemci dersinde bir makro olarak, Fonksiyonlar dersinde bağlayıcının
çözdüğü bildirilmiş bir çağrı olarak yazılabilir; ikisi de "bu değer nedir" sorusuna yanıt
verir, ama biri metin düzeyinde, öbürü birimler bir araya gelince. Kurs boyunca sorulacak
soru değişmiyor: kaynakta yazılan bu karar hangi elde veriliyor?

## Sınırlayıcı Ölçüm

Dört aşamanın varlığı bir karmaşıklık değil, dört ayrı denetim noktasıdır. Aynı türden bir
yanlışlık dört ayrı yerde ortaya çıkabilir ve dördü de aynı ağırlığı taşımaz. `KAT`
makrosuna yanlış bir sayı yazılırsa metin yanlış üretilir ve bu, kaynağın geri kalanına
sessizce yayılır — ön işlemci hiçbir denetim yapmaz, yalnız değiştirir. `MAVI` sabitine
yanlış bir değer verilirse derleyici bunu görebilir, çünkü tek bir birimin içinde kalan bir
tutarsızlıktır. `secim.c`'deki bir tanım silinirse hata derleyicide değil bağlayıcıda çıkar,
çünkü `asama.c` kendi başına derlenmeye devam eder — eksik olan yalnız birimler bir araya
gelince görünür. `veri` dizisine yanlış bir sayı eklenirse hiçbir aşama bunu yakalamaz;
sonuç yalnız o veriyle koşulunca ortaya çıkar.

Dördü de "yanlış değer" diye anılabilir, ama dördünün yakalandığı yer ayrıdır ve dördü de
aynı gücü taşımaz. Ön işlemci ve derleyici hatası programın derlenmesini durdurabilir;
bağlayıcı hatası programın bağlanmasını durdurabilir; koşum hatası ise yalnız o veriyle
karşılaşıldığında görünür ve önceki üç aşamanın hiçbiri onu göremez. Aşama sayısının
fazlalığı bu yüzden bir yük değil, bir avantajdır: aynı hata sınıfının nerede yakalanacağını
seçmek, kaynağı nasıl yazdığına bağlıdır.

Bu sınır kursun geri kalanında bir uyarı olarak da okunmalı: bir aşamanın denetlemediği bir
şey, bir sonraki aşamanın denetleyeceği anlamına gelmez. Ön işlemcinin geçtiği bir hata
derleyiciye kalmaz; derleyicinin geçtiği bir hata bağlayıcıya kalmaz; bağlayıcının geçtiği
bir hata da koşuma kalmaz — her aşama yalnız kendi girdisine bakar ve bir öncekinin ne
yaptığını sorgulamaz. Dört aşamanın toplamı bu yüzden birbirini tamamlayan bir denetim
zinciri değil, dördü de kendi sınırları içinde çalışan dört ayrı bakıştır.

## Özet

- Bir C kaynağı programa dönüşürken dört aşamadan geçer: ön işlemci, derleyici, bağlayıcı,
  koşum; bu dört ad kurs boyunca değişmez.
- Üç dosyalık ölçüm çekirdeği on dört gözlemi tek koşumda sınıflandırdı: 4'ü ön işlemci,
  4'ü derleyici, 3'ü bağlayıcı, 3'ü koşum.
- Aynı türden bir karar (bir değerin ne olduğu) dört aşamanın herhangi birinde verilebilir;
  hangisinin seçildiği kaynağın nasıl yazıldığına bağlıdır.
- Dört aşamanın varlığı karmaşıklık değil denetim noktası çokluğudur: aynı tür hata dört
  ayrı yerde, dört ayrı ağırlıkla yakalanabilir.

## Sonraki Adım

Bu ders dört aşamayı adlandırdı ve tek bir koşumda yan yana gösterdi. Sıradaki ders aynı
çekirdeğe geri dönüyor, ama bu kez dört sınıfı tek tek ele alıyor: her aşamanın kararını
verirken **hangi girdiye baktığı** ve aşamaların neden geri dönüşü olmayan bir sırayla
çalıştığı.
