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 :

Pointeur de tableau - Problème


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 9
    Par défaut Pointeur de tableau - Problème
    Bonjour tout le monde. Je suis débutant en C et je bloque sur un exercice qui consiste à utiliser une fonction qui renvoie un pointeur vers un tableau.

    Prototype: int (*ecLectDates (int *pNbrLues)) [3];.

    Donc, cette fonction est censé renvoyer un pointeur pointant sur un tableau de 3 entiers.

    Voici ma fonction:

    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
    int (*ecLectDates (int *pNbrLues)) [3]
    {
    	char cQuit;
    	int dNbreIntrod;
    	int (*pTab)[3];
    	int dCpt;
    	int tTab[10][3];
     
     
     
    	/*Intitialisation des dates lues*/
     
    	*pNbrLues = 0;
     
    	/*-------------------------------------------------------------------
    	Invitation à introduire le nbre de dates maximales souhaité
    	--------------------------------------------------------------------*/
     
     
     
    	do
    	{
    		printf ("Veuillez introduire le nombre de dates souhaitées: ");
    		scanf("%d", &dNbreIntrod);
    	}
     
    	while (dNbreIntrod < 1);
     
    	pTab = tTab;
     
     
     
    	/*--------------------------------------------------------------------------------------------
    	Invitation à saisir les dates
    	----------------------------------------------------------------------------------------------*/
     
    		do  
    		{			
    			do
    			{
    				printf("\nVeuillez entrer la date: ");
    				scanf("%d-%d-%d", &pTab[*pNbrLues][0], &pTab[*pNbrLues][1], &pTab[*pNbrLues][2]); 
    				fflush(stdin);
    			}
    			while (pTab[*pNbrLues][0] < 1 || pTab[*pNbrLues][0] > 30 || pTab[*pNbrLues][1] < 1 || pTab[*pNbrLues][1] > 12|| pTab[*pNbrLues][2] < 1900);
     
    			printf("\nLa date entrée est correcte");
     
    			*pNbrLues = *pNbrLues + 1;
     
    			printf("\nVoulez-vous quitter? Tapez Q:  ");
    			cQuit = getchar();
    			fflush(stdin);
    		}
    		while (cQuit != 'Q' && *pNbrLues < dNbreIntrod);
     
    	printf("Tableau: %d \n", pTab[0][0]);
    	printf("Tableau: %d \n", pTab[0][1]);
    	printf("Tableau: %d \n\n", pTab[0][2]);
     
    	return pTab;
     
     
    }

    Les 3 printf de fin servent à voir si le tableau contient bien les valeurs que j'ai introduite dans la fonction. A ce niveau là, c'est ok. Mais quand je renvois le pointeur de tableau à mon main, les valeurs ne correspondent plus à ce que j'avais dans ma fonction. Ce qui me fait évidemment dire qu'il y a un soucis au niveau du renvoi de pTab. Ou lors de la réception de pTab.
    Pour mon main, je place pTab dans un pointeur de tableau, comme suit:

    MAIN

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int (*pTab)[3];
    pTab = ecLectDates(&dDatesLues);

    Voilà, il y a sûrement un gros truc honteux qui m'a échappé et que vous n'allez pas manquer de me faire remarquer.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MrMasure Voir le message
    Donc, cette fonction est censé renvoyer un pointeur pointant sur un tableau de 3 entiers.

    Voici ma fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int (*ecLectDates (int *pNbrLues)) [3]
    {
    	int (*pTab)[3];
    	int tTab[10][3];
    
    	pTab = tTab;
    	return pTab;
    }
    Voilà, il y a sûrement un gros truc honteux qui m'a échappé et que vous n'allez pas manquer de me faire remarquer.
    Bonjour

    Juste un seul: si tu as un tableau de 3 entiers, pourquoi dans ta fonction tu définis 10 tableaux de 3 entiers ???

    Ceci dit, même si la syntaxe était parfaite, la conception, elle, ne peut pas fonctionner. En effet, tu n'as pas le droit de renvoyer l'adresse d'une variable locale. Ou plutôt tu peux le faire mais comme la variable est détruite quand la fonction se termine, tu récupères au final une adresse qui ne correspond à plus rien de valide.

    Tu n'as que 2 façons de faire
    1. tu définis ton tableau avant d'appeler la fonction et tu passes à celle-ci ledit tableau qu'elle peut alors remplir. Elle n'a alors rien à renvoyer (sauf peut-être un flag indiquant si tout s'est bien passé)
    2. ta fonction crée le tableau de façon dynamique en mémoire via malloc() et renvoie l'adresse du tableau créé. La différence c'est que l'allocation mémoire se fait dans une zone qui n'est pas gérée de la même façon et n'est pas détruite quand la fonction se termine. Mais c'est alors à toi de libérer manuellement (via free()) la mémoire allouée quand tu n'en auras plus besoin.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 9
    Par défaut
    Merci pour la réponse claire rapide. En fait, je dois me diriger vers la 2ème façon que tu as proposé mais en utilisant les pointeurs de tableau.
    Et c'est bien de plusieurs pointeurs dont j'ai besoin.
    Pour le tTab[10][3], je voulais à allouer dynamiquement comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int (*pTab)[3];
    pTab = (int*) malloc (dNbreIntrod *  sizeof(int));
    Mais visiblement une telle allocation n'est pas possible. Et puis, je me suis embourbé dans d'autres trucs foireux...

    En résumé, je cherche vraiment à "simuler" un tableau à 2 dimensions en utilisant les pointeurs de tableau. Je suppose que la clé réside dans cette allocation dynamique de mes pointeurs pointant sur les tableaux de taille 3.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MrMasure Voir le message
    En résumé, je cherche vraiment à "simuler" un tableau à 2 dimensions en utilisant les pointeurs de tableau. Je suppose que la clé réside dans cette allocation dynamique de mes pointeurs pointant sur les tableaux de taille 3.
    Tu alloues 10 pointeurs, chaque pointeur allouant 3 int
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int **ppTab;
     
    ppTab=malloc(10 * sizeof(int*));
    for (i=0; i < 10; i++)
        ppTab[i]=malloc(3 * sizeof(int));

    Ensuite, tu peux taper dans ppTab[x][y], x variant de 0 à 9 et y variant de 0 à 3.
    Bien entendu, il faut aussi penser à vérifier chaque malloc et prévoir une solution au cas où ne serait-ce qu'un seul d'entre eux échouerait. Puis en final, penser à libérer chaque malloc.

    Ou alors tu alloues une seule zone de 30 int
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *pTab;
    pTab=malloc(10 * 3 * sizeof(int));

    Ensuite pour accéder à pTab[x][y], te faut convertir pTab[x][y] (2D) en pTab[z] (1D) en utilisant la formule z=3*x+y. Et pour convertir pTab[z] en pTab[x][y] c'est x=z/3 et y=z%3. L'avantage c'est qu'il n'y a qu'un seul malloc à gérer donc un seul free.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre habitué
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 9
    Par défaut
    Si je pouvais utiliser des pointeurs de pointeurs, ça me faciliterait la vie. Mais, malheureusement, je dois vraiment respecter le prototype donné au départ (int (*ecLectDates (int *pNbrLues)) [3]).

    En prenant en considération que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int tab[6][5]; // tableau de 6 fois 5 entiers.  
    int (*pTab)[5]= tab;
    pt[2][3] = 1;

    J'aimerais arriver à la même chose mais avec tab qui serait dynamique, pas statique. Est-ce que c'est possible? D'une manière ou d'une autre?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par MrMasure Voir le message
    J'aimerais arriver à la même chose mais avec tab qui serait dynamique, pas statique. Est-ce que c'est possible? D'une manière ou d'une autre?
    Postulat de base: tu n'as absolument pas le droit de renvoyer l'adresse d'une variable locale. Et les statiques sont à manipuler avec précaution car tu ne peux pas utiliser une fonction qui utilise des statiques dans deux boucles imbriquées style
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for (...)
    {
    	fct_utilisant_des_statiques();
    	for (...)
    	{
    		fct_utilisant_des_statiques();
    	}
    }
    Car le second appel modifie la statique (qui reste unique) et au retour du premier for, la statiques modifiée par le second ne correspond plus à ce qu'il faut

    Donc la seule solution est le malloc. Ceci dit, ce n'est pas interdit de faire du malloc de tableaux...
    Code c : 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
    #include <stdio.h>
    #include <stdlib.h>
     
    int (*fct())[3]
    {
    	int i, j;
    	int (*pt)[3];
    	pt=malloc(5 * sizeof(int[3]));
    	if (pt == NULL) return NULL;
    	for (i=0; i < 5; i++)
    	{
    		for (j=0; j < 3; j++)
    			pt[i][j]=i*j;
    	}
     
    	return pt;
    }
     
    int main(int argc, char* argv[]){
    	int (*tab)[3];
    	int i, j;
    	tab=fct();
    	if (tab != NULL)
    	{
    		for (i=0; i < 5; i++)
    		{
    			for (j=0; j < 3; j++)
    				printf("tab[%d][%d]=%d\n", i, j , tab[i][j]);
    		}
    		free(tab);
    	}
     
    	return 0;
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Problème de pointeur sur tableau
    Par franklin626 dans le forum Ada
    Réponses: 2
    Dernier message: 21/04/2009, 22h32
  2. Réponses: 4
    Dernier message: 28/05/2008, 00h55
  3. convertion pointeur vers tableau
    Par gdpasmini dans le forum C++
    Réponses: 2
    Dernier message: 30/03/2006, 00h34
  4. [HTML] Tableau problème de formatage avec internet Explorer
    Par rabobsky dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 18/11/2005, 09h50
  5. Pointeur et TAbleau
    Par melmouj dans le forum C
    Réponses: 20
    Dernier message: 25/09/2005, 16h13

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