CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Quadtree construction image c + affichage

mxbr236
mxbr236
Niveau 7
28 décembre 2021 à 15:38:55

Bonjour,

Je travaille actuellement sur un projet qui vise à implémenter différentes fonctions concernant les quadtrees en C. Sauf que j'ai certaines difficultés à comprendre ce qui est demandé.

Quadrees représentent images noir et blanc. Une image Quadtree est soit blanche, soit noir, soit décomposée en 4 sous-images : haut-gauche, haut-droit, bas-gauche, bas-droit.

On dispose du type suivant :

typedef struct bloc_image
{
    int toutnoir; //représente un booléen
    struct bloc_image * fils[4];
}bloc_image;

typedef bloc_image *image;

de plus, on sait que :
image blanche si pointeur NULL.
Lorsque le pointeur pointe vers un struct dont le champ "toutnoir" est true (=1), l'image est noire et les 4 champs fils[0], fils[1], fils[2], fils[3] sont NULL.

Quand il pointe vers un struct dont le champ toutnoir est false, l’image est obtenue en
découpant l’image en 4, et en plaçant respectivement les images fils[0], fils[1], fils[2],
fils[3] en haut à gauche, en haut à droite, en bas à gauche, en bas à droite.

Ce qui est demandé :
coder une fonction Construit_blanc() qui rend une image banche à partir de rien;
Construit_noir qui rend une image noire à partir de rien;
enfinConstruit_composer(ihg, ihd, ibg, ibd) qui construit une image composée dont les 4 sous-images sont ihg, ihd, ibg et ibd.

Pour le moment j'ai implémenter les deux premières :

image Construit_noir()
{
    image newImage;
    newImage->toutnoir = 1;
    newImage->fils[0] = NULL;
    newImage->fils[1] = NULL;
    newImage->fils[2] = NULL;
    newImage->fils[3] = NULL;
    return newImage;
}

image Construit_blanc()
{
    image newImage;
    newImage = NULL;
    return newImage;
}

ça compile, j'ai essayé de mettre en place quelques tests de base, ces tests semblent s'executer mais j'ai un message à la fin.

les tests :

int main(void)
{
    image blanche = Construit_blanc();
    printf("blanche est null : %d\n", blanche == NULL);
    image noire = Construit_noir();
    printf("toutnoir vaut %d\n", noire->toutnoir == 1);
    for(int i = 0; i < 4; ++i)
    {
        printf("Le fils n°%d est null : %d\n", i, noire->fils[i] == NULL);
    }
    return 0;
}

le résultat obtenu :

