Programlama işindeki ilerlemeyi satır sayısı ile ölçmek, uçak imalatı işindeki ilerlemeyi ağırlıkla ölçmek gibi olur.

Bill Gates

Bana Atılan E-Postaların Yanıtları

Sevgili Arkadaşlar...

Bu site aracılığıyla -bazıları sorulardan oluşan- pek çok e-posta alıyorum. Ancak yoğunluk nedeniyle bazılarına yanıt yazamadım.  Sakın unuttum sanmayın ve "adam bir yanıt bile yazmadı" diye düşünmeyin :-). Bundan sonra atacağınız e-postalara da daha kısa bir süre içinde yanıt vermeye çalışacağım. Gecikme için özür diliyorum...

 

Lütfen Alıntılarda Kaynak Belirtiniz

Çeşitli Internet sitelerinde yazmış olduğum makalelerden, ders notlarından, çizimlerden, kaynak kodlardan vs. bire bir alıntı yapıldığını, ancak kaynak belirtlmediğini görüyorum. Lütfen bu gibi alıntlarda kaynak belirtiniz.

Kitap Eleştirisi

Artık her hafta sitede bilgisayar alanında basılmış bir kitabın eleştirisini göreceksiniz. Umarım beğenirsiniz...

Tarihe Göre

Yeni İçerik

C’nin Standart Dosya Fonksiyonlarının Uyguladığı Tamponlama Mekanizması

    Standart C fonksiyonlarını kullanmadan bir dosyanın her byte’ı üzerinde sırasıyla işlem yapmak isteyelim. Herhalde ilk akla gelecek yöntem doğrudan işletim sisteminin sistem fonksiyonlarını çağırmak olacaktır. Örneğin UNIX/Linux sistemlerinde dosyayı read fonksiyonuyla (Windows sistemlerinde ReadFile fonksiyonuyla) byte byte aşağıdaki gibi okuyabiliriz:
 
int fd;
ssize_t result;
unsigned char ch;

if ((fd = open("test", O_RDONLY)) < 0) {
    perror("open");
    exit(EXIT_FAILURE);
}

while ((result = read(fd, &ch, 1)) > 0) {
    /* Okunan byte işleniyor */
}   

if (result < 0) {
    perror("read");
    exit(EXIT_FAILURE);
}   

close(fd);

Programların Komut Satırı Argümanları

    İşletim sistemi tarafından prosese geçirilen komut satırı argümanları program içerisinden çeşitli biçimlerde elde edilebilmektedir. En yaygın yöntem komut satırı argümanlarının programın başlangıç fonksiyonunun parametrelerinden elde edilmesidir. Örneğin, C ve C++’ta komut satırı argümanları main fonksiyonuna parametre olarak geçirilirler. Bu dillerin standartlarına göre programın başlangıç noktasını (entry point) belirten main fonksiyonunun parametrik yapısı ve geri dönüş değeri aşağıdaki iki durumdan biri biçiminde olmalıdır:

int main(void)  { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }

UNIX/Linux ve Windows Sistemlerinde Stdin, Stdout ve Stderr Dosyaları

    Yalnızca UNIX/Linux sistemlerinde değil modern işletim sistemlerinin çoğunda aygıtlar birer dosyaymış gibi ele alınmaktadır. Örneğin klavye ve ekran -aslında birer dosya olmadığı halde- işletim sistemi tarafından sanki birer dosyaymış gibi işleme sokulurlar. Aygıtlara ilişkin bu tür dosyalar için de birer dosya betimleyicisi ve dosya nesnesi vardır. Bu betimleyicilerle işlem yapıldığında işletim sisteminin dosya alt sistemi aslında bu dosyaların birer aygıta ilişkin olduğunu anlar ve okuma/yazma amacıyla o aygıtlara yönelir. UNIX türevi sistemlerdeki çokbiçimliliği (polymophism) andıran bu tasarıma Sanal Dosya Sistemi (Virtual File System) denilmektedir.  

C#'taki Yapı ve Sınıf Nesneleri Nerede Yaratılıyor?

Pek çok C# programcısının sınıf ve yapı kavramlarıyla stack ve heap kavramlarını yanlış bir biçimde ilişkilendirdiğini görüyorum. Örneğin, “yapı nesneleri stack’te sınıf nesneleri heap’te tutulur” biçiminde yanlış anlaşılmaya yol açacak bilgiler veren yerli ve yabancı çok sayıda yazı ve makaleyle karşılaştım. Konuya biraz açıklık getirmek istiyorum.

UNIX/Linux Sistemlerinde Dosya Betimleyicilerinin Anlamı

    UNIX/Linux sistemlerinde her prosesin proses tablosu yoluyla erişilen bir dosya betimleyici tablosu (file descriptor table) vardır. Dosya betimleyici tablosu bir gösterici dizisi biçimindedir. Betimleyci tablo içersindeki her gösterici açılmış bir dosyanın bilgilerinin tutulduğu ve ismine dosya nesnesi (file object) denilen bir veri yapısını gösterir. open fonksiyonundan elde edilen dosya betimleyicisi (file descriptor) prosesin dosya betimleyici tablosunda bir indeks belirtmektedir.

Proseslerin Çevre Değişkenleri

    Modern işletim sistemlerinde her prosesin bir çevre değişken bloğu vardır. Prosesin çevre değişken bloğu çevre değişkenlerinden ve onların değerlerinden oluşmaktadır. Örneğin, MESAJ bir çevre değişkeninin ismi olabilir, “Merhaba Dunya” ise onun değeri olabilir. Çevre değişkenleri pek çok işletim sisteminde proses yaratılırken belirlenebilmekte  ya da üst prosesten (parent process) aktarılabilmektedir. Çevre değişkenlerinin üst prosesten aktarılması en çok karşılaşılan tipik durumdur.

