Rechercher : dans
Par :

[C++] static bool tableau[13][4]

Dernière réponse le 17 sep 2008 à 13:13:33 zzzer, le 16 sep 2008 à 14:34:42 
 Signaler ce message aux modérateurs

Bonjour,


J'ai une classe carte, dans laquelle j'ai un tableau statique bidimensionnel.

Etant donné qu'il est privé, j'ai fait une méthode reinitialiseTableau() qui est censée mettre toutes les valeurs du tableau à false.

Cependant, voici l'erreur qu'il me retourne lorsque j'essaye de compiler (dejaUtilisees est le nom de mon tableau) :

undefined reference to `carte::dejaUtilisees'
Voici ma classe (carte.h) :
class carte
{
    private :
        ...
        static bool dejaUtilisees[13][4]; // nombre, couleur

    public :

        ...
        static void reinitialiseTableau()
        {
            for (int i=0 ; i<13 ; i++)
                for  (int j=0 ; j<4 ; j++)
                    carte::dejaUtilisees[i][j] = false;
        }
};

Ainsi, dans mon main (main.cpp), je pensais pouvoir appeller simplement la méthode de cette façon :
carte::reinitialiseTableau();
Mais ça ne lui plaît pas...
Quelqu'un pourrait m'aider ?

Merci d'avance !

N'oubliez pas de marquer la discussion comme résolue dès que c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 
Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS
Configuration: Windows XP
Internet Explorer 7.0

Meilleures réponses pour « [C++] static bool tableau[13][4] » dans :
Décaler les éléments d'un tableau (Rotation) -Récursivité- VoirVoici une procédure récursive qui permet de décaler tous les éléments d’un tableau d’une position à droite à partir de la position p Procedure Decaler (Var t : Tab; p, n : integer); Begin If p
Les structures en langage C VoirDifférence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de...
Langage C - Les chaînes de caractères VoirQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C, une chaîne...
Langage C - Les tableaux VoirType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes...

1

mamiemando, le 16 sep 2008 à 14:56:36

En fait je ne comprends pas pourquoi tu utilises des static et pourquoi ta classe s'appelle carte alors qu'en fait un carte_manager_t serait plus approprié.

Du coup plus besoin de static tu instancies un carte_manager_t et autant de carte_t que tu veux.

Bonne chance

Répondre à mamiemando

2

zzzer, le 16 sep 2008 à 15:02:43

Je ne connais manager_t... (je suis en DUT Info et on ne nous en a jamais parlé)

En fait, je veux faire un jeu de poker, donc il faut que je sache quelle carte a déjà été utillisée ou non.
Donc si dejaUtilisees[12][1] est à true, alors la dame de coeur sera déjà sortie...

N'oubliez pas de marquer la discussion comme résolue dès que­ c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

3

Char Snipeur, le 16 sep 2008 à 17:23:33

Salut.
En effet, je trouve ça étrange d'utiliser des static, mais bon...
Toujours est il que ça devrait fonctionner.
Que veux tu dire par "ça ne lui plait pas" ? Salutation ! avant je croyais, maintenant je suis fixé.Jésus Christ
Char Snipeur

Répondre à Char Snipeur

4

zzzer, le 16 sep 2008 à 21:15:36

Eh bien, il me retourne l'erreur

undefined reference to `carte::dejaUtilisees'
lorsque j'essaye de le compiler...

N'oubliez pas de marquer la discussion comme résolue dès que­ c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 
Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

6

zzzer, le 16 sep 2008 à 23:26:23

Eh bien, il me retourne l'erreur undefined reference to `carte::dejaUtilisees' lorsque j'essaye de le compiler...

N'oubliez pas de marquer la discussion comme résolue dès que­ c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

7

zzzer, le 16 sep 2008 à 23:51:47

Il me retourne l'erreur undefined reference to `carte::dejaUtilisees' lorsque j'essaye de le compiler...

N'oubliez pas de marquer la discussion comme résolue dès que­ c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

11

zzzer, le 17 sep 2008 à 07:32:12

