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 :

Sauriez-vous m'expliquer cette partie de code svp ?


Sujet :

C++

  1. #1
    Membre éprouvé
    Avatar de beegees
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Points : 1 277
    Points
    1 277
    Par défaut Sauriez-vous m'expliquer cette partie de code svp ?
    Bonjour tout le monde,

    Je ne comprends pas bien une partie de code d'un programme que j'analyse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    bool CTableauGenerique::Ajouter(const CGenerique& ModeleAAjouter, bool RetourEnCasDeDoublon)
    {
    	if (!ModeleAAjouter.EstValide()) return false;
    	if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    	void* Nouveau = realloc(m_Tableau,(m_Nombre+1)*sizeof(CGenerique*));
    	if (Nouveau == NULL) return false;
    	m_Tableau = (CGenerique**)Nouveau;
    	CGenerique* AAjouter = ModeleAAjouter.Cloner();
    	if (!AAjouter->EstValide())
    	{
    		delete AAjouter;
    		return false;
    	}
    	m_Tableau[m_Nombre] = AAjouter;
    	m_Tableau[m_Nombre]->DefinirConteneur(this);
    	m_Nombre++;
    	return true;
    }
    Déjà, je vois que RetourEnCasDeDoublon vaut 1, je ne pense pas que ça soit le chiffre 1 mais plutôt le code ASCII 1 qui correspond au start of heading, sauriez-vous me dire à quoi ça correspond ?

    Cette ligne termine-t'elle la méthode ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;


    J'ai du mal avec cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    Le premier test vérifie si l'unicité est gérée ou non avec cette méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool CRecompense::GereUnicite() const
    {
    	return true;
    }
    Le second test appelle la méthode "Indice" ci-desssous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    long CTableauGenerique::Indice(const CGenerique& ModeleRecherche) const
    {
    	if ( (m_Nombre == 0) || (!m_Poubelle->GereUnicite()) || (!ModeleRecherche.EstValide()) ) return -1;
    	const CGenerique* Recherche = &ModeleRecherche;
    	unsigned int n = m_Nombre;
    	((CTableauGenerique*)this)->m_TypeComparaison = ComparaisonPourUnicite;
    	CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    	((CTableauGenerique*)this)->m_TypeComparaison = -1;
    	return (Trouve != NULL) ? Trouve - m_Tableau : -1;
    }
    Ce que je ne comprends pas dans cette méthode Indice s'est ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    Il va donc faire une recherche ici ? une recherche de quoi exactement ?

    et ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	return (Trouve != NULL) ? Trouve - m_Tableau : -1;
    Il retourne donc l'adresse de Trouve - l'adresse de m_Tableau :

    m_Tableau vaut 0x00360858
    - Trouve vaut 0x00360858
    ----------------------------------
    Il retourne donc 0 (à chaque fois)

    Merci d'avance pour votre aide.

    beegees

  2. #2
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut beegees,

    Citation Envoyé par beegees Voir le message
    Bonjour tout le monde,

    Je ne comprends pas bien une partie de code d'un programme que j'analyse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    bool CTableauGenerique::Ajouter(const CGenerique& ModeleAAjouter, bool RetourEnCasDeDoublon)
    {
    	if (!ModeleAAjouter.EstValide()) return false;
    	if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    	void* Nouveau = realloc(m_Tableau,(m_Nombre+1)*sizeof(CGenerique*));
    	if (Nouveau == NULL) return false;
    	m_Tableau = (CGenerique**)Nouveau;
    	CGenerique* AAjouter = ModeleAAjouter.Cloner();
    	if (!AAjouter->EstValide())
    	{
    		delete AAjouter;
    		return false;
    	}
    	m_Tableau[m_Nombre] = AAjouter;
    	m_Tableau[m_Nombre]->DefinirConteneur(this);
    	m_Nombre++;
    	return true;
    }
    Déjà, je vois que RetourEnCasDeDoublon vaut 1, je ne pense pas que ça soit le chiffre 1 mais plutôt le code ASCII 1 qui correspond au start of heading, sauriez-vous me dire à quoi ça correspond ?
    RetourEnCasDeDoublon est un booléen qui vaut soit true (1) ou false (0).
    1 est donc bien sa valeur, et non un code ASCII.

    Citation Envoyé par beegees Voir le message
    Cette ligne termine-t'elle la méthode ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    Cette ligne, d'après ma compréhension, sert à sortir de la fonction si le ModeleAAjouter fait déjà partie de notre tableau.

    Citation Envoyé par beegees Voir le message
    J'ai du mal avec cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    Le premier test vérifie si l'unicité est gérée ou non avec cette méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool CRecompense::GereUnicite() const
    {
    	return true;
    }
    Le second test appelle la méthode "Indice" ci-desssous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    long CTableauGenerique::Indice(const CGenerique& ModeleRecherche) const
    {
    	if ( (m_Nombre == 0) || (!m_Poubelle->GereUnicite()) || (!ModeleRecherche.EstValide()) ) return -1;
    	const CGenerique* Recherche = &ModeleRecherche;
    	unsigned int n = m_Nombre;
    	((CTableauGenerique*)this)->m_TypeComparaison = ComparaisonPourUnicite;
    	CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    	((CTableauGenerique*)this)->m_TypeComparaison = -1;
    	return (Trouve != NULL) ? Trouve - m_Tableau : -1;
    }
    Ce que je ne comprends pas dans cette méthode Indice s'est ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    Il va donc faire une recherche ici ? une recherche de quoi exactement ?

    et ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	return (Trouve != NULL) ? Trouve - m_Tableau : -1;
    Il retourne donc l'adresse de Trouve - l'adresse de m_Tableau :

    m_Tableau vaut 0x00360858
    - Trouve vaut 0x00360858
    ----------------------------------
    Il retourne donc 0 (à chaque fois)
    Là c'est plutôt bizarre

    Améliorons déjà un peu la lecture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (Trouve == NULL) {
        return -1;
    } else
    {
       return Trouve - m_tableau;
    }
    Avant de continuer, je suppose que m_tableau est un tableau de CGenerique *.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    Avec la page expliquant ce qu'est lfind, c'est plus clair

    Recherche est l'adresse de ModeleRecherché.
    Donc la fonction lfind utilise la méthode Comparer sur chaque élément de m_Tableau, pour le comparer à l'élément recherché. Si elle le trouve, alors elle retourne un pointeur sur l'élément de m_tableau correspondant.

    Ca revient à peu près à ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CGenerique **Trouvé;
     
    /* n correspond à la taille du tableau */
    for (int i = 0; i < n; i ++)
    {
        if (Comparer(Recherche, m_tableau[i]) == 0)
        {
             Trouvé = &(m_tableau[i]); //équivalent à m_tableau + i
             break; //on sort de la boucle
        }
    }
    Bon, de leur côté, ça doit être un peu plus optimisé, mais c'est le principe

    Donc si Recherche ne fait pas partie de m_tableau, Trouvé vaut NULL, et donc on retourne -1.
    Sinon, si par exemple Recherche correspond au troisième élément de m_tableau, alors Trouvé = &(m_tableau[2]).

    Or l'adresse du troisième élément d'un tableau est aussi l'adresse du 1er du tableau + 2.

    Donc dans mon exemple, Trouvé vaut m_tableau + 2.
    Et quand on fait Trouvé - m_tableau, ça fait 2!! On a ainsi l'indice de Recherche dans m_tableau!!!

    Ainsi la fonction Indice(const CGenerique &modele) retourne -1 si modele n'est pas dans m_tableau, sinon la position de modele dans m_tableau.

    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    si ModeleAAjouter est présent dans m_tableau, on sort de la fonction.

    Citation Envoyé par beegees Voir le message
    Merci d'avance pour votre aide.

    beegees
    De rien, là j'avoue j'ai eu un peu de mal

    Bonne journée!

    Coyotte507

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Je ne voudrais pas casser du sucre sur le dos des absents ni même heurter quiconque, mais, à parler honnêtement, la personne qui t'a fournis ce code devrait avoir honte...: C'est écrit avec les pieds.

    Si, déjà, on ne s'intéresse qu'à la partie du code qui te pose des problèmes de compréhension, et donc que l'on "glisse" sur l'utilisation de malloc, de l'utilisation de tableau de tableaux C style et de pointeurs de pointeurs, il faudra quand même qu'il puisse m'expliquer comment, alors que le type booléen (bool) ne peut représenter que deux valeurs (true pour vrai ou false pour faux) il arrive à faire pour demander à la fonction de renvoyer une valeur "RetourEnCasDeDoublon" et ce qu'elle représente... ca doit vouloir être la réponse de normand "j'ai pas dit oui, mais ce n'est pas non"

    Ceci dit, et pour quand même te permettre d'avancer.

    Certains codeurs ont bien encrée en tête l'idée farfelue qu'il existe -à nombre de commande égal - un rapport entre le nombre de ligne et l'efficacité du code.

    Non seulement, ce n'est absolument pas le cas, mais en plus, ils en oublient que la qualité première d'un code doit être la facilité de compréhension: un code est bien plus souvent lu qu'il n'est écrit, et par conséquent, il est souvent préférable de "perdre" quelques secondes à assurer la "compréhensibilité" du code en mettant en œuvre une politique stricte d'indentation et en respectant la règle d' "une commande par ligne" plutôt que de vouloir gagner une demi-seconde en utilisant les raccourcis que permet le langage.

    Et donc, au final, effectivement les codes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    sont strictement équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) 
        return RetourEnCasDeDoublon;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) )
        return RetourEnCasDeDoublon;
    la compréhensibilité à la lecture en moins.

    Maintenant, pour l'appel à la méthode "GereUnicite()", il y a fort à parier qu'il s'agisse d'une méthode virtuelle, redéfinie pour les différentes classe qui héritent de la classe mère, et que donc la valeur de retour est susceptible de changer en fonction du type réel de m_poubelle)

    La ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    quant à elle crée un objet temporaire nommé trouve qui est type pointeur de pointeur (beurk ) sur un objet de type CGenerique et qui est initialisé par le résultat le transtypage "C style" (re-beurk) de la valeur de retour de la méthode _lfind, dont il y a fort à parier qu'elle renvoie en réalité un pointeur de pointeur sur un objet d'un type descendant de la classe CGenerique.

    Enfin, la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (Trouve != NULL) ? Trouve - m_Tableau : -1;
    utilise ce que l'on appelle l'opérateur ternaire ou le résultat est calculé sur base du test (booléen) qui se trouve avant le ?.

    Si le résultat est vrai (ici, si trouve ne vaut pas nul, autrement dit, si le pointeur de pointeur temporaire pointe sur un pointeur estimé valide), on renvoie Trouve - m_Tableau, sinon, on renvoie -1.

    Cette ligne est donc équivalente à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(Trouve!=NULL)
        return Trouve - m_Tableau;
    else
        return -1;
    que l'on pourrait simplifier (sans trop perdre de compréhensibilité) en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(Trouve!=NULL)
        return Trouve - m_Tableau;
    return -1;//car on n'arrive ici que si le résultat du test est faux
    Visibilement, si le codeur préfère renvoyer la différence entre Trouve et m_tableau sous forme de long, c'est sans doute parce qu'il estime que le résultat renvoyé par la méthode _lfind pourrait ne pas être l'adresse de m_tableau (et donc que m_tableau ne soit qu'une partie du résultat renvoyé par la méthode)

    Cependant, je considère toujours comme suspect le fait de faire renvoyer une valeur, sous forme d'un long qui plus est, qui soit le résultat d'une opération d'arithmétique de pointeurs (ou de pointeurs de pointeurs en l'occurrence).

    En effet, cela sous entend que le codeur considère qu'un pointeur (ou un pointeur de pointeur dans le cas qui nous occupe ici) est de type long, ce qui peut être vérifié sur son architecture avec son compilateur mais dont on ne peut absolument pas être certain (il me semble que l'on a déjà abordé la problèmatique des tailles des type primitifs avec toi... sinon, une recherche sur le forum t'apportera les infos qui te manquent... ou tu peux toujours les demander ) selon l'architecture, l'OS et le compilateur utilisé.

    Il me semble avoir fait le tour de tes interrogations... Si tu le souhaite, je tiens "sous le coude" les explications sur lesquelles j'ai "glissé"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Comme son nom l'indique, RetourEnCasDeDoublon est la valeur retournée par la fonction en cas de doublon.

    Indice(ModeleAAjouter) donne l'indice de ModeleAAjouter dans le tableau, et -1 si il n'est pas dedans.
    Même pas besoin de lire le code pour ça, c'est évident d'après le nom et la manière dont c'est utilisé.
    Boost ftw

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par coyotte507 Voir le message
    <snip>

    Améliorons déjà un peu la lecture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (Trouve != NULL) {
        return -1;
    } else
    {
       return Trouve - m_tableau;
    }
    Attention... ton "amélioration" inverse les valeurs renvoyées par rapport au code original
    Avant de continuer, je suppose que m_tableau est un tableau de CGenerique *.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    ou du moins dont on peut espérer que c'est d'un type compatible (d'un tableau de pointeurs ou d'un pointeur de pointeur sur une classe descendant de CGenerique)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Attention... ton "amélioration" inverse les valeurs renvoyées par rapport au code original
    Mea culpa, Corrigé

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Comme son nom l'indique, RetourEnCasDeDoublon est la valeur retournée par la fonction en cas de doublon.
    Bien sur que le nom est explicite...

    Seulement, sans même s'inquiéter de savoir quelle valeur cela représente, dans le contexte actuel, il faut se demander ce que cela apporte de l'utiliser (hormis le fait d'une compréhensibilité - toute relative - peut être accrue)

    en effet, du moment que cette valeur n'est pas égale à 0, il n'y a aucun moyen, une fois qu'elle est transformée en booléen, de récupérer la valeur originale et de pouvoir faire, par exemple un truc du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    bool res= obj->Ajouter(/*blabla... sans importance ici */);
    monenum e=(monenum e); //si c'est une énumération 
    /* ou   -   ou   --   ou */
    int i = (int) res; //si c'est un #define
    swhitch( e /* ou i, selon le cas */)
    {
        case RetourEnCasDeDoublon :
            doSomething();
            break;
        case RetourSiNonExistant :
            doSomethingElse();
            break;
        default:
            doNothing();
    }
    [EDIT]Le petit code ci-dessous (même s'il est horrible du fait des casts C style et qu'il ne n'appelle pas la méthode Ajouter de la classe CTableauGenerique) permet de se faire une idée de ce qui se passe une fois que l'on a transofrmé (ici un entier) en booléen:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #include <iostream>
    using namespace std;
    int main()
    {
        int i=0;
        int j=-1;
        int k=1;
        int l=2;
        bool bi=i;
        bool bj=j;
        bool bk=k;
        bool bl=l;
        cout<<i<<" correspond a "<<std::boolalpha <<bi<<endl;
        cout<<j<<" correspond a "<<std::boolalpha <<bj<<endl;
        cout<<k<<" correspond a "<<std::boolalpha <<bk<<endl;
        cout<<l<<" correspond a "<<std::boolalpha <<bl<<endl;
        if(bj==bk)
            cout<<j<<" et "<<k<<" ont la meme valeur booleenne"<<std::endl;
        if((int)bj==(int)bk)
            cout<<bj <<" a une valeur numerique egale a "<<bk;
        return 0;
    }
    La sortie donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    0 correspond a false
    -1 correspond a true
    1 correspond a true
    2 correspond a true
    -1 et 1 ont la meme valeur booleenne
    true a une valeur numerique egale a true
    ce qui prouve que, bien qu'ils soient basé sur des entiers différents, bj et bk obtiennent la même valeur si on les transtype sous forme d'entiers
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre éprouvé
    Avatar de beegees
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Points : 1 277
    Points
    1 277
    Par défaut
    Citation Envoyé par coyotte507 Voir le message
    Salut beegees,
    Salut Coyotte,

    Un sincère merci pour ta réponse.

    Citation Envoyé par coyotte507 Voir le message
    RetourEnCasDeDoublon est un booléen qui vaut soit true (1) ou false (0).
    1 est donc bien sa valeur, et non un code ASCII.
    Ah s'est un booléen, je pensais que s'était un entier ou quelque chose dans le genre, s'est plus logique maintenant, merci.


    Cette ligne, d'après ma compréhension, sert à sortir de la fonction si le ModeleAAjouter fait déjà partie de notre tableau.
    Je pense aussi.

    Là c'est plutôt bizarre

    Améliorons déjà un peu la lecture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (Trouve == NULL) {
        return -1;
    } else
    {
       return Trouve - m_tableau;
    }
    Avant de continuer, je suppose que m_tableau est un tableau de CGenerique *.
    Euh oui, s'est un tableau de pointeur de pointeur de CGenerique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CGenerique** Trouve = (CGenerique**)_lfind(&Recherche,m_Tableau,&n,sizeof(CGenerique*),Comparer);
    Avec la page expliquant ce qu'est lfind, c'est plus clair
    Merci pour ce lien.
    Recherche est l'adresse de ModeleRecherché.
    Donc la fonction lfind utilise la méthode Comparer sur chaque élément de m_Tableau, pour le comparer à l'élément recherché. Si elle le trouve, alors elle retourne un pointeur sur l'élément de m_tableau correspondant.
    Elle renvoie donc une adresse.

    Ca revient à peu près à ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CGenerique **Trouvé;
     
    /* n correspond à la taille du tableau */
    for (int i = 0; i < n; i ++)
    {
        if (Comparer(Recherche, m_tableau[i]) == 0)
        {
             Trouvé = &(m_tableau[i]); //équivalent à m_tableau + i
             break; //on sort de la boucle
        }
    }
    Bon, de leur côté, ça doit être un peu plus optimisé, mais c'est le principe

    Donc si Recherche ne fait pas partie de m_tableau, Trouvé vaut NULL, et donc on retourne -1.
    Sinon, si par exemple Recherche correspond au troisième élément de m_tableau, alors Trouvé = &(m_tableau[2]).

    Or l'adresse du troisième élément d'un tableau est aussi l'adresse du 1er du tableau + 2.

    Donc dans mon exemple, Trouvé vaut m_tableau + 2.
    Et quand on fait Trouvé - m_tableau, ça fait 2!! On a ainsi l'indice de Recherche dans m_tableau!!!

    Ainsi la fonction Indice(const CGenerique &modele) retourne -1 si modele n'est pas dans m_tableau, sinon la position de modele dans m_tableau.

    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( (m_Poubelle->GereUnicite()) && (Indice(ModeleAAjouter) >= 0) ) return RetourEnCasDeDoublon;
    si ModeleAAjouter est présent dans m_tableau, on sort de la fonction.
    Merci s'est beaucoup plus claire maintenant, franchement je vais relire ton message (et répondre aux autres membres qui ont répondu).

    De rien, là j'avoue j'ai eu un peu de mal
    S'est vrai que s'est assez balaise, mais grâce à ton message, je comprends beaucoup mieux, un tout grand merci à toi pour ton super dévouement.

    Bonne journée!
    Une très bonne fin de journée à toi aussi.

    Beegees

  9. #9
    Membre éprouvé
    Avatar de beegees
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Points : 1 277
    Points
    1 277
    Par défaut
    Salut Koala,

    Je ne voudrais pas casser du sucre sur le dos des absents ni même heurter quiconque, mais, à parler honnêtement, la personne qui t'a fournis ce code devrait avoir honte...: C'est écrit avec les pieds.
    Tu ne casses du sucre sur le dos de personne, tu donnes juste ton avis

    Certains codeurs ont bien encrée en tête l'idée farfelue qu'il existe -à nombre de commande égal - un rapport entre le nombre de ligne et l'efficacité du code.

    Non seulement, ce n'est absolument pas le cas, mais en plus, ils en oublient que la qualité première d'un code doit être la facilité de compréhension: un code est bien plus souvent lu qu'il n'est écrit, et par conséquent, il est souvent préférable de "perdre" quelques secondes à assurer la "compréhensibilité" du code en mettant en œuvre une politique stricte d'indentation et en respectant la règle d' "une commande par ligne" plutôt que de vouloir gagner une demi-seconde en utilisant les raccourcis que permet le langage.
    Effectivement, je suis d'accord sur ce principe, ce qui est un peu bête aussi s'est le manque de commentaires dans le code

    Maintenant, pour l'appel à la méthode "GereUnicite()", il y a fort à parier qu'il s'agisse d'une méthode virtuelle, redéfinie pour les différentes classe qui héritent de la classe mère, et que donc la valeur de retour est susceptible de changer en fonction du type réel de m_poubelle)
    En effet, s'est une méthode virtuelle

    Visibilement, si le codeur préfère renvoyer la différence entre Trouve et m_tableau sous forme de long, c'est sans doute parce qu'il estime que le résultat renvoyé par la méthode _lfind pourrait ne pas être l'adresse de m_tableau (et donc que m_tableau ne soit qu'une partie du résultat renvoyé par la méthode)

    Cependant, je considère toujours comme suspect le fait de faire renvoyer une valeur, sous forme d'un long qui plus est, qui soit le résultat d'une opération d'arithmétique de pointeurs (ou de pointeurs de pointeurs en l'occurrence).

    En effet, cela sous entend que le codeur considère qu'un pointeur (ou un pointeur de pointeur dans le cas qui nous occupe ici) est de type long, ce qui peut être vérifié sur son architecture avec son compilateur mais dont on ne peut absolument pas être certain (il me semble que l'on a déjà abordé la problèmatique des tailles des type primitifs avec toi... sinon, une recherche sur le forum t'apportera les infos qui te manquent... ou tu peux toujours les demander ) selon l'architecture, l'OS et le compilateur utilisé.
    Je pense qu'il tient compte qu'on utilise tous le même IDE et si ça fonctionne chez lui, ça ne peut que fonctionner chez nous, mais je peux me tromper.

    Il me semble avoir fait le tour de tes interrogations... Si tu le souhaite, je tiens "sous le coude" les explications sur lesquelles j'ai "glissé"
    Non je pense que tu as été très complet, et à nouveau, je t'en remerice.

    Je me demande ce que j'aurais fais sans ton aide et sans l'aide de Coyotte pour ne citer que vous.

    Un tout GRAND merci pour ton aide vraiment très très précieuse.

    beegees

  10. #10
    Membre éprouvé
    Avatar de beegees
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2004
    Messages
    3 610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 3 610
    Points : 1 277
    Points
    1 277
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Comme son nom l'indique, RetourEnCasDeDoublon est la valeur retournée par la fonction en cas de doublon.

    Indice(ModeleAAjouter) donne l'indice de ModeleAAjouter dans le tableau, et -1 si il n'est pas dedans.
    Même pas besoin de lire le code pour ça, c'est évident d'après le nom et la manière dont c'est utilisé.
    Merci Loufoque.

    Bonne fin de journée.

    beegees

  11. #11
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Bonjour

    J'ajouterais que j'espère qu'il n'y a pas trop d'élèments dans le tableau car la methode d'allocation ci après tue !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void* Nouveau = realloc(m_Tableau,(m_Nombre+1)*sizeof(CGenerique*));
     
    ...
    m_Nombre++;
    Il est genéralement préférable d'allouer plusieurs elements a la fois et de faire le realloc d'un nouvel ensemble quand on a atteint la taille du paquet
    « Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)

Discussions similaires

  1. Sauriez-vous m'expliquer cette chaine sql ?
    Par beegees dans le forum Langage SQL
    Réponses: 4
    Dernier message: 07/04/2013, 21h20
  2. [DOM] Sauriez-vous m'expliquer ce script svp ?
    Par beegees dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/10/2008, 22h36
  3. Réponses: 5
    Dernier message: 25/04/2008, 21h37
  4. Réponses: 7
    Dernier message: 03/03/2008, 08h47

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