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.
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
}*/
Bon ça fait un bail que j'ai pas fait activement du C, mais pour répondre vite fait ![]()
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 :
c'est comme si pour faire un return 0; tu déclarais un integer avant pour le renvoyer
-
newImage->toutnoir = 1; ne va pas.- 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).
-
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 ![]()
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.
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;
}
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;
}
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.
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
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
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
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.