blanche est null : 1
toutnoir vaut 1
Le fils n°0 est null : 1
Le fils n°1 est null : 1
Le fils n°2 est null : 1
Le fils n°3 est null : 1
Inconsistency detected by ld.so: dl-fini.c: 88: _dl_fini: Assertion `ns != LM_ID_BASE || i == nloaded' failed!

Hormis le dernier message, les differentes assertions semblent verifiées.

Par contre, je n'ai aucune idée de comment procéder à la fonction suivante (Construit_composer(ihg, ihd, ibg, ibd) qui construit une image composée dont les 4 sous-images sont ihg, ihd, ibg et ibd.)

Etant donné que le sujet parle de positionnement des images, ce qui est assez confus je trouve.

Surtout qu'ensuite on nous demande d'afficher des images en éctiture postfixe :

ex : image blanche : +BBB+BBB+BBBB

et de réaliser d'autres types de fonctions.

Donc j'aimerais être sûr de bien avoir compris ce qui est demandé

Merci en tous cas,

Cordialement.

mxbr236
mxbr236
Niveau 7
28 décembre 2021 à 16:05:03

Surtout qu'ensuite on nous demande d'afficher des images en éctiture postfixe :

En créant une nouvelle fonction

Par contre, je n'ai aucune idée de comment procéder à la fonction suivante

Après je me doute bien que ça commence à peu près comme ça :

/*image Construit_composee(image ihg, image ihd, image ibg, image ibd)
{
code de la fonction
}*/
aAardvark
aAardvark
Niveau 75
28 décembre 2021 à 23:52:43

Bon ça fait un bail que j'ai pas fait activement du C, mais pour répondre vite fait :d)

Tu sembles mal maîtriser - ou n'as pas fait attention - comment est gérée la mémoire quand tu déclares / alloues tes variables :

  • dans ta fonction Construit_blanc(), qui est correcte mais inutilement longue en fait, tu demandes au compilo de réserver de la mémoire sur la pile-mémoire pour un pointeur vers une structure bloc_image. Ne pas confondre donc les structures bloc_image, et les pointeurs image qui pointent vers ces structures. Une fois que la fonction est terminée, le compilo "dépile" de manière fictive et théoriquement tu ne dois plus utiliser les variables qui ont été déclarée dans ta fonction car cet espace mémoire sera utilisé ensuite pour autre chose.
  • au final dans cette fonction tu ne retournes qu'un pointeur NULL, donc pas de soucis. Mais tu peux combiner la 1ère et la 2ème ligne, et même en fait juste faire un return NULL;

c'est comme si pour faire un return 0; tu déclarais un integer avant pour le renvoyer

-

  • pour ta fonction Construit_noir() là il y a un problème. Tu déclares un pointeur, mais tu oublier de déclarer ta structure ! donc ton pointeur va pointer vers l'adresse 0 ou une adresse random, et rien que faire newImage->toutnoir = 1; ne va pas.
  • Tu dois à un moment ou un autre déclarer ta structure, et pas juste le pointeur. et là deux possibilités :

- Le C t'autorise à renvoyer une structure, donc tu la déclares, la remplie, et la renvoie. Là il me semble que le compilo fait une copie de ta structure et c'est ce que tu reçois
- soit tu fais une allocation dynamique de ta structure avec malloc(), et tu peux renvoyer un pointeur qui pointe vers celle-ci car ta structure ne disparaîtra pas à la fin de la fonction (elle n'est pas sur la pile-mémoire).

-

  • De la même manière, comme un int ou un float, quand tu passes une structure directement en paramètre d'une fonction, c'est une copie qui est passée (et mise sur la pile). Sinon, il faut effectivement passer par un pointeur, c'est toujours une copie qui sera passée et mise sur la pile mais pas de soucis vu que c'est un pointeur (une adresse)

Comme je reste humble et qu'il m'arrive d'être à côté de la plaque, qu'on me corrige si je dis des bêtises :hap:

mxbr236
mxbr236
Niveau 7
29 décembre 2021 à 14:40:20

Du coup pour la fonction Construit_blanc, j'ai combiné la ligne 1 et la ligne 2 pour donner :

image Construit_blanc()
{
    image newImage;
    newImage = NULL;
    return newImage;
}

et pour Construit_noir, jai alloué dynamiquement de la mémoire, ce qui donne le résultat suivant :

image Construit_noir()
{
    image newImage;
    newImage->toutnoir = 1;
    newImage->fils[0] = NULL;
    newImage->fils[1] = NULL;
    newImage->fils[2] = NULL;
    newImage->fils[3] = NULL;
    return newImage;
}

au niveau des tests, le résultat est le même que précédemment, et je n'ai plus ce message d'erreur : Inconsistency detected by ld.so: dl-fini.c: 88: _dl_fini: Assertion `ns != LM_ID_BASE || i == nloaded' failed!
Donc tout me semble correct au niveau des tests, et je vais voir ce que je peux faire pour la suite.

mxbr236
mxbr236
Niveau 7
29 décembre 2021 à 14:56:09

Petite correction, j'avais remis les codes tel quels dans mon précédent message.

image Construit_blanc()
{
    image newImage = NULL;
    return newImage;
}
image Construit_noir()
{
    image newImage = malloc(sizeof(image));
    newImage->toutnoir = 1;
    newImage->fils[0] = NULL;
    newImage->fils[1] = NULL;
    newImage->fils[2] = NULL;
    newImage->fils[3] = NULL;
    return newImage;
}
mxbr236
mxbr236
Niveau 7
29 décembre 2021 à 15:09:38

Par contre, je n'ai aucune idée de comment procéder à la fonction suivante (Construit_composer(ihg, ihd, ibg, ibd) qui construit une image composée dont les 4 sous-images sont ihg, ihd, ibg et ibd.)

Finalement on m'a expliqué que c'est le même système que pour la fonction Construit_noir, sauf qu'il faut remplacer les 4 fils null par les 4 sous images, ce qui donne quelque-chose comme ça :

