Accéder à une valeur dans un champ de bits [C] - Programmation
Marsh Posté le 23-06-2001 à 21:18:57
il faut faire des masques
imaginons : xxx@ xxxx ton octet et tu souhaites recuperer @
et bien tu mets dans char A = (la valeur de ton octet);
A >> 4; 4 decalages vers la droite
puis tu fais un masque logique
A = A & 0x01;
tu retrouves dans A la valeur de @
Marsh Posté le 23-06-2001 à 21:50:59
Et si le champs est composé de plus de 8 bits? Comment fait-on? Pareil?
Marsh Posté le 23-06-2001 à 22:17:24
Et c'est quoi le nom anglais pour "champ de bits"? Que je puisse aller chercher sous Google un peu d'infos.
Marsh Posté le 23-06-2001 à 22:57:10
bitfield
A+,
Marsh Posté le 23-06-2001 à 23:09:25
C'est un peu la merde les champs de bits dès qu'on veut une grande quantité de bits...
N'y a-t-il pas moyen de gérer une plus grande quantité mémoire de la même manière?
Sinon quelle la taille d'une variable bool? Elle est pas spécifiée dans mon bouquin de C++.
Marsh Posté le 23-06-2001 à 23:43:46
sérieux, les vecteurs de bool
vector<bool>
c'est cool. C'est dans le standard C++ 1998 ansi et est implémenté entre autres dans gcc et Visual, et c'est un tableau de bits accessibles individuellement.
Marsh Posté le 23-06-2001 à 23:45:19
D'ailleurs, j'ai répondu dans un post d'il y qqes jours une classe de tableau Bidimensionnel de bool. Si tu veux, je peux tu filer un fichier .h avec le type défini et qui a plein de fonctions qui marchent bien.
Marsh Posté le 23-06-2001 à 23:52:55
Oui je veux bien, et en m'expliquant un peu comment ça marche, parce que dans mon bouquin de C++ ils en parlent même pas de vector... Honte sur eux...
Marsh Posté le 24-06-2001 à 00:17:25
alors voilà, c'est pas trop compliqué en fait. Un vector, c'est un peu comme un tableau, sauf qu'on se fait pas chier à l'allouer, ou à le désallouer, et y'a une implémentation pour les bool avec les bits côte à côte:
exemple:
#include <vector>
using namespace std;
void main
{
vector<bool> tabbits(100); //je crée un tableau de 100 bits;
for (int i=0; i<100;< i++)
tabbits[i]= (i%2==0); //j'y écris la parité par exemple
vector<bool> tabback=tabbits; //je fais un backup du tableau
tabbits.clear(); //pour effacer le contenu
for (int j=0; j<tabback.size(); j++)
cout << tabback[j] << ' '; //j'affiche le contenu!
}//tabbits est détruit (par le destructeur) et donc désalloué à la sortie du bloc;
Marsh Posté le 24-06-2001 à 00:20:04
Cool, ça a l'air bien ce <vector>, c'est un peu comme un champ de bits sans restriction de place et plus simple d'accès.
Par contre, on peut stocker quoi dedans? 1, 0 ou true, false?
Marsh Posté le 24-06-2001 à 00:24:28
Bon, je t'ai filé deux fichiers
BidimArray.h
et
BidimArrayImp.h
qui te serviront à faire des tableaux bidimensionnels de types de ton choix, des bits, des octets, des RGBA,....
C'est documenté dans le code, et si tu downloades
http://www.stack.nl/~dimitri/doxygen
le logiciel de doc C++ cool, tu pourras générer l'aide html de cette classe.
J'ai écrit cette classe en faisant bon usage de la STL (même si y'a des choses que je changerais aujourd'hui, mais j'insiste pour que tu essayes de piger ce que j'y fais, c'est pas trop dur, et ça t'évitera de buter contre des problèmes comme moi dans le passé.
N'hésite pas à aller voir mon site web
http://janos.boudet.free.fr/
sur le C++. Je le mets à jour régulièrement
/*!
\file BidimArray.h
\date 24/01/2001
\author Janos Boudet
\brief définit les vecteurs bidimensionnels avec une base d'opérateurs associés. Les Images notamment en seront et on pourra aussi faire des transformations en ondelettes avec. Les constructeurs par recopie (en fait ceux de vector<T> doivent se comporter admirablement
*/
#ifndef __BidimArray_hh__
#define __BidimArray_hh__
#ifdef _msvc
#include <vector>
using namespace std;
#else
#include <vector.h>
#endif
/*!
\class BidimArray
\Author Janos Boudet
\brief La classe de vecteur bidimensionnel. Les données sont rangées en x consécutifs
*/
template <class T>
class BidimArray: protected vector<T>
{
protected:
//!largeur
int w;
//! hauteur
int h;
public:
//! constructeur par défaut: Vecteur de 0x0 pixels
BidimArray();
/*!
\brief constructeur d'un vecteur de x*y valeurs
\param x largeur du vecteur à créer
\param y hauteur du vecteur à créer
*/
BidimArray(int x, int y);
/*!
\brief constructeur avec éventuellement conversion de type
\param other le modèle a partir duquel on construit
*/
template <class X>
BidimArray(const BidimArray<X> & other);
/*!
\brief accède à la valeur (x,y)
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
T & operator()(int x, int y);
/*!
\brief accède à la valeur (x,y) const
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
const T & operator ()(int x, int y) const;
/*!
\brief accède au ième pixel avec i=x+y*w
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
T & operator[](int i);
/*!
\brief accède au ième pixel avec i=x+y*w const
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
const T & operator[](int i) const;
/*!
\brief lit la largeur
\return la largeur du vecteur
*/
int GetW() const;
/*!
\brief lit la hauteur
\return la hauteur du vecteur
*/
int GetH() const;
/*!
\brief impose une valeur constante à tout le vecteur
\param value la valeur constante à donner à tout le vecteur
*/
void SetConstantValue(const T & value);
/*!
\brief Copie une portion rectangulaire du vecteur
\param x la plus petite abscisse du rectangle à copier
\param y la plus petite ordonnée du rectangle à copier
\param dx largeur du vecteur à copier
\param dy hauteur du vecteur à copier
\return le rectangle copié
*/
BidimArray<T> Copy(int x=0, int y=0, int dx=0, int dy=0) const;
/*!
\brief insère un vecteur dans le vecteur courant
\param other le vecteur à insérer
\param x abscisse de l'insertion
\param y ordonnée de l'insertion
\renvoit l'image courante ainsi modifiée
*/
BidimArray<T> & Paste(const BidimArray<T> & other, int x, int y);
/*!
\brief opérateur ==
\param other vecteur auquel comparer (tous les éléments et la taille)
\return true ou false
*/
bool operator == (const BidimArray<T> & other);
/*!
\brief envoit l'exception length_error correctement formatée en cas de différence de taille
\param other vecteur auquel comparer
*/
void TestSizeMatch(const BidimArray<T> & other) const;
/*!
\brief met le vecteur à une taille de 0x0 (et au passage libère la mémoire)
*/
void Clear();
/*!
\brief redimensionne le vecteur à une nouvelle taille. L'état des données à la sortie doit être considéré comme indéfini
\param x nouvelle largeur
\param y nouvelle hauteur
*/
void BruteResize(int x, int y);
/*!
\brief écrit une ligne dans l'image. NB la ligne doit avoir une longueur égale à w
\param line la ligne à écrire
\param y quelle ligne remplacer
*/
void WriteLine(const vector<T> & line, int y);
/*!
\brief écrit une colonne dans l'image. NB la colonne doit avoir une hauteur égale à h
\param column la colonne à écrire
\param x quelle colonne remplacer
*/
void WriteColumn(const vector<T> & column, int x);
/*!
\brief lit une ligne dans l'image.
\param y quelle ligne lire
\return la ligne lue
*/
vector<T> ReadLine(int y) const;
/*!
\brief lit une colonne dans l'image.
\param x quelle colonne lire
\return la colonne lue
*/
vector<T> ReadColumn(int x) const;
};
#include "BidimArrayImp.h"
#endif //__BidimArray_hh__
***************************
****************************
*****************************
******************************
******************************
/*!
\file BidimArrayImp.h
\Author Janos Boudet
\date 24/01/2001
\brief implémentation du vecteur bidimentionnel
*/
#include "BidimArray.h"
#include <assert.h>
#ifdef _msvc
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _linux
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _sgi
#include <stdexcept.h>
#include <strstream.h>
#endif
#ifdef DEBUG
//#define BIDIM_ARRAY_RANGE_TEST
#endif
template <class T>
BidimArray<T>::BidimArray(): vector<T>(0), w(0), h(0)
{
//nothing
}
template <class T>
BidimArray<T>::BidimArray(int x, int y): w(x), h(y), vector<T>(x*y)
{
if (w<0)
{
strstream errmsg;
errmsg<<"w="<<w<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
if (h<0)
{
strstream errmsg;
errmsg<<"h="<<h<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
//on voit bien que l'on aura pas les deux
}
#ifdef _msvc
template <class X, class T>
#else
template <class T>
template <class X>
#endif
BidimArray<T>::BidimArray(const BidimArray<X> & other): w(other.GetW()), h(other.GetH())
{
for (int i=0; i<w*h; i++)
operator[](i)=other[i];
}
/*
NB: il faudrait remplacer tous les strstream par des stringstreams, mais un comportement
bizarre de la STL qui m'interdit ente autres d'inclure les fichiers .h sans le .h et de taper
-LANG:std dans les options de compilation, m'oblige à prendre des strstreams, moins propres
plutôt que des stringstreams.
lors du portage il serait propre de régler cela
*/
template <class T>
inline T & BidimArray<T>::operator()(int x, int y)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline const T & BidimArray<T>::operator()(int x, int y) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline T & BidimArray<T>::operator[](int i)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline const T & BidimArray<T>::operator[](int i) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline int BidimArray<T>::GetW() const
{
return w;
}
template <class T>
inline int BidimArray<T>::GetH() const
{
return h;
}
template <class T>
void BidimArray<T>::SetConstantValue(const T & value)
{
fill(begin(), end(), value);
}
template <class T>
BidimArray<T> BidimArray<T>::Copy(int x, int y, int dx, int dy) const
{
assert(x>0);
assert(y>0);
assert(dx>0);
assert(dy>0);
assert(x+dx<=w);
assert(y+dy<=h);
//test
//if(x<0)
// throw(out_of_range((stringstream("x out of range : " )<<x<<"!E["<<0<<", "<<w<<"]);
BidimArray<T> newimage(dx,dy);
for (int j=0; j<dy; j++)
for (int i=0; i<dx; i++)
newimage(i,j)=operator()(i+x, j+y);
return newimage;
}
template <class T>
BidimArray<T> & BidimArray<T>::Paste(const BidimArray<T> & other, int x, int y)
{
assert(x>0);
assert(y>0);
assert(x+other.w<=w);
assert(y+other.h<=h);
for (int j=0; j<other.h; j++)
for (int i=0; i<other.w; i++)
operator()(i+x,j+y)=other(i,j);
return *this;
}
template <class T>
bool BidimArray<T>::operator == (const BidimArray<T> & other)
{
if (w!=other.w)
return false;
//if (h!=other.h)
//return false //on ne le fait pas car c'est redondant avec le test suivant
return vector<T>::operator==(other);
}
template <class T>
inline void BidimArray<T>::TestSizeMatch(const BidimArray<T> & other) const
{
if (w!=other.w || h!=other.h)
{
strstream s; //mettre stringstream quand ça bugge pas
s<<"Size mismatch : "<<w<<"x"<<h<<"!="<<other.w<<"x"<<other.h<<
endl;
throw(length_error(s.str()));
}
}
template <class T>
void BidimArray<T>::Clear()
{
BruteResize(0,0);
}
template <class T>
void BidimArray<T>::BruteResize(int x, int y)
{
w=x;
h=y;
resize(x*y);
}
template <class T>
void BidimArray<T>::WriteLine(const vector<T> & line, int y)
{
int wr=y*w;
for (int i=0; i<w; i++, wr++)
operator[](wr)=line[i];
}
template <class T>
void BidimArray<T>::WriteColumn(const vector<T> & column, int x)
{
int wr=x;
for (int i=0; i<h; i++, wr+=w)
operator[](wr)=column[i];
}
template <class T>
vector<T> BidimArray<T>::ReadLine(int y) const
{
int rd=y*w;
vector<T> line(w);
for (int i=0; i<w; i++, rd++)
line[i]=operator[](rd);
return line;
}
template <class T>
vector<T> BidimArray<T>::ReadColumn(int x) const
{
int rd=x;
vector<T> column(h);
for (int i=0; i<h; i++, rd+=w)
column[i]=operator[](rd);
return column;
}
Marsh Posté le 24-06-2001 à 00:25:22
Repost mais sans les smileys:
Bon, je t'ai filé deux fichiers
BidimArray.h
et
BidimArrayImp.h
qui te serviront à faire des tableaux bidimensionnels de types de ton choix, des bits, des octets, des RGBA,....
C'est documenté dans le code, et si tu downloades
http://www.stack.nl/~dimitri/doxygen
le logiciel de doc C++ cool, tu pourras générer l'aide html de cette classe.
J'ai écrit cette classe en faisant bon usage de la STL (même si y'a des choses que je changerais aujourd'hui, mais j'insiste pour que tu essayes de piger ce que j'y fais, c'est pas trop dur, et ça t'évitera de buter contre des problèmes comme moi dans le passé.
N'hésite pas à aller voir mon site web
http://janos.boudet.free.fr/
sur le C++. Je le mets à jour régulièrement
/*!
\file BidimArray.h
\date 24/01/2001
\author Janos Boudet
\brief définit les vecteurs bidimensionnels avec une base d'opérateurs associés. Les Images notamment en seront et on pourra aussi faire des transformations en ondelettes avec. Les constructeurs par recopie (en fait ceux de vector<T> doivent se comporter admirablement
*/
#ifndef __BidimArray_hh__
#define __BidimArray_hh__
#ifdef _msvc
#include <vector>
using namespace std;
#else
#include <vector.h>
#endif
/*!
\class BidimArray
\Author Janos Boudet
\brief La classe de vecteur bidimensionnel. Les données sont rangées en x consécutifs
*/
template <class T>
class BidimArray: protected vector<T>
{
protected:
//!largeur
int w;
//! hauteur
int h;
public:
//! constructeur par défaut: Vecteur de 0x0 pixels
BidimArray();
/*!
\brief constructeur d'un vecteur de x*y valeurs
\param x largeur du vecteur à créer
\param y hauteur du vecteur à créer
*/
BidimArray(int x, int y);
/*!
\brief constructeur avec éventuellement conversion de type
\param other le modèle a partir duquel on construit
*/
template <class X>
BidimArray(const BidimArray<X> & other);
/*!
\brief accède à la valeur (x,y)
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
T & operator()(int x, int y);
/*!
\brief accède à la valeur (x,y) const
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
const T & operator ()(int x, int y) const;
/*!
\brief accède au ième pixel avec i=x+y*w
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
T & operator[](int i);
/*!
\brief accède au ième pixel avec i=x+y*w const
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
const T & operator[](int i) const;
/*!
\brief lit la largeur
\return la largeur du vecteur
*/
int GetW() const;
/*!
\brief lit la hauteur
\return la hauteur du vecteur
*/
int GetH() const;
/*!
\brief impose une valeur constante à tout le vecteur
\param value la valeur constante à donner à tout le vecteur
*/
void SetConstantValue(const T & value);
/*!
\brief Copie une portion rectangulaire du vecteur
\param x la plus petite abscisse du rectangle à copier
\param y la plus petite ordonnée du rectangle à copier
\param dx largeur du vecteur à copier
\param dy hauteur du vecteur à copier
\return le rectangle copié
*/
BidimArray<T> Copy(int x=0, int y=0, int dx=0, int dy=0) const;
/*!
\brief insère un vecteur dans le vecteur courant
\param other le vecteur à insérer
\param x abscisse de l'insertion
\param y ordonnée de l'insertion
\renvoit l'image courante ainsi modifiée
*/
BidimArray<T> & Paste(const BidimArray<T> & other, int x, int y);
/*!
\brief opérateur ==
\param other vecteur auquel comparer (tous les éléments et la taille)
\return true ou false
*/
bool operator == (const BidimArray<T> & other);
/*!
\brief envoit l'exception length_error correctement formatée en cas de différence de taille
\param other vecteur auquel comparer
*/
void TestSizeMatch(const BidimArray<T> & other) const;
/*!
\brief met le vecteur à une taille de 0x0 (et au passage libère la mémoire)
*/
void Clear();
/*!
\brief redimensionne le vecteur à une nouvelle taille. L'état des données à la sortie doit être considéré comme indéfini
\param x nouvelle largeur
\param y nouvelle hauteur
*/
void BruteResize(int x, int y);
/*!
\brief écrit une ligne dans l'image. NB la ligne doit avoir une longueur égale à w
\param line la ligne à écrire
\param y quelle ligne remplacer
*/
void WriteLine(const vector<T> & line, int y);
/*!
\brief écrit une colonne dans l'image. NB la colonne doit avoir une hauteur égale à h
\param column la colonne à écrire
\param x quelle colonne remplacer
*/
void WriteColumn(const vector<T> & column, int x);
/*!
\brief lit une ligne dans l'image.
\param y quelle ligne lire
\return la ligne lue
*/
vector<T> ReadLine(int y) const;
/*!
\brief lit une colonne dans l'image.
\param x quelle colonne lire
\return la colonne lue
*/
vector<T> ReadColumn(int x) const;
};
#include "BidimArrayImp.h"
#endif //__BidimArray_hh__
***************************
****************************
*****************************
******************************
******************************
/*!
\file BidimArrayImp.h
\Author Janos Boudet
\date 24/01/2001
\brief implémentation du vecteur bidimentionnel
*/
#include "BidimArray.h"
#include <assert.h>
#ifdef _msvc
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _linux
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _sgi
#include <stdexcept.h>
#include <strstream.h>
#endif
#ifdef DEBUG
//#define BIDIM_ARRAY_RANGE_TEST
#endif
template <class T>
BidimArray<T>::BidimArray(): vector<T>(0), w(0), h(0)
{
//nothing
}
template <class T>
BidimArray<T>::BidimArray(int x, int y): w(x), h(y), vector<T>(x*y)
{
if (w<0)
{
strstream errmsg;
errmsg<<"w="<<w<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
if (h<0)
{
strstream errmsg;
errmsg<<"h="<<h<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
//on voit bien que l'on aura pas les deux
}
#ifdef _msvc
template <class X, class T>
#else
template <class T>
template <class X>
#endif
BidimArray<T>::BidimArray(const BidimArray<X> & other): w(other.GetW()), h(other.GetH())
{
for (int i=0; i<w*h; i++)
operator[](i)=other[i];
}
/*
NB: il faudrait remplacer tous les strstream par des stringstreams, mais un comportement
bizarre de la STL qui m'interdit ente autres d'inclure les fichiers .h sans le .h et de taper
-LANG:std dans les options de compilation, m'oblige à prendre des strstreams, moins propres
plutôt que des stringstreams.
lors du portage il serait propre de régler cela
*/
template <class T>
inline T & BidimArray<T>::operator()(int x, int y)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline const T & BidimArray<T>::operator()(int x, int y) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline T & BidimArray<T>::operator[](int i)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline const T & BidimArray<T>::operator[](int i) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline int BidimArray<T>::GetW() const
{
return w;
}
template <class T>
inline int BidimArray<T>::GetH() const
{
return h;
}
template <class T>
void BidimArray<T>::SetConstantValue(const T & value)
{
fill(begin(), end(), value);
}
template <class T>
BidimArray<T> BidimArray<T>::Copy(int x, int y, int dx, int dy) const
{
assert(x>0);
assert(y>0);
assert(dx>0);
assert(dy>0);
assert(x+dx<=w);
assert(y+dy<=h);
//test
//if(x<0)
// throw(out_of_range((stringstream("x out of range : " )<<x<<"!E["<<0<<", "<<w<<"]);
BidimArray<T> newimage(dx,dy);
for (int j=0; j<dy; j++)
for (int i=0; i<dx; i++)
newimage(i,j)=operator()(i+x, j+y);
return newimage;
}
template <class T>
BidimArray<T> & BidimArray<T>::Paste(const BidimArray<T> & other, int x, int y)
{
assert(x>0);
assert(y>0);
assert(x+other.w<=w);
assert(y+other.h<=h);
for (int j=0; j<other.h; j++)
for (int i=0; i<other.w; i++)
operator()(i+x,j+y)=other(i,j);
return *this;
}
template <class T>
bool BidimArray<T>::operator == (const BidimArray<T> & other)
{
if (w!=other.w)
return false;
//if (h!=other.h)
//return false //on ne le fait pas car c'est redondant avec le test suivant
return vector<T>::operator==(other);
}
template <class T>
inline void BidimArray<T>::TestSizeMatch(const BidimArray<T> & other) const
{
if (w!=other.w || h!=other.h)
{
strstream s; //mettre stringstream quand ça bugge pas
s<<"Size mismatch : "<<w<<"x"<<h<<"!="<<other.w<<"x"<<other.h<<
endl;
throw(length_error(s.str()));
}
}
template <class T>
void BidimArray<T>::Clear()
{
BruteResize(0,0);
}
template <class T>
void BidimArray<T>::BruteResize(int x, int y)
{
w=x;
h=y;
resize(x*y);
}
template <class T>
void BidimArray<T>::WriteLine(const vector<T> & line, int y)
{
int wr=y*w;
for (int i=0; i<w; i++, wr++)
operator[](wr)=line[i];
}
template <class T>
void BidimArray<T>::WriteColumn(const vector<T> & column, int x)
{
int wr=x;
for (int i=0; i<h; i++, wr+=w)
operator[](wr)=column[i];
}
template <class T>
vector<T> BidimArray<T>::ReadLine(int y) const
{
int rd=y*w;
vector<T> line(w);
for (int i=0; i<w; i++, rd++)
line[i]=operator[](rd);
return line;
}
template <class T>
vector<T> BidimArray<T>::ReadColumn(int x) const
{
int rd=x;
vector<T> column(h);
for (int i=0; i<h; i++, rd+=w)
column[i]=operator[](rd);
return column;
}
Marsh Posté le 23-06-2001 à 20:04:43
Je viens de voir qu'on pouvait créer des champs de bits afin de gagner de la place mémoire.
Mais si je veux créer un champ de width*height bits, je l'initialise de cette façon:
int champ : (width*heigh)
Mais une fois initalisé, comment j'accède par exemple à l'état du bit (x+y*width)? Et d'ailleurs comment je décide de l'état du bit (x+y*width)?