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 :

Petit problème sur les pointeurs :


Sujet :

C++

  1. #1
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut Petit problème sur les pointeurs :
    Salut à tous,
    Je fais du c++ depuis quelques temps mais je bloque sur un problème qui me parait pourtant simple. Voici le code, puis j'explique où je ne comprends pas :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #include <iostream>
    #include <iomanip>
     
    using namespace std;
     
    //***** Première fonction 'création'
    int ** création ( int x, int y )
    {
    	int** tableau = new int*[y];
    	for ( int i =0; i < y; i++ )
    		tableau[i] = new int[x];
     
    	for ( int i = 0; i < y; i++ )
    		for ( int j =0; j < x; j++ )
    			tableau[i][j] = i + 10*j;
     
    	return tableau;
    }
     
    //***** Deuxième fonction 'création'
    void création ( int ** tableau, int x, int y )
    {
    	tableau = new int*[y];
    	for ( int i =0; i < y; i++ )
    		tableau[i] = new int[x];
     
    	for ( int i = 0; i < y; i++ )
    		for ( int j =0; j < x; j++ )
    			tableau[i][j] = i + 10*j;
    }
     
    void efface ( int ** tableau, int y )
    {
    	if ( tableau )
    	{
    		for ( int i = 0; i < y; i++ )
    			delete [] tableau[i];
    		delete [] tableau;
    		tableau = 0;
    	}
    }
     
    void affiche ( int ** tableau, int x, int y )
    {
    	if ( tableau )
    	{
    		cout << "Tableau :" << endl;
     
    		for ( int i = 0; i < y; i++ )
    		{
    			for ( int j =0; j < x; j++ )
    				cout << setw (3) << tableau[i][j];
    			cout << endl;
    		}
    	}
    }
     
    //****************
    //***** main *****
    //****************
    void main ()
    {
    	int ** tab01 = 0;
    	int ** tab02 = 0;
     
    	tab01 = création ( 3, 5 );
    	affiche ( tab01, 3, 5 );
     
    	création ( tab02, 4, 6 );//***** Pb ici *****
    	affiche ( tab02, 4, 6 );
     
    	efface ( tab01, 5 );
    	efface ( tab02, 6 );
     
    	system ("pause");
    }
    Mais pourquoi donc, après l'éxécution, dans 'main', de la ligne
    création ( tab02, 4, 6 );//***** Pb ici *****
    le pointeur tab02 reste-t-il désespérément vide alors que dans la fonction 'void création ( int ** tableau, int x, int y )', on initialise correctement la pointeur. Puisque l'opérateur new est utilisé, l'objet créé n'est pas éffacé à la fin de la fonction!! ( Où est-il donc passé? )

    Ici le problème est simplifié, mais dans un programme que j'écris, je crée une fonction qui dois initialiser 3 pointeurs comment faire?

  2. #2
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Je pense que tu dois passer un triple pointeur à ta fonction création. Sinon, ta variable tab02 n'est pas modifiée (ce sera une copie du double pointeur qui sera passée puis modifiée ) .

    Le principe est le même que quand ta fonction doit modifier un entier : tu passes un pointeur sur l'entier. Là tu dois modifier un double pointeur alors passe un pointeur sur le double pointeur

    Par contre ta première fonction création doit marcher.

  3. #3
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Oui, Bioche,
    La première fonction création marche à merveille... Mais, je ne comprends pas pourquoi la deuxième est inéfficace.
    Le but étant de faire une fonction du type 'MaFonction ( char** tab, MaClasse* objet1, SDL_Surface* aireDeJeu );' qui soit capable d'initialiser ces trois pointeurs fournis en arguments...
    Je ne comprends pas trop
    passe un pointeur sur le double pointeur
    , pour 'char** tab' ça donnerai quoi?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par bertry Voir le message
    Je ne comprends pas trop , pour 'char** tab' ça donnerai quoi?
    char ***tab

    mais cela devient dur à comprendre. Au fait, en C++, il y a les vector, c'est beuacoup plus clair et facile à comprendre

  5. #5
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Oui, ram-0000,
    En effet je peux utiliser un container, mais on s'égare :
    Ce sur quoi je bloque c'est : comment faire une fonction qui initialise 2 ou 3 pointeurs, du genre 'MaFonction ( char* pt1, MaClasse* pt2, SDL_Surface* pt3 );'
    J'ai un petit jeu qui fonctionnais bien jusqu'à que je me décide à regrouper toutes les initialisations dans une seule fonction.

    Je pensait regrouper trois fonctions du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char* Init1 ( ... ); //Qui initialise pt1
    MaClasse* Init2 ( ... ); //Qui initialise pt2
    SDL_Surface* Init3 ( ... ); //Qui initialise pt3
    en une seule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaFonction ( char* pt1, MaClasse* pt2, SDL_Surface* pt3 );
    Seulement voilà, si tout marche à merveille à l'intérieur de cette fonction, aucun des initialisations des pointeurs n'est conservée à la clôture de cette fonction!

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    Le prototype de ta fonction doit être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaFonction ( char** pt1, MaClasse** pt2, SDL_Surface** pt3 );
    Et a l'intérieur de ta fonction : *pt1 = new char[x] etc...

    Il faut voir le char** comme (char*)* à savoir un pointeur sur un char*
    Lorsque tu fais pt1 = new char[x], tu modifies la valeur de pt1. Donc si tu passes juste pt1, à la sortie de ta fonction, la modification ne sera pas prise en compte.

    Par contre, si tu passes l'adresse du pointeur, et que tu modifies la valeur pointée par cette adresse, là la modification sera effective !

    D'où le char** et non pas char*.

  7. #7
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Merci,
    Je vais voir avec ça.
    Il semble que ceci donne aussi un résultat correcte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaFonction ( char* &pt1, MaClasse* &pt2, SDL_Surface* &pt3 );
    ...
    Je vais faire des tests pour comparer...

  8. #8
    Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Points : 64
    Points
    64
    Par défaut
    Citation Envoyé par Bioche Voir le message
    Le prototype de ta fonction doit être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaFonction ( char** pt1, MaClasse** pt2, SDL_Surface** pt3 );
    Et a l'intérieur de ta fonction : *pt1 = new char[x] etc...
    Tu as quelque chose contre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaFonction ( char* & pt1, MaClasse* & pt2, SDL_Surface* & pt3 );
    Et a l'intérieur de ta fonction : pt1 = new char[x] etc...

    Le C++ nous autorise, contrairement au C, à passer les arguments par référence ; pourquoi les passer par valeur ?

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2011
    Messages : 13
    Points : 16
    Points
    16
    Par défaut
    Bien sûr, ça marche aussi. Mais bon, tant qu'à utiliser les pointeurs, autant les utiliser jusqu'au bout

  10. #10
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Points : 410
    Points
    410
    Par défaut
    Citation Envoyé par Bioche Voir le message
    En effet je peux utiliser un container, mais on s'égare :
    Citation Envoyé par Bioche Voir le message
    Bien sûr, ça marche aussi. Mais bon, tant qu'à utiliser les pointeurs, autant les utiliser jusqu'au bout
    Bonjour,

    Attention à ton raisonnement. Tu as un code qui marche et tu veux y toucher au minimum : on comprends.
    Tu ne veux pas tout refaire et y passer du temps alors que ça fonctionne aujourd'hui : on comprends.
    Tout développeur fait ce choix la régulièrement dans sa vie, parce qu'il y est bien obligé.

    Cela dit, il ne faut pas que ça t'empêche d'avoir conscience du gain que tu aurais (en maintenabilité et en réutilisabilité), d'opter pour une approche plus objet.

    En particulier, tu seras sans doute régulièrement amené à mettre en balance :
    - le temps que te prends le fait de tout changer pour une approche "plus correcte"
    versus
    - le temps de maintenance que tu feras perdre par la suite le fait d'avoir une approche "moins correcte"
    les valeurs "plus correcte" et "moins correcte" dépendent évidemment du problème que tu envisages.

    En général, en début de projet, c'est le premier qui gagne. En fin de projet sur de très gros projet c'est souvent le second, mais pas toujours.

    Pour moi, le code que tu as posté est très peu maintenable et faiblement lisible (je sais, c'est dur à entendre). L'utilisation de pointeurs, et de pointeurs de pointeurs (ou de références de pointeurs) s'inscrit dans cette absence de maintenabilité.

    Mon conseil donc : puisque tu sembles être au début du projet et que tu postes en section "débutant", ne te contente pas de résoudre ton problème pour que ça marche. Mais fait en sorte que ça marche, que ce soit lisible et que ce soit maintenable.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/03/2008, 22h04
  2. petit problème sur les listes chaînées
    Par poche dans le forum C
    Réponses: 14
    Dernier message: 19/03/2007, 16h53
  3. Petit problème avec les pointeurs et variable
    Par mitherkiller dans le forum C
    Réponses: 5
    Dernier message: 09/03/2007, 22h05
  4. Petite précision sur les pointeurs
    Par Fonzy007 dans le forum C
    Réponses: 2
    Dernier message: 07/12/2006, 11h25
  5. une petite question sur les pointeurs
    Par guy777 dans le forum C
    Réponses: 4
    Dernier message: 06/10/2006, 17h44

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