image Construit-composee(ihg, ihd, ibg, ibd)
{
    image newImage = malloc(sizeof(image));
    newImage->fils[0] = ihg;
    newImage->fils[1] = ihd;
    newImage->fils[2] = ibg;
    newImage->fils[3] = ibd;
    return newImage;
}
mxbr236
mxbr236
Niveau 7
29 décembre 2021 à 15:14:36

et rien que faire newImage->toutnoir = 1; ne va pas.

Pour toutnoir, ce serait peut être mieux de faire une condition du style, si les 4 sous-images sont initialisées à NULL, toutnoir vaut 1 sinon 0 (vu que c'est un booléen)

Enfin dans le sujet ils explique ça, mais je n'ai pas très bien compris :

Quand il pointe vers un struct dont le champ toutnoir est true, l’image est noire et les 4
champs fils[0], fils[1], fils[2], fils[3] sont NULL.

Quand il pointe vers un struct dont le champ toutnoir est false, l’image est obtenue en
découpant l’image en 4, et en plaçant respectivement les images fils[0], fils[1], fils[2],
fils[3] en haut à gauche, en haut à droite, en bas à gauche, en bas à droite.

aAardvark
aAardvark
Niveau 75
29 décembre 2021 à 22:22:47

Sinon je pense que

image Construit_blanc()
{
     return NULL;
}

revient au même surtout que le pointeur de retour est de toute façon casté en image, et pour info je pense qu'il aurait aussi été possible de faire

bloc_image Construit_noir()
{
    bloc_image newImage
    newImage.toutnoir = 1;
    newImage.fils[0] = NULL;
    newImage.fils[1] = NULL;
    newImage.fils[2] = NULL;
    newImage.fils[3] = NULL;
    return newImage;
}

(j'ai rien pour déboguer je précise)

vu que l'image de retour est bien une copie de celle que tu remplies dans la fonction (qui elle disparaitra à la fin de la fonction)

mais si tu veux être cohérent avec la première fonction et retourner un pointeur oui fais comme tu l'as écrit :oui: juste oublie pas de libérer la mémoire allouée par malloc() à la fin de ton programme, histoire de montrer que tu ne l'oublie pas.

et rien que faire newImage->toutnoir = 1; ne va pas.

J'ai bien dit ça car tu écrivais "1" dans une case mémoire à laquelle tu n'avais normalement pas l'autorisation d'écrire ! Si ton pointeur pointe bien vers un bloc_image, c'est bon

  • Sinon tu considères simplement que ton programme est bien écris et que tu ne te confrontera jamais à une image avec par exemple le champ toutnoir à 1 et un des pointeurs fils non nul (même si techniquement tu pourrais faire une image mal construite)
aAardvark
aAardvark
Niveau 75
29 décembre 2021 à 22:27:49

Ah et ça s'execute correctement ton code ? :(

car normalement c'est pas

image newImage = malloc(sizeof(image));

Mais plutôt

image newImage = malloc(sizeof(bloc_image));

=

image newImage = (bloc_image*) malloc(sizeof(bloc_image));

=

image newImage = (image ) malloc(sizeof(bloc_image));

Après ça fait un bail que j'ai pas fait de C, mais là tu alloue juste assez de mémoire pour un pointeur, mais pas pour la taille de ta structure

mxbr236
mxbr236
Niveau 7
30 décembre 2021 à 14:36:29

Le 29 décembre 2021 à 22:27:49 :
Ah et ça s'execute correctement ton code ? :(

car normalement c'est pas

image newImage = malloc(sizeof(image));

Mais plutôt

image newImage = malloc(sizeof(bloc_image));

=

image newImage = (bloc_image*) malloc(sizeof(bloc_image));

=

image newImage = (image ) malloc(sizeof(bloc_image));

Après ça fait un bail que j'ai pas fait de C, mais là tu alloue juste assez de mémoire pour un pointeur, mais pas pour la taille de ta structure

C'est totalement possible, le compilateur a peut-être fait quelques changements pour que ça fonctionne. Sinon j'ai modifié cette partie.

bloc_image Construit_noir()
{
bloc_image newImage
newImage.toutnoir = 1;
newImage.fils[0] = NULL;
newImage.fils[1] = NULL;
newImage.fils[2] = NULL;
newImage.fils[3] = NULL;
return newImage;
}

Par contre si je remplace les flèches par des points, ça ne compile plus, donc je préfère garder la version précédente.

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment