PDA

Tam Sürümünü Görmek İçin : bool degiskeni


ceeyt
09/09/2004, 03:57
Herkese merhabalar...


Bildigim kadariyla bool degiskenleri hafizaya yerlestirilirken ilgili hafiza hucresini olusturan bitlere rasgele erisim saglanamiyor.Buna gore ben bool degiskenlerden olusan bir dizi (vektor icinde benzer bir durum gecerlidir sanirim) olusturdugumda bool degiskenler sekizli gruplar halinde bellege yazilacaktir.

Dizide yapilacak islemlerin bir isaretci ile yapildigini dusunelim.Ornek olarak isaretci dizinin herhangi bir elemaninin adresini alsin.Gosterge bir bite isaret edemeyeceginden,isaret ettigi adres aslinda sekizli grubun adresi olacak.

Yanlis mi biliyorum ? Eger dogruysa ; bool degiskenleden olusan bir dizi veya vektoru kullanabilmek icin kendim bir yapi mi olusturmaliyim ?


typedef struct {
bool b0_;
bool b1_;
...........
...........
...........
bool b7_;
} boolStruct;

vector<boolStruct> byteVals;

Belki tur donusumu kullanabilirim ama standartlar disindakilerde tasinabilirlik sorunu olabilir,bilinen bir turde ifade etsem bir bit le depolayabilecegim bir degisken icin cok alan kullanmis olurum.

Eminim mantikli bir cozumu ve aciklamasi vardir.Bu konu ile ilgili kullanisli cozumler onerebilir misiniz ? ( en guzel secenek yanlis bilmem ve bu kadar yazinin sacmaliktan ibaret olmasi sanirim :s008: :s008: :s008: )


anov
10/09/2004, 18:20
vector tanımlamayı bilmiyorum fakat bir bellek bölgesine bit olarak erişmek ve kurmak istiyorsan bunlar için bitwise operatörler en iyi çözüm olacaktır bence.
(bitwise and : & )
(bitwise or : | )
bir bellek bölgesinin 3. bitinin değerini öğrenmek için onu
00100000 ile bitwise and işlemine tabi tutarsan sonuc ya 00000000 ya da 00100000 olmalı and işleminin yutma özelliğinden dolayı
veya değiştirmek için de aynı yollar kullanılabilir.
dediklerimi denemedim yanımda derleyici var ama şimdi kim yazacak derleyecek uzun iş (no warranty :p)
iyi niyet ve yardım seninle olsun.

ceeyt
10/09/2004, 22:08
& , | operatorlerini kullanarak her bite erisebilirim ama bunun yerine yukarida yazdigimi kullansam daha kolay olur sanki :hiohahoha

senin dedigin gibi yaparsak ;


typedef struct {
bool b0_;
bool b1_;
...........
...........
...........
bool b7_;
} boolStruct;

class bools {
friend
std::ostream &operator<<(std::ostream &output,bools b)

private:
std::vector<boolStruct> byteVals;
public:

/*
................
*/
};

std::ostream &operator<<(std::ostream &output,bools b)
{
vector<boolStruct> *p = new vector<boolStruct>( );
p=v.begin( );

while(p!=v.end() )
{
output << (*p& 0x00h) << '\t'
<< (*p& 0x01h) << '\t'
<< ..................
<< ..................
<< '\t' << '\t' ;
++p;
}
delete p;
return output;
}

gibisinden birseye gerek olur sanirim.

Derleyicim yok ( zaten olsa sorunu cozmek icin bir seyler yapmaya calisirim ama... bir kac gun daha bu haldeyim :aglama: :aglama: :aglama: )
umarim hatalarla dolu degildir.

Daha kolay bir sey yok mu ?
Hic gerek yok mu boyle bir seye?

Dogrudan vector<bool> bVec kullanabiliyor muyum?
Bu durumda her ilk basta bahsettigim sorunlar olmaz mi?
Bunu engellemek icin kolay birseyler yok mudur?


derleyicisinden ayrı kalmaz zor is :tamams:

acehreli
13/09/2004, 23:59
ceeyt, vector<bool> istedigin gibi bit erisimi saglar ve bool icin ozel olarak gerceklenmistir. Gonul rahatligiyla kullanabilirsin. :)


#include <vector>
#include <iostream>

typedef std::vector<bool> Bitler;

int main()
{
Bitler bitler(11);
bitler[3] = true;
std::cout << bitler[0] << ' ' << bitler[3] << '\n';
}


Ali

entegre78
02/10/2004, 01:36
Aranılan çözüm
ya arkadaşlar c++ yazacağınıza ilk önce bir c yi öğrenin derim ben size
sanırım arkadaşımız yer tasarrufu yapmak istiyor.
struct versiyon
{
unsigned int yuksekver:8; //ilk sekiz bit
unsigned int dusukver:8; // ikinci sekiz bit
unsigned int bos:15; // sonraki 15 bit
unsigned int ortam:1; // 32 inci 1 bit
};

typedef struct
{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
}boolstruct; //bellekte bir byte yer tutar

sizeof(boolstruct); ile bakabilirsin.
kullanımı da oldukça basit
boolstruct bilgi;
bilgi.b2=0;
bilgi.b2=1;

entegre78
02/10/2004, 01:55
ceeyt, vector<bool> istedigin gibi bit erisimi saglar ve bool icin ozel olarak gerceklenmistir. Gonul rahatligiyla kullanabilirsin. :)


#include <vector>
#include <iostream>

typedef std::vector<bool> Bitler;

int main()
{
Bitler bitler(11);
bitler[3] = true;
std::cout << bitler[0] << ' ' << bitler[3] << '\n';
}


Ali
bunun bit erişimi sağladığı konusunda hem fikir değilim
sizeof(bitler);
sizeof(bitler[1]);

ceeyt
02/10/2004, 02:51
Aslında amacim yer tasarrufu saglamak degildi. Bir sure derleyicisiz kalmistim ( cok zor gunlerdi :) ) bu sirada aklima bool veri tipinin std::vector le beraber kullanimiyla ilgili bir seyler takildi.

Bu nedenle
typedef struct
{
unsigned char b0:1;
..................
..................
unsigned char b8:1;
}boolstruct; gibi birsey kullanmayi dusunmedim.

bu arada ;
- yazi sekli goze hic hos gelmiyor
- vector<bool> bitler ise yariyor ( bellekte dizilis olarak dusunme )
- C bilmedigimi nerden cikardin

sagolsun arkadaslar yadimci oldular,sen de sagol...

entegre78
02/10/2004, 03:17
...
Herkese merhabalar...


Bildigim kadariyla bool degiskenleri hafizaya yerlestirilirken ilgili hafiza hucresini olusturan bitlere rasgele erisim saglanamiyor.Buna gore ben bool degiskenlerden olusan bir dizi (vektor icinde benzer bir durum gecerlidir sanirim) olusturdugumda bool degiskenler sekizli gruplar halinde bellege yazilacaktir.

Dizide yapilacak islemlerin bir isaretci ile yapildigini dusunelim.Ornek olarak isaretci dizinin herhangi bir elemaninin adresini alsin.Gosterge bir bite isaret edemeyeceginden,isaret ettigi adres aslinda sekizli grubun adresi olacak.

Yanlis mi biliyorum ? Eger dogruysa ; bool degiskenleden olusan bir dizi veya vektoru kullanabilmek icin kendim bir yapi mi olusturmaliyim ?


typedef struct {
bool b0_;
bool b1_;
...........
...........
...........
bool b7_;
} boolStruct;

vector<boolStruct> byteVals;

Belki tur donusumu kullanabilirim ama standartlar disindakilerde tasinabilirlik sorunu olabilir,bilinen bir turde ifade etsem bir bit le depolayabilecegim bir degisken icin cok alan kullanmis olurum.
Eminim mantikli bir cozumu ve aciklamasi vardir.Bu konu ile ilgili kullanisli cozumler onerebilir misiniz ? ( en guzel secenek yanlis bilmem ve bu kadar yazinin sacmaliktan ibaret olmasi sanirim :s008: :s008: :s008: )

ceeyt
02/10/2004, 03:57
ustundeki satir :
tasinabilirlik sorunu olabilir

Sanirim tur donusumu diyerek yanlis ifade etmisim,

typedef struct
{
unsigned char b0:1;
..................
..................
unsigned char b8:1;
}boolstruct;

kullaniminindan soz etmeye calismistim.Bu kullanimda tasinabilirlik sorunlari olmaz mi ?

acehreli
05/10/2004, 01:02
entegre78,

C ogrenme ile ilgili onerin icin tesekkurler. Hep birlikte ogreniyoruz zaten degil mi...

C'de bit alanlarinin gerceklenmesi uygulamaya birakilmistir. sizeof'un verdigi guven, baska derleyiciler ve/veya ortamlarda yaniltici olabilir. Ornegin bitlerin baytlara hangi sirada yerlestirildiklerinden ve/veya hangi aralara ne kadar sayida doldurma biti eklendiginden emin olamazsin.

vector<bool> bit erisimi saglar. vector<bool>, vector sablonunun ozel bir halidir ve bitlerle kullanilmak icin tasarlanmistir. Derleyici ve/veya ortam degisikliklerinden etkilenmez, arayuzu C++ standardi tarafindan belirlenmistir.

Bitlerin adresleri olmadigi icin, senin de soyledigin gibi, vector<bool> bitlere adreslerini kullanarak erisim saglayamaz. (Bunu C'den gelen bit alanlari da yapamazlar ama...)

Ancak, C++'in siniflarini kullanarak BitAdresi gibi bir sinif yazabiliriz. Onu sanki bir biti adresliyor gibi kullanabiliriz:


unsigned int * bitler = /* ... */;
size_t kacinci = 3;

BitAdresi adres(bitler, kacinci);

// Ondan sonra bu nesneleri sanki bir adres gibi kullanabiliriz:

cout << (*adres);
*adres = true;


Bunu yapmak icin, BitAdresi icin operator* islecini tanimlar ve mutlu mutlu kodlariz.

sizeof(bitler) ve sizeof(bitler[1]) ile neden ilgilendigini anlayamadim. sizeof(vector<HerHangiBirTur>), vector icinde ne kadar cok oge olursa olsun, hep kucuk bir sayi verecektir. Bunun nedeni, icinde asil veriyi gosteren bir gostericisi olmasidir. Ornegin:


template <class T>
class vector
{
size_t toplamOge_;
T * ogeler_;

/* ... */
};


Boyle bir gerceklemede sizeof(vector<HerHangiBirTur>), 32-bitlik bir ortamda her zaman icin herhalde 8 olacaktir.

boolStruct ile ilgili sordugun sorunun yaniti: Hayir, senin boyle bir yapi yazmana gerek yok. O isi vector<bool> zaten yapiyor.

Ali

acehreli
05/10/2004, 02:28
Selamlar,

Daha once bahsettigim BitAdresi gibi bir sinif yazdim. Su anda elimin altinda cok eski bir derleyici oldugu icin BitAdresi'ni std::iterator'in alt sinifi olarak derleyemedim. (Belki de ben bir yerde bir hata yapmisimdir.)

Yani aslinda


class BitAdresi : public iterator<forward_iterator_tag, bool, ptrdiff_t, bool *, bool &>
{
/* ... */
};


yazabilseydim, BitAdresi sinifini standart islevlerle de kullanabilirdim. Ornegin


copy(bitler.basi(), bitler.sonu, ostream_iterator<bool>(cout, "\n"));


gibi kullanabilirdim.

Asagidaki kodu fazlaca denemeden gonderiyorum. Mutlaka hatalari vardir...


#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

class BitAdresi
{
unsigned int * adres_;
size_t kacinci_;

public:

BitAdresi(unsigned int * adres, size_t kacinci)
:
adres_(adres),
kacinci_(kacinci)
{}

bool operator* ()
{
return (*adres_) & (1 << kacinci_);
}

BitAdresi & operator++ ()
{
if (++kacinci_ == CHAR_BIT)
{
++adres_;
kacinci_ = 0;
}

return *this;
}

bool operator!= (BitAdresi const & diger) const
{
return ((adres_ != diger.adres_) ||
(kacinci_ != diger.kacinci_));
}
};

class BitDeposu
{
vector<unsigned int> bitler_;
size_t toplamBit_;

public:

BitDeposu()
:
toplamBit_(0)
{}

void ekle(bool deger)
{
size_t const kacinci = toplamBit_ % CHAR_BIT;

if (kacinci == 0)
{
bitler_.push_back(0);
}

if (deger) bitler_.back() |= (1 << kacinci);

++toplamBit_;
}

BitAdresi basi()
{
return BitAdresi(&bitler_[0], 0);
}

BitAdresi sonu()
{
size_t const kacinci = toplamBit_ % CHAR_BIT;
unsigned int * sonAdres = (&bitler_[0]) + (toplamBit_ / CHAR_BIT);

// Tanim geregi, sonuncudan sonraki varolmayan nesneyi
// gosteriyor:
return BitAdresi(sonAdres, kacinci);
}

void bilgiVer(ostream & cikis) const
{
cikis << toplamBit_ << " tane bit "
<< bitler_.size() << " adreste tutuluyorlar\n";
}
};

int main()
{
BitDeposu bitler;

for (int i = 0; i != 13; ++i)
{
bitler.ekle(i % 3);
}

bitler.bilgiVer(cout);

size_t kacinci = 0;
for (BitAdresi it = bitler.basi(); it != bitler.sonu(); ++it, ++kacinci)
{
cout << kacinci << ": " << *it << '\n';
}
}


Ali