Ders 13 / 13
Girdi/Çıktı
Bir biçim dizesinin metni derlemede bellidir ama ne anlama geldiği ancak koşumda belli olur: dokuz gözlemin biri ön işlemcide, ikisi derleyicide, biri bağlayıcıda, beşi koşumda karara bağlanıyor. Sınırlayıcı ölçüm, biçim dizesi ile argümanların uyumunu dilin kendisinin garanti etmediğini gösteriyor.
Yayın Güncelleme
Bu derste
- Bir biçim dizesinin hangi parçasının derlemede, hangisinin koşumda karara bağlandığını ölçer
- Yazma işlevlerinin dönüş değerini okuyup kesilen yazımı fark eder
- Metinden okumanın kaç alan atadığını sayarak başarısız okumayı ayırt eder
İçindekiler
Kurs boyunca sorulan soru hep aynıydı: bu karar hangi aşamada veriliyor. Girdi ve çıktı, o soruyu tek bir satırda dört aşamaya birden dağıtabildiği için kursun kapanışına uygun düşüyor. Bir yazma çağrısında biçim dizesindeki bir makro ön işlemcide yerine konur, dizenin metni derlemede sabitlenir, çağrılan işlevin tanımı bağlamada bulunur ve dizenin ne anlama geldiği ancak koşumda belli olur.
Bu ders o dağılımı ölçüyor. Ölçüm çekirdeğin veriden hesaplanan deger satırının bıraktığı
yerden devam ediyor: orada bir toplam koşumda hesaplanmıştı, burada o toplamın nasıl
yazıldığı soruluyor.
Dokuz Gözlem
// girdicikti.c — bir bicim dizesinin hangi asamada karara baglandigi
#include <stdio.h>
#include <string.h>
#define ETIKET "olcum"
static void gozle(const char *ad, const char *asama, const char *kanit) {
printf("%-34s%-12s%s\n", ad, asama, kanit);
}
int main(void) {
char tampon[64];
char kucuk[8];
printf("%-34s%-12s%s\n", "gozlem", "asama", "kanit");
/* on islemci */
snprintf(tampon, sizeof tampon, "%s basligi metne kondu", ETIKET);
gozle("bicim dizesindeki makro", "on islemci", tampon);
/* derleyici */
snprintf(tampon, sizeof tampon, "eleman sayisi %d", (int)(sizeof tampon / sizeof tampon[0]));
gozle("tampon uzunlugu", "derleyici", tampon);
const char *sabit = "deger: %d";
snprintf(tampon, sizeof tampon, "metin %d karakter", (int)strlen(sabit));
gozle("bicim dizesinin metni", "derleyici", tampon);
/* baglayici */
gozle("bicimleme islevinin tanimi", "baglayici", "kaynakta tanim yok, cagri yine de cozuldu");
/* kosum */
int deger = 42;
const char *bicim = (deger < 100) ? "%d" : "[%d]";
snprintf(tampon, sizeof tampon, bicim, deger);
gozle("bicim dizesinin secimi", "kosum", tampon);
int genislik = (int)strlen("dort") + 1;
snprintf(tampon, sizeof tampon, "%*d", genislik, deger);
gozle("alan genisligi argumani", "kosum", tampon);
int istenen = snprintf(kucuk, sizeof kucuk, "%s", "merhaba dunya");
snprintf(tampon, sizeof tampon, "istenen %d yazilan %d", istenen, (int)strlen(kucuk));
gozle("kesilen yazim", "kosum", tampon);
int okunan = 0, sayi = 0;
okunan = sscanf("sicaklik 21 derece", "sicaklik %d", &sayi);
snprintf(tampon, sizeof tampon, "atanan alan %d deger %d", okunan, sayi);
gozle("metinden okuma", "kosum", tampon);
int eslesmeyen = sscanf("sicaklik yirmibir", "sicaklik %d", &sayi);
snprintf(tampon, sizeof tampon, "atanan alan %d", eslesmeyen);
gozle("eslesmeyen okuma", "kosum", tampon);
printf("\n%-12s%d\n", "on islemci", 1);
printf("%-12s%d\n", "derleyici", 2);
printf("%-12s%d\n", "baglayici", 1);
printf("%-12s%d\n", "kosum", 5);
printf("toplam gozlem: %d\n", 9);
return 0;
}
gozlem asama kanit bicim dizesindeki makro on islemci olcum basligi metne kondu tampon uzunlugu derleyici eleman sayisi 64 bicim dizesinin metni derleyici metin 9 karakter bicimleme islevinin tanimi baglayici kaynakta tanim yok, cagri yine de cozuldu bicim dizesinin secimi kosum 42 alan genisligi argumani kosum 42 kesilen yazim kosum istenen 13 yazilan 7 metinden okuma kosum atanan alan 1 deger 21 eslesmeyen okuma kosum atanan alan 0 on islemci 1 derleyici 2 baglayici 1 kosum 5 toplam gozlem: 9
TS14. ETIKET makrosu biçim dizesine derleyici kaynağı görmeden önce kondu. Ön işlemci
için bu bir metin birleştirmesidir; dizenin bir biçim dizesi olduğunu bilmez, %s ile
%d arasındaki farkı da bilmez. Bu yüzden makroyla kurulan bir biçim dizesi, argüman
listesiyle uyuşmasa bile ön işlemci aşamasını sorunsuz geçer.
TS15. Tampon uzunluğu derlemede bellidir: sizeof tampon / sizeof tampon[0] bir sabit
ifadedir ve 64 verir. Dizinin uzunluğunun derlemede bilindiği Diziler ve Dizgiler
dersinde ölçülmüştü; burada aynı bilgi bir yazma çağrısının sınırı olarak kullanılıyor.
Biçim dizesinin metni de aynı sınıfa düşer — deger: %d dokuz karakterdir ve bu sayı
kaynaktan okunur, koşumdan değil.
TS16. Biçimleme işlevinin tanımı kaynakta yok. Yalnız başlık dosyasından gelen bildirimi
var ve çağrı buna rağmen çözüldü: tanımı bağlayıcı buldu. Bu, Fonksiyonlar dersindeki
baska birimdeki islev satırının aynısıdır; tek fark, tanımın bu kez ayrı bir kaynak
biriminde değil, dilin standart kitaplığında olmasıdır.
TS17. Kalan beş gözlem koşuma düşüyor ve hepsinin ortak yanı şu: kaynak metni değişmeden
sonucun değişebilmesi. Biçim dizesi bir koşula göre seçildi (deger < 100 doğru olduğu için
köşeli ayraçsız biçim kullanıldı), alan genişliği bir argümandan geldi (dort beş karakterlik
bir alan açtı), yazma kesildi, bir metinden bir sayı okundu ve bir okuma hiçbir alan
atayamadı.
Dönüş Değeri Ne Söylüyor
TS18. Kesilen yazım satırı, dönüş değerinin ne olduğunu gösteriyor: istenen 13 yazilan 7.
Yazma işlevi, tampona sığdırabildiği karakter sayısını değil, sığdırmak isteseydi kaç
karakter yazacağını döndürüyor. On üç karakterlik metin sekiz baytlık tampona konduğunda
yedi karakter ve bir sonlandırıcı yazıldı, ama dönüş değeri on üç kaldı. Bu iki sayının
ayrışması, kesilmenin olup olmadığını anlamanın tek belirlenimci yoludur: dönüş değeri tampon
uzunluğundan küçükse yazım tamdır.
TS19. Okuma tarafında dönüş değeri başka bir şey sayıyor: kaç alanın atandığını. Aynı
biçim dizesi bir metinde bir alan atadı, ötekinde sıfır. İkinci metin de geçerli bir metindi
ve program çökmedi — yalnız sayi değişkeni dokunulmamış kaldı. Okumanın başarısızlığı
bir hata değeriyle değil, bir sayımla bildiriliyor ve o sayıyı okumayan bir kaynak,
atanmamış bir değişkeni atanmış sanır.
Sınırlayıcı Ölçüm
TS20. Biçim dizesi ile argümanların uyumunu dilin kendisi garanti etmez. Yukarıdaki
ölçümde biçim dizesi bir yerde bir değişkenden geldi — koşula göre seçilen bicim işaretçisi.
O çağrıda derleyicinin elinde, dizenin içeriğine bakarak argümanları denetleyecek bir bilgi
yoktu; dize koşumda seçiliyordu. Biçim dizesi kaynakta yazılı bir sabit olduğunda
derleyicinin elinde uyumu denetleyecek bilgi vardır ve yaygın derleyiciler bunu isteğe bağlı
bir uyarı olarak sunar. Denetimin kendisi dilin bir garantisi değildir: standart, argümanın
biçim belirleyicisiyle uyuşmamasını doğrudan tanımsız davranış sayar ve hiçbir denetim
öngörmez. Dize bir değişkenden geldiğinde o bilgi de kalmaz — denetim düşer ve sorumluluk
tümüyle yazana geçer.
Bu, kursun dört aşamalı sorusunun en keskin sonucudur: aynı çağrı, biçim dizesinin nereden geldiğine göre derleyici sınıfından koşum sınıfına kayar. Kaynak metni neredeyse aynıdır; değişen tek şey, bir bilginin hangi aşamada elde bulunduğudur.
Kapanış Tablosu
On üç ders boyunca ölçülen kararlar aşağıda toplanıyor. Aşama hücresi her dersin kendi metninde yazılı olandan alınmıştır; birden çok aşama ölçen dersler ikisini de taşır.
| Ders | Ölçülen karar | Aşama | Sınırlayıcı ölçüm |
|---|---|---|---|
| C’nin Konumu | Çekirdeğin on dört gözleminin dağılımı | dördü birden | Dört aşama bir karmaşıklık değil, dört ayrı denetim noktasıdır |
| Derleme Aşamaları | Her aşamadan birer satırın yan yana koşumu | dördü birden | Aşamalar sırayla çalışır ve geri dönmez; ön işlemcinin ürettiği metni derleyici düzeltmez |
| Başlık Dosyaları | Bildirimin metin olarak kopyalanması | ön işlemci · bağlayıcı | Başlık dosyası bir sözleşme değildir; bildirimle tanımın uyumunu dil denetlemez |
| Ön İşlemci | Makronun tip bilmeden metin koyması | ön işlemci | Makro bir işlev değildir; argümanı birden çok kez yerine konabilir |
| Derleyici Uyarıları ve Standartlar | Uyarının hangi aşamada doğduğu | derleyici | Uyarı bir hata değildir ve uyarısız derlenen bir program doğru sayılmaz |
| Veri Tipleri | Tip aralığı ve tam sayı yükseltmesi | derleyici | Taşma davranışı tipin işaretine bağlıdır: işaretsizde tanımlı, işaretlide tanımsız |
| Değişkenler, Kapsam ve Ömür | Adın görünürlüğü ile değerin yaşadığı süre | derleyici · koşum · bağlayıcı | Aynı ad iki birimde iki ayrı nesne olabilir; bunu belirleyen bağlayıcıdır |
| İşleçler | İşlecin tipe göre anlam değiştirmesi | derleyici | Öncelik gruplamayı belirler, değerlendirme sırasını her zaman belirlemez |
| Denetim Akışı | Hangi dalın izlendiği | koşum · ön işlemci | Hangi dalların var olduğu koşumla değil, ön işlemciyle belirlenmiş olabilir |
| Fonksiyonlar | Çağrının tanıma bağlanması | bağlayıcı | Bildirimle tanımın birimler arası uyuşmazlığını ne derleyici ne bağlayıcı denetler |
| Diziler ve Dizgiler | Dizi uzunluğu ile dizgi uzunluğu | derleyici · koşum | Dizinin uzunluğu derlemede bellidir ama bu bilgi işleve geçmez |
| Yapılar, Birlikler ve Numaralandırmalar | Alanların yerleşimi ve sabitlerin değeri | derleyici | Birlik, hangi alanın en son yazıldığını kendi başına izlemez |
| Girdi/Çıktı | Biçim dizesinin yorumlanması | koşum | Biçim dizesi bir değişkenden geldiğinde derleyicinin uyum denetimi düşer |
Özet
- Bir yazma çağrısı dört aşamayı birden taşıyabiliyor: makro ön işlemcide, tampon uzunluğu ve dizenin metni derleyicide, işlevin tanımı bağlayıcıda, dizenin anlamı koşumda karara bağlandı.
- Dokuz gözlemin biri ön işlemcide, ikisi derleyicide, biri bağlayıcıda, beşi koşumda ölçüldü; girdi çıktı, kursun dört sınıfının en yoğun karıştığı yerdir.
- Yazma işlevinin dönüş değeri yazılan karakter sayısı değil, yazılmak istenen sayıdır: on üç istendi, yedi yazıldı, dönüş on üç kaldı.
- Okuma işlevinin dönüş değeri atanan alan sayısıdır; sıfır dönen bir okumada hedef değişken dokunulmamış kalır ve bunu fark etmenin tek yolu o sayıyı okumaktır.
- Biçim dizesi kaynakta sabitken derleyici argüman uyumunu denetleyebiliyor; dize bir değişkenden geldiğinde aynı çağrı koşum sınıfına kayıyor ve denetim düşüyor.
Kurs Kapanışı
On üç ders boyunca tek bir soru soruldu: bu karar hangi aşamada veriliyor. Ortak tanımın on dört gözlemi 4 ön işlemci, 4 derleyici, 3 bağlayıcı, 3 koşum olarak dağılmıştı ve bu dağılım kurs boyunca değişmedi — değişen, hangi düzeneğin hangi sınıfa düştüğüydü.
Dil ve Derleme konusu soruyu kaynağın programa dönüşme yoluna sordu: dört aşamanın varlığına, bildirimlerin metin olarak paylaşılmasına, ön işlemcinin tip bilmemesine ve uyarının nerede doğduğuna. Temel Sözdizim konusu aynı soruyu dilin kendi yapılarına taşıdı: bir tipin taşıdığı değere, bir adın görünürlüğü ile bir değerin ömrünün ayrı sorular olmasına, bir işlecin tipe göre anlam değiştirmesine, bir çağrının nerede çözüldüğüne, bir uzunluğun ne zaman bilindiğine ve bir kayıt tipinin alanlarının nasıl yerleştiğine.
Kursun en çok tekrarlanan tek bulgusu şudur: aynı kaynak metni, bir bilginin hangi aşamada elde bulunduğuna göre farklı davranır. Bir dizi uzunluğu derlemede bilinir, bir dizgi uzunluğu koşumda; bir makro tip bilmez, bir derleyici bilir; bir ad iki birimde aynı yazılır ama aynı nesne olmayabilir.
Sıradaki kurs belleğe ve işaretçilere bakıyor: bir değerin nerede durduğu, kim tarafından ayrıldığı ve ne zaman bırakıldığı. C’de bu soruların hepsi kaynakta yazılıdır ve hiçbiri kendiliğinden denetlenmez.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.