Ça ne lui plaît pas car il ne passe pas à la compilation (erreur undefined reference to `carte::dejaUtilisees').

N'oubliez pas de marquer la discussion comme résolue dès que­ c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte : 

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

5

mamiemando, le 16 sep 2008 à 21:39:47

Je ne connais manager_t...

Encore heureux c'est moi qui te suggère un nom plus cohérent avec ce que fait la classe. Ici tu ne décris pas une carte, tu décris un objet qui gère un jeu de carte.

Ensuite bien de nommer ses types avec un suffixe distinctif (genre "_t"). En particulier, ça permet d'écrire "plop_t plop". On peut ainsi déduire le type à partir du nom de la variable. C'est mieux que de mettre un nom bidon (comme "plop p"). Enfin ça c'est un conseil de programmation.

Ensuite je maintiens que tu n'as aucune vraie bonne raison de faire des statics ici. Enfin tu peux le faire mais c'est une mauvaise structure de code je trouve. Je te propose d'utiliser plutôt une std::map pour gérer tes cartes.

#include <map>
#include <set>
#include <string>
#include <ostream>
#include <iostream>

typedef std::string couleur_t;
typedef std::string rang_t;
typedef std::set<couleur_t> couleurs_t;
typedef std::set<rang_t> rangs_t;

class carte_t{
	protected:
		rang_t rang;
		couleur_t couleur;
	public:
		carte_t(const rang_t & rang0,const couleur_t & couleur0):
			rang(rang0),couleur(couleur0)
		{}

		inline rang_t get_rang() const{
			return rang;
		}

		inline couleur_t get_couleur() const{
			return couleur;
		}
};

inline bool operator <(const carte_t & x,const carte_t & y){
	return x.get_rang() < y.get_rang() ||
		(x.get_rang() == y.get_rang() && x.get_couleur() < y.get_couleur());
}

inline bool operator==(const carte_t & x,const carte_t & y){
	return x.get_rang() == y.get_rang() && x.get_couleur() == y.get_couleur();
}
inline std::ostream & operator<<(std::ostream & out,const carte_t & c){
	out << c.get_rang() << " de " << c.get_couleur();
	return out;
}

class manager_t{
	public:
		typedef std::map<carte_t,bool> etat_t;
	protected:
		etat_t etat;
		couleurs_t couleurs;
		rangs_t rangs;
	public:
		manager_t(
			const couleurs_t & couleurs0,
			const rangs_t & rangs0
		):
			couleurs(couleurs0),
			rangs(rangs0)
		{
			init_manager();
		}

		inline void init_manager(){
			std::set<couleur_t>::const_iterator
				couleurs_it (couleurs.begin()),
				couleurs_end(couleurs.end());
			for(;couleurs_it!=couleurs_end;++couleurs_it){
				std::set<rang_t>::const_iterator
					rangs_it (rangs.begin()),
					rangs_end(rangs.end());
				for(;rangs_it!=rangs_end;++rangs_it){
					carte_t c(*rangs_it,*couleurs_it);
					etat[c] = false;
				}
			}
		}

		inline void set_etat(const carte_t & c,bool state) {
			etat_t::iterator fit(etat.find(c));
			if (fit == etat.end()) throw; // cette carte n'existe pas
			etat[c] = state;
		}

		inline bool get_etat(const carte_t & c) const{
			etat_t::const_iterator fit(etat.find(c));
			if (fit != etat.end()) throw; // cette carte n'existe pas
			return fit->second;
		}

		inline const couleurs_t & get_couleurs() const{
			return couleurs;
		}

		inline const rangs_t & get_rangs() const{
			return rangs;
		}

		inline const etat_t & get_etat() const{
			return etat;
		}
};

inline std::ostream & operator <<(std::ostream & out,const manager_t & m){
	const manager_t::etat_t & etat = m.get_etat();
	manager_t::etat_t::const_iterator
		etat_it (etat.begin()),
		etat_end(etat.end());
	for(;etat_it!=etat_end;++etat_it){
		out << etat_it->first << '\t' << (etat_it->second ? "true" : "false") << std::endl;
	}
	return out;
}

int main(){
	couleurs_t couleurs;
	couleurs.insert("pique");
	couleurs.insert("coeur");
	couleurs.insert("carreau");
	couleurs.insert("trèfle");

	rangs_t rangs;
	rangs.insert("as");
	rangs.insert("2");
	rangs.insert("3");
	//...

	manager_t m(couleurs,rangs);
	std::cout << m;

	std::cout << "************" << std::endl;
	m.set_etat(carte_t("as","coeur"),true);
	std::cout << m;

	return 0;
}
ce qui donne :
2 de carreau    false
2 de coeur      false
2 de pique      false
2 de trèfle     false
3 de carreau    false
3 de coeur      false
3 de pique      false
3 de trèfle     false
as de carreau   false
as de coeur     false
as de pique     false
as de trèfle    false
************
2 de carreau    false
2 de coeur      false
2 de pique      false
2 de trèfle     false
3 de carreau    false
3 de coeur      false
3 de pique      false
3 de trèfle     false
as de carreau   false
as de coeur     true
as de pique     false
as de trèfle    false

L'avantage de ce code c'est que tu peux facilement créer un jeu de tarot, de 32 cartes, de 52 cartes, etc...

Bonne chance

Répondre à mamiemando

12

Char Snipeur, le 17 sep 2008 à 08:57:29

Certes, ce n'est pas le plus élegant efficace etc. mais la question demeure, pourquoi n'arrive t'il pas à compiler ?
Je ne vois pas où est la faute. Salutation !  avant je croyais, maintenant je suis fixé.Jésu­s Christ
Char Snipeur

Répondre à Char Snipeur

13

Char Snipeur, le 17 sep 2008 à 09:04:04

Après essai, j'ai le même problème que toi.
il semble que le fait de mettre le mot clé static fait que la déclaration de ton tableau n'alloue pas de mémoire. Il faut donc déclarer/créer ton tableau en dehors de la classe en ajoutant la ligne :
bool carte::dejaUtilisees[13][4];
Je pense que comme une variable statique est propre à la classe et non à l'objet (ce qui reviens à une variable globale) elle n'occupe pas de place mémoire dans chaque objet, il semble donc logique de la déclarer en dehors de la classe. Salutation !  avant je croyais, maintenant je suis fixé.Jésu­s Christ
Char Snipeur

Répondre à Char Snipeur

14

mamiemando, le 17 sep 2008 à 10:12:19

En fait c'est expliqué ici :
http://cpp.developpez.com/faq/cpp/?page=static

(comment initialiser une variable statique, pourquoi tu as une erreur de linkage etc...)

Bonne lecture

Répondre à mamiemando

15

zzzer, le 17 sep 2008 à 10:47:17

J'ai déjà cherché à résoudre mon problème avec cette page, mais je n'y parviens pas...
Ils initialisent leur membre static dans le fichier .cpp, je n'en ai pas.
J'ai tenté de faire un static int plutôt qu'un tableau static. J'ai réussi à l'initialiser en plaçant l'initialisation en dehors de la classe, dans le fichier .h.
Mais quand je mets un for dans ce même fichier, cela ne passe pas à la compilation...

N'oubliez pas de marquer la discussion comme résolue dès que c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte :

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer

16

mamiemando, le 17 sep 2008 à 11:21:15

Ben oui c'est normal. Une boucle for c'est dans une fonction. Il faudrait par exemple initialiser ta variable via une fonction, comme tu as voulu faire, mais tu as bien vu que ce n'était pas possible, c'est dit en toute lettre dans le lien que je t'ai donné.

C'est la raison pour laquelle je t'ai dit que l'approche par variable statique n'était pas bonne et que je t'ai proposé une méthode alternative. En gros ça ne sert à rien de s'acharner avec un tableau static car tu ne pourras jamais l'initialiser, car tu te prendras systématiquement une erreur de linkage.

Répondre à mamiemando

17

 zzzer, le 17 sep 2008 à 13:13:33

Arf, ok, merci, je vais voir avec ce que tu as mis alors...

N'oubliez pas de marquer la discussion comme résolue dès que c'est le cas ! -> En haut de la page, Statut: Résolu
Attention aussi à bien respecter la 6e règle de la charte :

Rédiger les messages dans un langage clair sans abréviation, style télégraphique ou mode SMS

Répondre à zzzer