Temmuz
11
2009

C#’ta Using Namespace Direktifi

      Pek çok C# programcısının using namespace direktifinin kullanımını pek iyi bilmediğini görüyorum. Bu konuda bazı açıklamalar yapayım dedim. Ancak bu yazıda extern alias ve using alias direktifleri üzerinde durmayacağım. Bunlara ilişkin de bir makale yazmayı planlıyorum.

Öncelikle using namespace direktifinin, isim alanlarının ilk elemanları olacak biçimde -eğer varsa- extern alias direktiflerinden sonra belirtilmek zorunda olduğunu anımsatayım. Örneğin aşağıdaki bildirim geçersizdir:
 
namespace A
{
    class X
    {
        //...
    }

    using System;            // error!

    class Y
    {
        //...
    }
    //...
}

using direktifleri (extern alias direktiflerinden sonra) isim alanlarının başında bulunmak zorundadır:

namespace A
{
    using System;            // geçerli

    class X
    {
        //...
    }

    class Y
    {
        //...
    }
    //...
}

Eğer global isim alanı söz konusuysa, using direktiflerinin (global isim alanının başı kaynak dosyanın başı olduğu için) kaynak dosyanın (compilation unit) başına yerleştirilmleri zorunludur. 

using namespace direktifinin genel biçimi şöyledir:

using <isim alanı belirten ifade>
{
    //...
}

İsim alanı belirten ifade tek bir isim olabilir ya da nokta operatörü ile oluşturulmuş olabilir. Örneğin:

using System;
using System.IO;

Şimdi gelelim using namespace direktifinin ne işe yaradığına. Bu direktif gereksiz niteliklendirmeyi engellemek için düşünülmüştür. using namespace direktifinde iki isim alanı söz konusudur: Direktifin yerleştirildiği isim alanı ve direktifte belirtilen isim alanı. Örneğin:

namespace A
{
    using B;
    //...
}

buradaki using namespace direktifinde direktifin yerleştirildiği isim alanı A, direktifte belirtilen isim alanı B’dir.

Standart anlatımıyla açıklarsak: using namespace direktifi, direktifte belirtilen isim alanı içerisinde bildirilmiş olan isimleri direktifin yerleştirildiği isim alanına taşır. Fakat using namespace direktifi,  direktifte belirtilen isim alanı içerisindeki isim alanı isimlerini taşımamaktadır ve ayrıca da direktifin yerleştirildiği isim alanındaki isimler direktifte belirtilen isimleri gizlemektedir. Ya da şöyle daha iyi açıklayabiliriz: İsim araması sırasında eğer isim direktifin yerleştirildiği isim alanı içirisinde bulunamazsa direktifte belirtilen isim alanına da bakılır. Burada birkaç nokta üzerinde durmak gerekecek. Açıklamalarda aşağıdaki örneği kullanacağım:

namespace A
{
    using B;
    using C;
   
    class App
    {
        public static void Main()
        {
           
X x;     // Geçerli, A.X
            Y y;     // Geçerli, B.Y
            Z z;     // error! Z hem A'da hem de B'de var 
            K k;     // error! Direktifin geçişililiği yok!
            C.K ck;  // error! K ismi C'de aranır 
            E.L dl;  // error! E isim alanı görülemez!
            //...
        }
    }

    class Sample
    {
        //...
    }
}

class Y
{
    //...
}

namespace B
{
    class X
    {
        //...
    }

    class Y
    {
        //...
    }

    class Z
    {
        //...
    }

    namespace E
    {
        class L
        {
            //...
        }
    }
}

namespace C
{
    using D;

    class Z
    {
        //...
    }
}

namespace D
{
    class K
    {
        //...
    }
   
}

1. Eğer isim direktifin yerleştirildiği isim alanına kadar ya da direktifin yerleştirildiği isim alanında bulunursa direktifin bir etkisi kalmaz. Örneğimizdeki Main içerisindeki X ismi direktifin yerleştirildiği A isim alanında bulunduğu için B'de ve C'de aranmayacaktır. Yani buradaki X sınıfı A.X sınıfıdır.

2. İsim using namespace direktifi ile belirtilen isim alanında  bulunmuşsa aramaya devam edilmez. Örneğimizdeki Main metodunda kullanılan Y sınıfı B.Y sınıfıdır, global isim alanındaki Y sınıfı değildir.

3. İsim birden fazla using namespace direktifi ile belirtilen isim alanında bulunursa error oluşur. Direktiflerin yerleştirilme sırasının bir önemi yoktur. Örneğin Main içerisindeki Z ismi hem B isim alanında hem de C isim alanında bulunmaktadır. Bu durumda ismi nitelikli olarak (yani B.Z ya da C.Z biçiminde) bildirmek ya da using alias direktifi kullanmak gerekir.

4. using namespace direktifi geçişli değildir. Yani eğer isim direktifle belirtilen isim alanında bulunamamışsa, o isim alanındaki isimler dikkate alınmaz. Örneğin Main içerisinde K ismi kullanılmıştır. Bu isim D isim alanı içerisindedir. C'deki using direktifinin bir etkisi yoktur. 

5. using namespace direktifinde eğer isim nitelikli olarak aranıyorsa (yani nokta operatörünün sağındaki isim aranıyorsa) bu durumda using namespace direktifinin bir etkisi yoktur. Örneğin Main metodundaki C.K ifadsinde C ismi bulunur. K ismi ise C'de aranır. C'de bulunamazsa D'ye bakılmaz.

6. using namespace direktifinde, direktifte belirtilen isim alanında arama yapılırken isim alanı isimleri görülmez. Örneğimizde E.L ifadesinde B isim alanına bakılırken buradaki E görülmeyecektir.

Haftanın Böceği Yukarı