Bitfield olanağını C veya C++'tan biliyor musun? Temel türlerden daha alt düzeyde değişkenler tanımlamaya yararlar. Uyduruk bir örnek olarak, 16 bitlik bir türün alt 10 biti bir sayaç olur, üst 6 biti de üçer üçer başka kavramlar. Yani tek değişken alt alanlara ayrılır:
'
Bit: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Alan: | yazı | kağıt | harf |
| rengi | rengi | adedi |
'
Çok uyduruk oldu ama üçü bir arada şunu temsil ediyorlar: bir metinde kullanılan yazının bundan sonra kaç harfinin hangi yazı rengiyle ve hangi kağıt (arka plan) rengiyle yazdırılacağı.
Günümüzde böyle alanları tek değişkene sıkıştırmaya pek gerek olmuyor ama IP başlık dosyalarında bir sürü bir kaç bitlik alan da vardır:
http://en.wikipedia.org/wiki/IPv4#Header
Orada IP paketlerinin başlığında nasıl bir kaç bitlik veriler olduğu görülüyor. Örneğin 'version' 0'dan 3'üncü bite kadar bir alana yazıldığından 4 bitten oluşuyor. (Bu da toplam 16 sürüm değeri olabileceğini gösterir.)
İşte, bit alanları C ve C++'ta bitfield yazımı ile tanımlanır:
#include <stdio.h>
// C kodu
struct MetinRengi
{
unsigned short yazi_rengi : 3;
unsigned short kagit_rengi : 3;
unsigned short harf_adedi : 10;
};
typedef struct MetinRengi MetinRengi;
int main()
{
MetinRengi mr = { 1, 2, 3 };
printf("Buyuklugu %zu bit olan degiskene 3 alan sigdirdik.\n",
sizeof(MetinRengi) * 8);
}
Çıktısı:
'Buyuklugu 16 bit olan degiskene 3 alan sigdirdik.'
Ancak, C ve C++ standartları bit alanları fazla gevşek tutarlar. Derleyici alanların sıralarını değiştirebilir, aralara gerek gördüğü gibi boşluklar ekleyebilir, vs.
Zafer'in gösterdiği 'bitfields' D'nin gücünü gösteren çok güzel bir örnek. Bit alanları D'de dil olanağı olmak zorunda değiller, bir kütüphane ile bile gerçekleştirilebiliyorlar. Sonuçta türün o isimde üyeleri oluveriyor.
Alıntı (zafer):
> BenimSayim yapısının içinde sayi isimli uint bir değişken var
Ama senin örneğinde onun diğerleriyle ilgisi yok. Belki BenimSayim'ın bütün üyelerini union içine alsaydın bit alanlarının sayi'nin hangi bitlerine karşılık geldiklerini görebilirdin.
Alıntı:
> ve biz bitfields şablonunu kullanarak bu sayının bitlerini kendimize göre özelleştiriyoruz. Şöyle bir deneme yaptım;
Ben onları union yaparak bit alanlarını sayi'nin içinde şöyle göstereceğim:
import std.stdio;
import std.bitmanip;
struct BenimSayim
{
union // <-- Ali ekledi
{
uint sayi;
mixin(bitfields!(uint, "bos", 16, // Türlerini de uint yapmam
uint, "pay", 8, // gerekti. Zaten bitlerle
uint, "payda", 8)); // uğraşırken en mantıklısı odur.
}
}
void main()
{
BenimSayim testSayi;
testSayi.pay = 0xff; // pay'ın bütün bitleri 1
testSayi.payda = 0xaa; // payda'nın bitleri 0, 1, 0, 1 diye gidiyor
writefln("%b", testSayi.sayi); // sayi'yi yazdırıyoruz
}
Çıktısı:
'10101010111111110000000000000000'
Yani 'bitfields', üyeleri asıl türün içine ters sırada yerleştiriyormuş.
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]