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 :

Passage à une fonction d un array a deux dim mat[][] considéré comme pointeur


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 52
    Par défaut Passage à une fonction d un array a deux dim mat[][] considéré comme pointeur
    bonjour je n arrive pas a faire passer l argument mat à mes fonctions
    code blocks me dit que mat n'est ni un array ni un pointeur... comment faire ? merci


    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
    77
    78
    79
    80
    81
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    #include "main.h"
     
    const long MAX=100,MIN=0;
    int main()
    {
     
        long n=4,vect[n],mat[n][n];
        srand(time(NULL));
    	printf("calcul sur les vecteurs et matrices\n");
        printf("calcul aleatoire du vecteur et de la matrice\n");
        aleatvect(vect,n);
        affichevect(vect,n);
        aleatmat(mat,n);
        affichemat(mat,n);
        printf("calcul de la norme du vecteur");
        printf("%lf",normvect(vect,n));
     
    	return 0;
    }
     
     
    void aleatvect(long *vect, long n)  //cree un vecteur de nb entiers aleatoires
    {
        long i;
        for(i=0;i<n;i++)
        {
            vect[i]=rand()%(MAX-MIN+1)+MIN;
        }
    }
     
    void affichevect(long *vect,long n) //affiche les composantes du vecteur
    {
        long i;
        printf("affichage du vecteur :\n");
        for(i=0;i<n;i++)
        {
            printf("vect[%ld]=%ld\n",i,vect[i]);
        }
    }
     
    void aleatmat(long *mat,long n) // cree une matrice carree de nb entiers aleatoires
    {
        long i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                mat[i][j]=rand()%(MAX-MIN+1)+MIN;
            }
        }
    }
     
    void affichemat(long *mat, long n)  //affiche la matrice
    {
        long i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                printf("mat[%ld][%ld]=%ld\t",i,j,mat[i][j]);
            }
            printf("\n");
        }
    }
     
     
    double normvect(long *vect, long n) //calcule la norme du vecteur
    {
        long i;
        double norm=0.0;
        for(i=0;i<n;i++)
        {
            norm +=pow(vect[i],2);
        }
        return sqrt(norm);
    }

  2. #2
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Et en remplacant:
    par:
    ?
    En définissant "n" en globale et en compilant avec un compilateur c99.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 52
    Par défaut
    merci ça semble marcher même si mon header a du etre changé je ne peut plus mettre une dimmension n quelconque mais n=4 par exemple :

    void aleatvect(long *vect, long n);
    void affichevect(long *vect,long n);
    void aleatmat(long (*mat)[4],long n);
    void affichemat(long (*mat)[4], long n);
    double normvect(long *vect, long n);

    à moins que tu saches aussi resoudre ce pb

    une question : pourquoi ça marche ?merci

  4. #4
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    "n" indique la taille supposée du tableau passé en paramètre ce qui permet de la passer via "n" sans avoir un deuxième argument dans la 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
    #include<stdio.h>
    #include<stdlib.h>
     
    static int n; 
     
    void f(long (*t)[n]){
         printf("La taille de t est : %d\n",sizeof(*t)/sizeof(int));
         return;
         }
     
    int main(int argc,char* argv[])
    {
     
    n=10;
    long t[10][10];
     
    f(t);
     
    system("pause");
    return EXIT_SUCCESS;
    }
    Pour le header, peut être qu'en mettant à son début:
    Lorsqu'un tableau est indiqué en tant que paramètre d'une fonction il est remplacé par "un pointeur du type des éléments du tableau pointant sur le premier élément du tableau".
    Donc si "m" est un tableau à deux dimensions, un tableau de tableau en C, contenant des "long" il sera remplacé par "un pointeur sur un tableau de long", noté "long (*m)[]", pointant sur le premier sous tableau de "m".
    Les VLA (Variable Length Array) ont été ajouté au C avec la norme C99.
    Ils permettent de créer des tableaux dont la taille est évalué dynamiquement, qui donc n'est pas obligé d'être connue à la compilation.

  5. #5
    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
    Si on ne dispose pas d'un compilateur admettant les VLA, il est obligatoire de spécifier une constante dans la déclaration.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void aleatmat(long (*mat)[4],long n);
    est le prototype correct.
    Mais la fonction ne peut traiter que des tableaux de type long tab[...][4] ce qui est très restrictif. La raison est que le compilateur a besoin de cette dimension (4) pour calculer les adresses des éléments du tableau.
    Une possibilité pour s'affranchir de cette restriction est d'avoir une déclaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void aleatmat(long *mat,long n);
    mais dans ce cas,
    1- l'appel à cette fonction doit inclure un cast du tableau sur un long *
    2- la fonction ne peut plus utiliser la notation mat[i][j] et le programmeur doit à la place coder lui-même le calcul des adresses : mat[i*n+j]

  6. #6
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Et il faut aussi indiquer l'autre dimension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void aleatmat(long *mat,long n,long m);
    1- l'appel à cette fonction doit inclure un cast du tableau sur un long *
    Ou passer l'adresse du 1er élement du 1er sous tableau.
    D'ailleurs est-ce que la norme garantie que le cast d'un "long(*)[]" en "long*" donne ce résultat?

  7. #7
    Membre éclairé
    Inscrit en
    Août 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Août 2006
    Messages : 38
    Par défaut
    pourquoi ne pas utiliser simplement en paramètre un long **mat qu'on aurait alloué dynamiquement dans le main.

    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
     
    int main()
    {
        int i;
        long n = 4, *vect, **mat;
     
        vect = (long *) malloc(n * sizeof(long));
     
        mat = (long **) malloc(n * sizeof(long *));
        for (i = 0; i < n; i++)
          mat[i] = (long *) malloc(n * sizeof(long));
     
     
        srand((int) time(NULL));
     
     
        printf("calcul sur les vecteurs et matrices\n");
     
        printf("\ncalcul aleatoire du vecteur et de la matrice\n");
     
        aleatvect(vect, n);
        affichevect(vect, n);
     
        aleatmat(mat, n);
        affichemat(mat, n);
     
        printf("\ncalcul de la norme du vecteur\n");
        printf("%lf", normvect(vect, n));
     
        return 0;
    }
     
    void aleatmat(long **mat, long n) // cree une matrice carree de nb entiers aleatoires
    {
        long i, j;
     
        for (i = 0; i < n; i++)
            for (j = 0; j < n; j++)
                mat[i][j] = rand() / ((double) RAND_MAX) * (MAX - MIN) + MIN;
    }
     
    void affichemat(long **mat, long n)  //affiche la matrice
    {
        long i, j;
     
        printf("\naffichage de la matrice :\n");
        for( i = 0; i < n; i++)
        {
            for(j = 0; j < n; j++)
                printf("mat[%ld][%ld]=%ld\t", i, j, mat[i][j]);
            printf("\n");
        }
    }

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Parce que c'est pas si facile que ça à allouer. Moi, je serais plutôt pour la thèse "une allocation par dimension" :
    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
    long ** AllocTab2Dim(size_t dim1, size_t dim2)
    {
    	long ** ppRetour = calloc(dim1, sizeof(*ppRetour));
    	if(ppRetour)
    	{
    		long * pLongs = calloc(dim1*dim2, sizeof(*pLongs));
    		if(pLongs)
    		{
    			size_t i;
    			for(i=0 ; i<dim1 ; i++)
    				ppRetour[i] = pLongs+(i*dim2);
    		}
    		else
    		{
    			free(ppRetour);
    			ppRetour = NULL;
    		}
    	}
    	return ppRetour;
    }
     
     
    void FreeTab2Dim(long **ppLongs)
    {
    	free(*ppLongs);
    	free(ppLongs);
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Passage d'une fonction en tant que paramètre
    Par bagnolm dans le forum Langage
    Réponses: 3
    Dernier message: 28/11/2006, 15h58
  2. Réponses: 17
    Dernier message: 15/05/2006, 17h18
  3. Trace ascii du passage dans une fonction
    Par ryko dans le forum Delphi
    Réponses: 4
    Dernier message: 10/05/2006, 21h06
  4. [FLASH 8] Pb passage d'une fonction en paramètre
    Par segphault dans le forum Flash
    Réponses: 2
    Dernier message: 17/02/2006, 11h14
  5. Problème avec une fonction et un array
    Par Neal Morse dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/08/2005, 12h04

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