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 :

Problème argument de fonction


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Avril 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 12
    Par défaut Problème argument de fonction
    Bonjour, je suis entrain de faire un petit jeu mais je rencontre des problèmes lors des appels des fonctions dans mon main.c. J'ai créé un tableau[9][9] qui stocke le "niveau" du jeu et pour le moment j'essaye juste de déplacer des symboles d'une case x,y jusqu'à une autre dans ce même tableau, j'ai donc créé des fonctions de déplacement mais je rencontre une erreur pour l'argument (du tableau 9x9) lors de l'appel, ça ne compile pas.

    Voilà donc un bout de 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
    void verticalMove (char map[9][9], int fromX, int fromY, int toX, int toY)
    {
    	int l = 0;
     
    	if (toY < fromY) //Haut
    	{
    		for (l = (fromY - 1); l <= (toY - 1); l--)
    		{
    			if (map[l][fromX] != ' ')
    			{
    				printf("\nDeplacement impossible: un symbole bloque le passage\n");
     
    				return;
    			}
    		}
     
    		map[toY][toX] = map[fromY][fromX];
    		map[fromY][fromX] = ' ';
    	}
     
    	if (toY > fromY) //Bas
    	{
    		for (l = (fromY - 1); l <= (toY - 1); l++)
    		{
    			if (map[l][fromX] != ' ')
    			{
    				printf("\nDeplacement impossible: un symbole bloque le passage\n");
     
    				return;
    			}
    		}
     
    		map[toY][toX] = map[fromY][fromX];
    		map[fromY][fromX] = ' ';
    	}
    }
    Et je l'appel de cette façon dans le main: verticalMove(map, fromX, fromY, toX, toY);
    Avec map étant un char map[9][9] et les autres variables des int.

    Bon là dans le code, je suis conscient que ça ne changera rien dans mon tableau initial vu que je ne passe pas par adresse, mais c'est justement là le problème, j'ai essayé plusieurs combinaison mais à chaque fois ca plante à la compilation, ca me dis, l'argument de la fonction est un char (*)[9] mais un char [9][9] est fourni, des messages dans ce genre.

    Voilà, si quelqu'un pouvais m'aider, j'ai encore quelque problème avec les pointeurs et les passages par adresse, surtout lorsqu'il s'agit de tableau à double dimension.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Ce code compile parfaitement chez moi :
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    void verticalMove (char map[9][9], int fromX, int fromY, int toX, int toY)
    {
    	int l = 0;
     
    	if (toY < fromY) //Haut
    	{
    		for (l = (fromY - 1); l <= (toY - 1); l--)
    		{
    			if (map[l][fromX] != ' ')
    			{
    				printf("\nDeplacement impossible: un symbole bloque le passage\n");
     
    				return;
    			}
    		}
     
    		map[toY][toX] = map[fromY][fromX];
    		map[fromY][fromX] = ' ';
    	}
     
    	if (toY > fromY) //Bas
    	{
    		for (l = (fromY - 1); l <= (toY - 1); l++)
    		{
    			if (map[l][fromX] != ' ')
    			{
    				printf("\nDeplacement impossible: un symbole bloque le passage\n");
     
    				return;
    			}
    		}
     
    		map[toY][toX] = map[fromY][fromX];
    		map[fromY][fromX] = ' ';
    	}
    }
     
    int main()
    {
        char c[9][9];
        verticalMove(c, 1, 1, 2, 2);
        return 0;
    }
    Pourrais-tu nous donner l'ensemble du code ainsi que les messages (et lignes) donnés par le compilateurs?


    Sinon, lorsqu'on passe un tableau en argument d'une fonction, le tableau n'est pas copié, seul l'adresse l'est ainsi :
    - si tu passe un char[9], tu peux décider dans ta fonction que c'est un pointeur sur un char : char * ou un tableau de 9 char : char[9]

    - si tu passe un char[9][8], tu peux décider dans ta fonction que c'est un pointeur de pointeur sur un char : char ** ou un pointeur sur un tableau de 8 char : char (*)[8] ou un tableau à deux dimension : char [9][8]

    Ne pas confondre char (*)[] qui est un pointeur sur un tableau de char et char * [] qui est un tableau de pointeur sur des char.

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    - si tu passe un char[9][8], tu peux décider dans ta fonction que c'est un pointeur de pointeur sur un char : char ** ou un pointeur sur un tableau de 8 char : char (*)[8] ou un tableau à deux dimension : char [9][8]
    J'ai un doute sur le char**, qui n'est pas équivalent à un char (*)[] puisque l'un est un pointeur sur pointeur alors que l'autre est un pointeur sur un tableau. On en a parlé au début de la semaine ici.

    En reprenant le post de diogene, si le paramètre formel est de type char**, alors l'objet passé devra est de type tableau de pointeur ou pointeur sur pointeur ; mais pas un tableau de tableau de char. Si on compile, le code suivant :
    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
    #include <stdlib.h>
     
    void f1(char mat[][5])
    {
        mat[0][0] = 0;
    }
     
    void f2(char **pt)
    {
        pt = NULL;
    }
     
    int main(void)
    {
        char mat[5][5];
        char *tab[5];
     
        f1(mat);
        f2(mat);
     
        f1(tab);
        f2(tab);
     
        return 0;
    }
    On obtient les warning suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    d:\...\main.c||In function 'main':|
    d:\...\main.c|19|warning: passing argument 1 of 'f2' from incompatible pointer type|
    d:\...\main.c|8|note: expected 'char **' but argument is of type 'char (*)[5]'|
    d:\...\main.c|21|warning: passing argument 1 of 'f1' from incompatible pointer type|
    d:\...\main.c|3|note: expected 'char (*)[5]' but argument is of type 'char **'|
    ||=== Build finished: 0 errors, 2 warnings (0 minutes, 0 seconds) ===|
    Pour répondre à la question "pourquoi ça ne compile pas", il faudrait voir l'appel à la fonction, ainsi que la déclaration de l'objet qui est passé en paramètre.

  4. #4
    Expert confirmé
    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
    Par défaut
    Pour compléter la juste remarque de Bktero, on peut aussi critiquer cette phrase
    - si tu passe un char[9], tu peux décider dans ta fonction que c'est un pointeur sur un char : char * ou un tableau de 9 char : char[9]
    Que la déclaration soit f(char a[9]) ou f(char a[])ou f(char *a), a sera toujours un char * dans la fonction f().
    C'est le seul cas (c'est à dire dans une liste de déclaration de paramètres) où on peut indifféremment mettre une déclaration du genre tableau ou du genre pointeur.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Bktero Voir le message
    J'ai un doute sur le char**, qui n'est pas équivalent à un char (*)[] puisque l'un est un pointeur sur pointeur alors que l'autre est un pointeur sur un tableau.
    Je n'ai jamais dit qu'ils étaient équivalant, je me suis peut être mal exprimé.

    Ce que je voulais dire c'est que si on veut passer à une fonction x un char[][], on a trois choix de prototypes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void x(char x[9][9]);
    void x(char (*)[9]);
    void x(char **); // par contre là il faut faire un cast (char **) lors de l'appel.
    Après savoir quel est le meilleurs prototype... Je pense qu'il faut regarder au cas par cas.

    Citation Envoyé par diogene
    Que la déclaration soit f(char a[9]) ou f(char a[])ou f(char *a), a sera toujours un char * dans la fonction f().
    C'est le seul cas (c'est à dire dans une liste de déclaration de paramètres) où on peut indifféremment mettre une déclaration du genre tableau ou du genre pointeur.
    Je savais quel seul le pointeur était copié, mais je ne pensais pas qu'il était considéré en tant que pointeur et non en tant que tableau ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void f(char c[9])
    {
               sizeof(c); // = sizeof(char *);
    }

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Ce que je voulais dire c'est que si on veut passer à une fonction x un char[][], on a trois choix de prototypes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void x(char x[9][9]);
    void x(char (*)[9]);
    void x(char **); // par contre là il faut faire un cast (char **) lors de l'appel.
    Après savoir quel est le meilleurs prototype... Je pense qu'il faut regarder au cas par cas.
    Les deux premiers prototypes sont équivalents (dans le premier, le premier 9 a la valeur d'un commentaire.)

    Le deuxième par contre déclare une fonction bien différente. On ne peut pas lui passer un tableau de tableau (alias tableau bidimensionnel), il faut lui passer un tableau de pointeurs vers des tableaux de valeurs. Et lui passer une variable définie par un char tab[9][9] va poser des problèmes si tu castes pour éviter l'erreur que le compilateur te donnera pour te signifier que tu vas droit dans le mur.

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je pense que je viens de comprendre, les tableaux à plusieurs dimensions n'existent que lors de la compilation, lors de l’exécution ce ne sont que des tableaux à une dimension.

    Ainsi pour un tableau déclaré comme ceci : char c[3][3][3], char c[2] n'existe pas.

    Par contre lorsqu'on va faire : c[x][y]; ou &c[x][y] on va obtenir l'adresse de l'élément c[x][y][0] de même avec c[x] où on obtient l'adresse de l'élément c[x][0][0].
    Je suppose que c'est pour faciliter les affectations char * d = c[x][y] ?

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

Discussions similaires

  1. [XL-2010] Problème argument Date fonction perso VBA
    Par dams53 dans le forum Macros et VBA Excel
    Réponses: 14
    Dernier message: 07/05/2013, 21h54
  2. Problème argument dans fonction
    Par flo1411 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 06/05/2013, 04h37
  3. problème avec la fonction Find et un passage en argument
    Par paiva44 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 29/12/2009, 18h56
  4. Probléme argument pour une fonction d'un SLOT
    Par guillaume40 dans le forum Qt
    Réponses: 3
    Dernier message: 03/03/2008, 13h55
  5. Réponses: 3
    Dernier message: 23/08/2007, 00h39

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