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 yil : 7;
  unsigned  ay : 4;
  unsigned 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 unsigned bir tamsayı olmalıdır. Standart, en azından unsigned int’in desteklenmesini gerektirir.
  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 ve int için 16, long için 32 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 a1 : 12;
      unsigned a2 : 5;
      unsigned a3 : 12;
    };
    

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

    12 bit a1, 4 bit kullanılmıyor (ilk 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 yerine unsigned long 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 long 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ı kullanmayı düşünmüyorsanız—örneğin yukarıdaki örnekte a2’yi—tipi ve alan ismini atlayın. Örneğin,

    struct dnm {
      unsigned a1 : 12;
                  : 5;
      unsigned 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 a1 : 12;
                  : 0;
      unsigned a3 : 12;
    };
    

    ile

    struct dnm {
      unsigned a1 : 12;
                  : 4;
      unsigned 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.