IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

problème de programmation


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut problème de programmation
    Bonjour,

    J'ai un problème lors de l'exécution de mon programme et je pense en avoir trouvé la cause. Si tout ce que je vais vous décrire vous semble normal, peut-être le problème vient d'ailleurs. Merci dans ce cas de m'en informer.
    Je suis en train de traiter des images (une vingtaine) et j'aimerais associer un nombre (int) à chacune d'entre elles. J'ai pour cela créé une fonction avec un grand switch, qui prend pour argument un entier et renvoie un pointeur vers l'image concernée.
    Le problème c'est que les images n'étant pas définies à l'intérieur de la fonction, il faut les définir en global. Je les ai donc définies en dehors du main, mais elles ne sont initialisées que dans le main (car chaque image doit être traitée avec des tests conditionnels et autres, qui ne sont je crois pas possibles hors du main).
    Le programme compile mais bloque à l'exécution et me dit que la fonction censée rendre un pointeur sur une image rend en fait un pointeur sur NULL.
    J'espère que vous m'avez compris (sinon demandez-moi des précisions) et que vous serez aptes à m'aider à résoudre mon problème.

    Merci d'avance

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Bonjour,

    Sous quel système travailles-tu, et avec quel compilateur ?

    Je suis en train de traiter des images (une vingtaine) et j'aimerais associer un nombre (int) à chacune d'entre elles. J'ai pour cela créé une fonction avec un grand switch, qui prend pour argument un entier et renvoie un pointeur vers l'image concernée.
    Un tableau de pointeurs serait beaucoup plus indiqué qu'un switch().

    Le problème c'est que les images n'étant pas définies à l'intérieur de la fonction, il faut les définir en global.
    Déjà, comment sont définies tes images ? Tu les charges depuis un fichier ? Tu inclus un *.XPM ? Tu ajoutes des ressources à un *.exe Windows ? Tu fais un malloc() ?

    Je les ai donc définies en dehors du main, mais elles ne sont initialisées que dans le main (car chaque image doit être traitée avec des tests conditionnels et autres, qui ne sont je crois pas possibles hors du main).
    En quoi consiste concrètement l'« initialisation » de ton image ?

    Le programme compile mais bloque à l'exécution et me dit que la fonction censée rendre un pointeur sur une image rend en fait un pointeur sur NULL.
    Le problème se trouve donc à l'intérieur de ta fonction. Il faut regarder si ton code est correct (et pour cela, il faut le poster ici). Je parie que tu transmets un numéro hors-plage, que ton switch() tombe dans le cas default: et renvoie un pointeur initialisé à NULL (ce qui est un moindre mal : il pourrait ne pas être initialisé du tout).

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut
    Bonjour,

    Je vous remercie de l'attention que vous portez à mon problème.

    Le code est probablement trop long (centaines de lignes) pour être copié. De plus vous ne pourriez pas le compiler sans les images.

    Je travaille sous windows xp avec codeblocks et gcc (mingw).

    Vous avez raison un tableau est probablement plus adapté. Je n'ai néanmoins pas précisé que ces int étaient des constantes définies avec des define, je ne sais pas si cela est compatible avec la notion de tableau.
    Par exemple :
    #define BordDeMer 100
    Je souhaiterais que image(BordDeMer) renvoie l'image concernée.

    Mes images sont des .bmp qui sont chargées avec une bibliothèque appelée SDL grâce à la fonction SDL_LoadBMP, qui renvoie une image dont le type est SDL_Surface *.

    L'<<initalisation>> de mon image comprend son chargement (avec SDL_LoadBMP), un test pour vérifier qu'elle a bien été chargée, et une fonction qui se charge de créer de la transparence en supprimant le fond jaune, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SDL_Surface* example_img = SDL_LoadBMP("example.bmp");
    if (!example_img)
        {
            fprintf(stderr, "Unable to load example: %s\n", SDL_GetError());
            return EXIT_FAILURE;
        }
    SDL_SetColorKey(example_img, SDL_SRCCOLORKEY, SDL_MapRGB(example_img->format, 255, 255, 0));

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KateA Voir le message
    Vous avez raison un tableau est probablement plus adapté. Je n'ai néanmoins pas précisé que ces int étaient des constantes définies avec des define, je ne sais pas si cela est compatible avec la notion de tableau.
    Par exemple :
    #define BordDeMer 100
    Je souhaiterais que image(BordDeMer) renvoie l'image concernée.
    Oui, ça marchera bien entendu puisque les define sont convertis par le préprocesseur bien avant le début de la compilation. Autrement dit, partout dans ton code où tu utiliseras "BordDeMer", ce sera ensuite retranscrit en 100. T'as même le droit d'écrire printf("%d", BordDeMer + 25)

    Toutefois il me semble que tu ne travailles pas d'une bonne façon. Ton code présuppose un lien réel entre le token "BordDeMer" et l'image associée qui, selon moi, représentera un bord de mer. Seulement en faisant ça, tu vas à l'encontre des règles de programmation car tu lies ton code à des données externes ce qui n'est pas propre. Ca marchera mais comment feras-tu si un jour l'image change et représente un clown ? Tu vas modifier ton code et remplacer "BordDeMer" par "TeteDeClown" ???

    Tu dois penser très tôt à dissocier le programme des données qu'il manipule. Car autrement tu auras très vite de gros soucis de maintenance/modification de code.

    Si tu veux associer à ton image un descriptif, rien ne t'interdit de créer une structure contenant l'identificateur de l'image et son descriptif. Et ton code se contentera, lui, de manipuler un tableau de cette structure. Et tu pourras passer l'adresse de ce tableau à toute fonction chargée de la manipuler ce qui t'évitera en plus de devoir le mettre en global.

    Citation Envoyé par KateA Voir le message
    Mes images sont des .bmp qui sont chargées avec une bibliothèque appelée SDL grâce à la fonction SDL_LoadBMP, qui renvoie une image dont le type est SDL_Surface *.
    Grosse erreur. La fonction ne te renvoie pas une image mais juste un pointeur (un simple nombre quoi) vers une structure de type SDL_Surface. Tout comme fopen() te renvoie un pointeur vers une strucure de type FILE.
    Et donc rien n'interdit d'utiliser une structure associative qui associe ton nombre et le pointeur renvoyé et gérer un tableau de ce genre de structure. Bien entendu tu peux avoir des soucis d'ordres techniques comme le nombre d'images pouvant être ouvertes en même temps mais c'est à toi de le régler. Par exemple au lieu d'ouvrir toutes tes images et stocker dans ladite structure le nombre que tu veux et le pointeur de l'image qui lui est associée, tu peux stocker à la place le nombre et le nom de l'image ("example.bmp" dans ton exemple) et n'appeler SDL_LoadBmp que quand tu veux vraiment traiter ladite image...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Par défaut
    En ce qui concerne le tableau, mon interrogation reposait sur sa structure. S'il est question d'un simple tableau d'images, alors l'accès à l'image 'bord de mer' se fera avec quelque chose du genre 'tableau[17]'. Cela ne me semble pas très parlant au niveau de la programmation. C'est pourquoi j'ai voulu associer un nom (une constante, avec #define) à chaque entier qui est relié à une image.
    Ainsi image(borddemer), avec #define borddemer 17, me semble plus parlant. Or on ne peut pas faire tableau[borddemer] car on ne sait pas si le #define de borddemer n'est pas plus grand que la taille du tableau.
    Une solution serait peut-être un tableau de couples, l'un étant l'image, et l'autre l'entier associé. Ca me semble aussi compliqué que de faire un switch, d'autant que ça complique l'utilisation future.
    L'idée principale est que l'accès à l'image 'bord de mer' est plus parlante avec image(borddemer) qu'avec tableau[17].

    borddemer n'était qu'un exemple pour ne pas vous noyer dans mes notations. Les images sont fixes et ne changeront normalement pas (ce sont les pièces d'un jeu).

    Dans mon programme, je dois conserver la position de toutes les pièces présentes à l'écran. Il me semble plus simple de manipuler des entiers que des images (SDL_Surface *).

    L'idée m'est donc venue de créer des #define pour chaque pièce, et d'associer grâce à une fonction les int aux images.

    Maintenant que vous comprenez un peu mieux ma situation, cette implémentation vous semble-t-elle toujours maladroite ?

    Je suis naturellement ouverte à toute modification, même si je préférerais garder ce que j'ai déjà programmé pour ne pas avoir fait du travail pour rien.

    En ce qui concerne la remarque que vous avez ajoutée sur les images, je voulais effectivement dire que la fonction image renvoie un pointeur sur image et non l'image elle-même, désolé. Je m'exprime sans doute mal, mais je ne pense pas avoir fait d'erreur de programmation à ce niveau-là.

  6. #6
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    rien n'interdit de créer une structure pour l'occasion, comme celle-ci par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct _IMAGE_DESCRIPTOR
    {
        int NumID; /* identifiant de l'image */
        SLD_Surface* Surface; /* Surface associée à l'image */
        char ImageName[20]; /* nom de l'image */
    } IMAGE_DESCRITPOR;
    Chaque image étant maintenant décrite par la structure ci-dessus, on utiliserait un tableau regroupant toutes les structures, c-a-d une structure par image.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IMAGE_DESCRIPTOR** tab_desc; /* tableau de descripteur d'image */
    Ensuite une fonction pour trouver:

    1) La structure associée à un nombre (NumID)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /* retourne la structure associée à un NumID donné. Retourne NULL si aucune structure ne contient le NumId */
    IMAGE_DESCRIPTOR* GetImageDescriptorByNumId(int NumID);
     
    /* ou bien */
    IMAGE_DESCRIPTOR* GetImageDescriptorByNumId(IMAGE_DESCRIPTOR** tab, int NumID);
    2) La structure associée à une chaine de caractère (ImageName)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /* retourne la structure associée à un 'ImageName' (nom d'image) donné. Retourne NULL si aucune structure ne contient le nom d'image */
    IMAGE_DESCRIPTOR* GetImageDescriptorByImageName(char* ImageName);
     
    /* ou encore */
    IMAGE_DESCRIPTOR* GetImageDescriptorByImageName(IMAGE_DESCRIPTOR** tab, char* ImageName);
    Au final, cela nous permet de récupérer la Surface associé à un nom:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /* récupère le descripteur associé à l'image "Bord de mer" */
    IMAGE_DESCRIPTOR* ImageDesc_BordDeMer = GetImageDescriptorByImageName("bord_de_mer");
     
    /* Récupère la surface associé à l'image bord de mer */
    SDL_Surface* Surf_BordDeMer = ImageDesc_BordDeMer->Surface;
    Ça ne sont que des exemples, il existe une foule de possibilités en ce qui concerne l'implémentation.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par KateA Voir le message
    Je suis naturellement ouverte à toute modification, même si je préférerais garder ce que j'ai déjà programmé pour ne pas avoir fait du travail pour rien.
    Lors de la création du système Unix autour des années 1970, les programmeurs ont commencé par travailler pendant 2 ans. Ils ont créé un système, apporté des modifs, bref fait un développement complet.
    Au bout de 2 ans, ils ont dit "ca cafouille trop" et ils ont tout jeté pour recommencer de zéro. Toutefois ils avaient accumulé une certaine expérience de connaissances et de réflexions et ça a donné ce superbe système très apprécié des professionnels qui a ensuite été repris en 1994 par Linus Thorvald pour donner naissance à Linux.

    On ne travaille jamais pour rien. Ce que t'as fait tu l'as en toi. Mais personne ne te demandera non plus de faire ce que tu ne veux pas. On te donne des conseils car on est passé avant toi par ce genre d'étape où on voit mal comment s'organiser mais personne ne t'en voudra si tu fais tes propres expériences. Ensuite, quand tu te sentiras à l'aise, tu verras que ce n'est pas si difficile de reprendre parfois un code, voire même de zéro.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Petit problème de programmation.
    Par willow.A dans le forum C
    Réponses: 3
    Dernier message: 08/01/2007, 16h36
  2. Problème en programmant un GUI swing
    Par kaelem dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 05/01/2007, 11h59
  3. Problème de programmation orientée objet
    Par dan65 dans le forum WinDev
    Réponses: 8
    Dernier message: 17/09/2006, 01h04
  4. problème finalisation programme
    Par depelek dans le forum Installation, Déploiement et Sécurité
    Réponses: 9
    Dernier message: 02/05/2006, 16h17
  5. Réponses: 1
    Dernier message: 26/09/2005, 19h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo