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 :

Tableau de pointeurs qui change


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 18
    Points
    18
    Par défaut Tableau de pointeurs qui change
    Bonjours,

    Je passe un tableau de pointeurs en paramètre d'une fonction, qui a été préalablement initialisé à certaines valeurs, et quand je le récupère dans le fonction les valeurs ne sont plus les même ! :s


    Voilà mon code :

    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
    void kruskal2 (struct arc* sommets [], struct arc* kruskal [], int nbrSommets) {
    	int *peres [nbrSommets];
    	int i, nbrArcs=0;
     
    	for (i=0; i<nbrSommets; i++) {
    		peres [i]=&i;
    	}
    for (i=0; i<nbrSommets; i++) {
    printf ("peres [%d]=%d.\n", i, *peres [i]);
    }
     
    	while (nbrArcs<nbrSommets-1) {
    printf ("Je suis dans le while, nbrArcs=%d.\n", nbrArcs);
    for (i=0; i<nbrSommets; i++) {
    printf ("peres [%d]=%d.\n", i, *peres [i]);
    }
    		nbrArcs=arcMin2 (sommets, kruskal, nbrSommets, peres, nbrArcs);
    	}
    }
     
    int arcMin2 (struct arc* sommets [], struct arc* kruskal [], int nbrSommets, int *peres [], int nbrArcs) {
    	int racineD, racineA, sommetD, sommetA, poid, sommetDTemp, sommetATemp, poidTemp=-1, i;
    printf ("Je passe dans arcMin2.\n");
    for (i=0; i<nbrSommets; i++) {
    printf ("peres [%d]=%d.\n", i, *peres [i]);
    }
     
    	for (i=0; i<nbrSommets; i++) {
    		if (poidTemp==-1 || sommets[i]->poid<poid) {
    			sommetDTemp=i+1;
    			sommetATemp=sommets[i]->sommetArrive;
    			poidTemp=sommets[i]->poid;
     
    			racineD=pere (peres, sommetDTemp);
    			racineA=pere (peres, sommetATemp);
     
    			if (racineD==racineA) {
    				poid=-1;
    			}
    			else {
    				sommetD=sommetDTemp;
    				sommetA=sommetATemp;
    				poid=poidTemp;
    			}
    		}
    	}
     
    	insererArc (kruskal, sommetD, sommetA, poid);
    	insererArc (kruskal, sommetA, sommetD, poid);
     
    	*peres [sommetA-1]=sommetD-1;
     
    	return nbrArcs+1;
    }
    Je ne sais pas si ça peut aider, mais voilà ce que j'optient à l'éxecution :

    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
    peres [0]=0.
    peres [1]=1.
    peres [2]=2.
    peres [3]=3.
    peres [4]=4.
    peres [5]=5.
    peres [6]=6.
    peres [7]=7.
    peres [8]=8.
    peres [9]=9.
    peres [10]=10.
    peres [11]=11.
    Je suis dans le while, nbrArcs=0.
    peres [0]=0.
    peres [1]=1.
    peres [2]=2.
    peres [3]=3.
    peres [4]=4.
    peres [5]=5.
    peres [6]=6.
    peres [7]=7.
    peres [8]=8.
    peres [9]=9.
    peres [10]=10.
    peres [11]=11.
    Je passe dans arcMin2.
    peres [0]=12.
    peres [1]=12.
    peres [2]=12.
    peres [3]=12.
    peres [4]=12.
    peres [5]=12.
    peres [6]=12.
    peres [7]=12.
    peres [8]=12.
    peres [9]=12.
    peres [10]=12.
    peres [11]=12.
    Est-ce que quelqu'un aurait une idée ?

    J'ai une autre question qui n'a rien à voir. Pour l'écriture dans un fichier je voudrais pouvoir me déplacer afin d'écrire quelque chose au début du fichier après avoir écrit la fin. J'ai essayé avec la fonction fseek, sauf que quand j'écris ce que j'ai à écrire ça efface les caractères suivant, et comme je ne connais pas d'avance la taille de ce que j'ai besoin d'écrire je ne peux pas laisser suffisament de "caractères à effacer".


    Merci d'avance pour votre aide.

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Janvier 2011
    Messages : 247
    Points : 163
    Points
    163
    Par défaut
    D'abord ton code est TRES mal indenté donc on y comprend pas grand chose!D'après ce que je j'ai pu lire peres est un tableau de int*, donc quand tu le passes en paramètre, si tu veux afficher les valeurs contenues dans les int* tu dois faire *(peres[i]). Essaye ça.
    Pour écrire dans le fichier je crois que le plus simple serait de tout recopier dans un autre que tu crées toi-même et qui peut remplacer l'original...

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void kruskal2 (....)
    {	
       int *peres [nbrSommets];
       int i, nbrArcs=0;
       for (i=0; i<nbrSommets; i++) 
       { 
           peres [i]=&i;
       }
    ....
    Tous les éléments du tableau contiennent la même valeur, à savoir l'adresse de i.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ....
    for (i=0; i<nbrSommets; i++) 
    {
        printf ("peres [%d]=%d.\n", i, *peres [i]);
    }
    Comme peres [i]=&i alors *peres [i] ==*&i == i
    Donc on affiche la valeur de i qui varie de 0 à nbrSommets-1.
    c'est équivalent à printf ("peres [%d]=%d.\n", i, i);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (nbrArcs<nbrSommets-1) 
    {
        printf ("Je suis dans le while, nbrArcs=%d.\n", nbrArcs);
       for (i=0; i<nbrSommets; i++) 
       {
          printf ("peres [%d]=%d.\n", i, *peres [i]);
        }
        nbrArcs=arcMin2 (sommets, kruskal, nbrSommets, peres, nbrArcs);
    Ici i est égal à nbrSommets (12) en sortie de boucle for et peres contient toujours l'adresse de i dans tous ses éléments. arcMin2 affichera 12 partout.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    sinon pour ne pas écraser ton fichier texte à chaque nouvelle phrase à insérer, et comme on parle C, tu peux utiliser les appels systèmes pour créer ton fichier (i-e open au lieu de fopen) et je crois me souvenir qu'il y a un flag (une macro) du genre O_TRUNC que tu peux passer en paramètre à open pour obtenir le résultat que tu souhaite. Dans les autres appels systèmes tu as seek aussi.

    Google t'en dira plus sur ces appels encore plus bas niveau.


    et +1 pour diogene.
    Nullius in verba

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    @ dré kam

    Les trois boucles for avec le printf sont juste là pour le débugage, c'est pour ça qu'elle ne sont pas indentées.
    Pour le fichier, c'est pas top parce que c'est pour un cours d'algo, et le but c'eset de faire un algo qui vas le plus vite possible, et là ça reviendrait à faire deux fois la même chose, ce qui n'est pas top niveau complexité ! :s Mais dans un autre contexte c'est sûrement ce que j'aurais fait, donc merci quand même.


    @diogene

    Vu comme ça, c'est évident que ça ne fasse pas ce que je souhaite ! :s

    Je viens de contourner le problème en mettant les valeurs dans un tableau de int (pas pointeurs), puis en "égalisant" ce tableau ave le tableau de pointeurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void kruskal2 (struct arc* sommets [], struct arc* kruskal [], int nbrSommets) {
    	int *peres [nbrSommets], t [nbrSommets];
    	int i, nbrArcs=0;
     
    	for (i=0; i<nbrSommets; i++) {
    		t [i]=i;
    		peres [i]=&t [i];
    	}
    ...
    Si tu as une meilleur solution à me proposer je suis prenneur !


    @ Kaamui

    Oki, merci pour l'info, je vais chercher de ce côté.



    Merci pour votre aide à tous.

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Si tu as une meilleur solution à me proposer je suis prenneur !
    Je ne sais pas trop ce que tu veux faire, donc il est difficile de répondre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	for (i=0; i<nbrSommets; i++) {
    		t [i]=i;
    		peres [i]=&t [i];
    	}
    Si peres n'est pas ultérieurement modifié (que fait la fonction pere() ?) , à quoi sert-il ? Si on connait t[] on connait le contenu de peres (peres[i]== t+i).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    Si tu ne c'est pas ce que je souhaite faire, tu ne risque pas de m'aider !...


    J'ai un ensemble de sommets, le tableau peres représente l'ensemble des ensembles de sommets.
    ie : les indices du tableau représente les sommets, et les cases leurs pères.
    Au début tous les sommets sont isolés, donc il n'ont pas de père, c'est pourquoi j'initialisele tableau de 0 à nbrSommets-1 (la convention que l'on utilise c'est que si un sommet n'a pas de père, alors il est son propre père).
    Après pour faire l'union d'ensemble de sommets, la racine d'un des ensembles prend pour père la racine de l'autre ensemble. Donc si peres[] est modifié (ligne 51 du code de mon premier poste).

    La fonction pere() (qui devrait plutôt s'appeler racine()) renvois la racine de l'ensemble auquel appartient le sommet

  8. #8
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Donc si peres[] est modifié (ligne 51 du code de mon premier poste).
    Pas du tout, la ligne 51 est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *peres [sommetA-1]=sommetD-1;
    peres[sommetA-1] n'est pas modifié, c'est *peres [sommetA-1] qui l'est.
    Cette ligne ne modifie pas le tableau peres[].

    Les indices du tableau représente les sommets, et les cases leurs pères.
    Si je comprend, les sommets sont repérés par des entiers (les indices). Mais, les pères, qui sont codés par le contenu des éléments du tableau, sont-ils aussi codés par un entier (indice de l'élément du tableau qui représente le sommet père) ou par un pointeur sur l'élément du tableau qui représente ce sommet ? (je pose la question pour savoir pourquoi peres est un tableau de pointeur).

    La structure des données utilisée est, pour comprendre un code, essentielle.
    La description de la structure des données que tu utilises est trop succinte pour que quelqu'un qui ne connait pas ton projet puisse vraiment comprendre ton code.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    Oui, les adresses de peres restent toujours identiques, c'est les case mémoires qui changent.

    Les pères sont codés par des entiers.

    je pose la question pour savoir pourquoi peres est un tableau de pointeur
    J'ai mit un tableau de pointeurs car, de ce que j'ai put lire (dans les livres ou sur internet), le c'est le seul moyen de pouvoir passer un tableau en paramétre d'un fonction et de le récuperé modifié à la sortie.

  10. #10
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Je me doutais bien qu'il y avait anguille sous roche.
    J'ai mit un tableau de pointeurs car, de ce que j'ai put lire (dans les livres ou sur internet), le c'est le seul moyen de pouvoir passer un tableau en paramétre d'un fonction et de le récuperé modifié à la sortie.
    C'est faux. Ou tu as mal compris, ou tu peux jeter tes bouquins et changer de sites d'informations sur internet.
    Lorqu'on passe un tableau à une fonction, on passe l'adresse de son premier élément. De là, on a l'adresse de tous les éléments et donc on peut les modifier.

    Exemple :

    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
    void fonc(int * tab, int n)
     // ou équivalent DANS UN PROTOTYPE de fonction :void fonc(int tab[], int n)
    {
      int i;
      for(i=0;i<n;i++) tab[i] = i;
    }
    #define N 10
    int main(void)
    { 
       int tab[10] = {0};
       // tab contient maintenant {0,0,0,0,0,0,0,0,0,0}
       fonc(tab, N);
       // tab contient maintenant {0,1,2,3,4,5,6,7,8,9}
       return 0;
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Points : 18
    Points
    18
    Par défaut
    Oki d'ac, bah c'est peut être moi qui ai mal compris, ou fait une généralité d'un cas particulier. :s

    Est ça marche aussi de la même manière pour un tableau à deux dimensions ?

  12. #12
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Est ça marche aussi de la même manière pour un tableau à deux dimensions ?
    Oui. (dans ce cas les éléments sont eux-mêmes des tableaux à une dimension)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

Discussions similaires

  1. Callback qui change des pointeurs
    Par phantomlibre dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 07/02/2014, 19h57
  2. Réponses: 5
    Dernier message: 01/04/2012, 20h58
  3. Réponses: 2
    Dernier message: 26/02/2009, 10h52
  4. Liens dans un tableau qui change le contenu d'un autre case da ce tableu
    Par maxtofurious dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 13/06/2007, 17h09
  5. Réponses: 3
    Dernier message: 22/07/2002, 14h19

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