Standart C Programlama Dili


5.6. Alanlar

Bazı durumlarda, dar bir yer içine (örneğin bir tamsayı boyunda bir bölgeye) birçok bilgi sığdırmamız gerekebilir. Bunun nedeni bellek tasarrufu olabildiği gibi, program dışındaki bazı durumlardan (örneğin donanım aygıtlarına olan arabirimlerden) kaynaklanabilir. Bunu yapmak için bir yapının üyelerini bit uzunluklarını da vererek tanımlarız. Bu tür üyelere alan adı verilir. Doğal olarak, uzunluklar sıfırdan küçük olmayan değişmez ifadelerdir. Tanım yapılarda olduğu gibidir; sadece her üyenin arkasına iki nokta ile uzunluk verilebilir. Erişim de yapılarda olduğu gibi . veya -> işleçleri ile yapılır. Bir örnek:

struct tarih {
  unsigned short yil : 7;
  unsigned short  ay : 4;
  unsigned short gun : 5;
};

veya daha kısa bir şekilde:

struct tarih {
  unsigned short yil : 7,  ay : 4,  gun : 5;
};

Burada, tarihin iki bayt (sizeof(struct tarih) 2’dir) içine sığdırılabileceği bir yapı tanımlanmaktadır. yil 7 bit kullanır (işaretsiz olduğu için, değeri 0’dan 27-1=127’e kadar değişebilir ve örneğin 1950 ile 2077 arasındaki yılları ifade etmek için kullanılabilir), ay 4 bit (0’dan 24-1=15’e kadar değişir), gun ise 5 bittir (0’dan 25-1=31’e kadar değişir). Eğer uzunlukları belirtmemiş olsaydık, her üye 2 bayt kullanacak, böylece tüm yapı 6 bayt kaplayacaktı.

Alanlarla uğraşan birisinin dikkat etmesi gereken kurallar şöyle özetlenebilir:

  1. Alan tipi signed veya unsigned bir tamsayı olmalıdır. Genelde, unsigned tamsayılar tercih edilir.
  2. Bitlerin alanlara atanma tarzı (soldan sağa veya sağdan sola) derleyiciye bağlıdır.
  3. Eğer bir alan sözcük sınırlarını (sistemimizde, short için 16, int için 32, long için 64 ve char için 8 bitlik sınırları) kesecek şekilde tanımlanırsa bir sonraki sözcükten başlatılır; kullanılmakta olan sözcükteki bitler kullanılmaz. Örneğin,

    struct dnm {
      unsigned short
        a1 : 12,
        a2 : 5,
        a3 : 12;
    };
    

    aşağıdaki biçimde 6 bayt kaplar:

    12 bit a1, 4 bit kullanılmıyor (ilk short sözcük, yani iki bayt),

    5 bit a2, 11 bit kullanılmıyor (ikinci sözcük),

    12 bit a3, 4 bit kullanılmıyor (üçüncü sözcük).

    Eğer unsigned short yerine unsigned int kullanmış olsaydık, yapı aşağıdaki biçimde 4 bayt kaplayacaktı:

    12 bit a1, 5 bit a2, 12 bit a3, 3 bit kullanılmıyor (bir int sözcük, yani 4 bayt).

    Eğer unsigned char kullanmış olsaydık, tanım kabul edilmeyecekti, çünkü alan a1 12 bit uzunluğundadır, oysa bir char en fazla 8 bit tutabilir. Bu, bir alanın kendi tipinden daha geniş olamayacağı anlamına gelir. Eğer bir alan için bit sayısı belirtilmemişse, o tip için en büyük değer kullanılır.

  4. Alanlardan oluşan diziler tanımlanamaz.
  5. Adres alma işleci (&) alanlara uygulanamaz, böylece alanlar gösterge kullanarak doğrudan doğruya adreslenemezler.
  6. Alan isimleri isteğe bağlıdır. Eğer bir alanı—örneğin, yukarıdaki örnekte a2’yi—kullanmayı düşünmüyorsanız, alan ismini atlayın. Örneğin,

    struct dnm {
      unsigned short
        a1 : 12,
           : 5,
        a3 : 12;
    };
    
  7. Eğer bir sonraki sözcüğün başına atlamak istiyorsanız, araya 0 genişliğinde bir boş alan koyun. Örneğin, sistemimizde

    struct dnm {
      unsigned short
        a1 : 12,
           : 0,
        a3 : 12;
    };
    

    ile

    struct dnm {
      unsigned short
        a1 : 12,
           : 4,
        a3 : 12;
    };
    

    eşdeğerdir. Neden?

  8. Alanlar da tıpkı yapı üyeleri gibi ilklenebilirler, fakat alan için çok büyük olan bir değer vermemeye dikkat etmek gerekir.