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 :

return tableau 2d et fonction parametre tableau 2d


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 45
    Par défaut return tableau 2d et fonction parametre tableau 2d
    Bonjour,

    Je suis encore un débutant en c. (j'ai un claver qwerty, dsl pour les accents)

    Je chercher un moyen pour retourner un tableau 2D dans mon main grace a la fonction Matrice. mais je ne sais pas comment faire ?
    Puis j'aimerais que ma deuxieme fonction Multimatrice puisse prendre en parametre un tableau 2D et un tableau 1D pour retourner un tableau 1D.

    La fonction Matrice retourne une matrice inverse forme grace aux coefficients donne en parametre.
    La fonction Multimatrice multiplie deux matrices. Une matrice carre et une matrice colonne et retourne matrice colonne.

    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "Inverseur.h"
    #include "Multimatrice.h"
    #include <math.h>
     
    struct Parametre
    {
      double Longueur;
      int Nbrepoints;
      int tend;
      double Re;
    };
     
    int main(void)
    {
      struct Parametre p = {2.,81,2,100.};
     
      double dx= (double) p.Longueur/( (double) p.Nbrepoints-1);
      double dt=dx/2.;
      double a = -dt/(p.Re*pow(dx,2));
      double b = 1+2*dt/(p.Re*pow(dx,2));
      double c = -dt/(p.Re*pow(dx,2));
      double*x=NULL,*B=NULL, *u=NULL;	
      /**
         dynamic allocation 
      */
      x= calloc(p.Nbrepoints,sizeof(double));
      u= calloc(p.Nbrepoints,sizeof(double));
      B= calloc(p.Nbrepoints, sizeof(double));
     
      /** 
         dynamic allocation 2D table
      */
     
      double **Ainv = (double **)malloc(sizeof(double*)*p.Nbrepoints);
      double *tableau2 = (double *)malloc(sizeof(double)*p.Nbrepoints*p.Nbrepoints);
      for(int i = 0 ; i < p.Nbrepoints ; i++)
    	Ainv[i] = &tableau2[i*p.Nbrepoints];
     
      /**
         initial elevation: a "bump", position 
      */
      double t=0.;
      for(int i=0; i<p.Nbrepoints;i++)
        {
          x[i+1] = x[i] + dx;
          u[i] = 1.;
        }
      for(int i =10; i<20;i++)
        u[i]=2.;
      /** 
          Boundaries Conditions 
      */
      u[0]=1.;
      u[p.Nbrepoints]=1.;
     
      /** 
          Matrice B
      */
      for (int i=1;i<p.Nbrepoints-1;i++){
        B[i] = (dt/dx)*(u[i-1]-u[i])+u[i];
      }
      B[0] = u[0];
      B[p.Nbrepoints] = u[p.Nbrepoints];
    /**
       Matrice inverse
    */
      Ainv = Matrice(&p.Nbrepoints, &a, &b, &c);
     
    /**
       begin the time loop
    */
      FILE *fic = fopen("data.txt", "w");
      fprintf(fic, "%s %s %s\n", "#x", "#u", "#t");
     
      while(t<=p.tend){
        for(int i=0;i<p.Nbrepoints;i++)
          fprintf(fic, "%g %g %g\n", x[i], u[i], t);
        fflush(fic);
        u=Multimatrice(Ainv,B,&p.Nbrepoints);
        memcpy(u,B,sizeof(double)*p.Nbrepoints);
        fprintf(fic,"\n\n");
        t+=dt;
      }
     
      free(x);
      free(u);
      free(B);
      fclose(fic);
      free(tableau2);
      free(Ainv);
      return 0;
    }
    Le code de la fonction Matrice :
    Cette fonction prend en parametre un entier qui est la taille du tableau carre puis deux doubles qui sont des coefficients. Puis retourne mon tableau 2D.

    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
    #include <stdio.h>
    #include "Inverseur.h"
     
    double *Matrice(int *taille, double *un, double *deux, double *trois){
    /* Declaration variable qui contient la valeur de la variable pointee **/
    	int n = *taille;
    	int a = *un;
    	int b = *deux;
    	int c = *trois;
    /* Initialisation tableau 2d + determinant +  **/
    	double mat[n][n];
    	double determinant = 0.;
    	static double **Inverse;
     
    /* Init **/
     
    	for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    			mat[i][j]=0.;
     
    /* Boundaries Conditions **/
     
    	mat[0][0]=1.;
    	mat[n][n]=1.;
     
    /* Matrice coefficients **/
     
    	for (int i=1; i<n-1; i++){
    		mat[i][i]=b;
    		mat[i-1][i]=a;
    		mat[i][i+1]=c;
    	}
    #if 0
     
    	printf("Enter elements of matrix row wise:\n");
    	for(int i = 0; i < n; i++)
    		for(int j = 0; j < n; j++)
               scanf("%le", &mat[i][j]);
     
    	printf("\nGiven matrix is:");
    	for(int i = 0; i < n; i++){
    		printf("\n");
     
    		for(int j = 0; j < n; j++)
    			printf("%g\t", mat[i][j]);
    	}
    #endif
    	//finding determinant
    	for(int i = 0; i < n; i++)
    		determinant = determinant + (mat[0][i] * (mat[1][(i+1)%n] * mat[2][(i+2)%n] - mat[1][(i+2)%n] * mat[2][(i+1)%n]));
    	if(determinant == 0)
    		printf("%s","Attention determinant egale a 0");
     
    	//printf("\n\ndeterminant: %f\n", determinant);
     
    	//printf("\nInverse of matrix is: \n");
    	for(int i = 0; i < n; i++){
    		for(int j = 0; j < n; j++)
    			Inverse[i][j]=((mat[(j+1)%n][(i+1)%n] * mat[(j+2)%n][(i+2)%n]) - (mat[(j+1)%n][(i+2)%n] * mat[(j+2)%n][(i+1)%n]))/ determinant;
     
    	}
    #if 0
    	for(int i = 0; i < n; i++){
    		printf("\n");
     
    		for(int j = 0; j < n; j++)
    			printf("%g\t", Inverse[i][j]);
    	}
    	printf("\n");
    #endif
       return Inverse;
    }
    Le code de la fonction Multimatrice : cette fonction prend en parametre mon tableau carre 2D, un tableau 1D et la taille du tableau.

    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
    #include <stdlib.h>
    #include "Multimatrice.h"
     
    double **Multimatrice(double **mat1, double *mat2, int *taille){
      int n = *taille;
      double *mul=NULL;
      mul = calloc(n, sizeof(double));
      //static double mul[taille];
      for(int i = 0; i < n; i++)
        {
    	for(int k = 0; k < n; k++)
    	{
    	   	mul[i] += mat1[i][k] * mat2[k];
    	}	
        }
      return mul;
    }
    Je sais que je fais des grosses erreurs sur la gestions des pointeurs et de la memoire mais je me perds un peu.
    Puis dans mes fonctions je pense que je dois mieux initialiser mes tableau avec des allocation dynamqiques mais j'aimerais avoir vos conseills.
    Je vous en remercie !

    Voici le resultats de ma compilation :

    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
    burger1D.c: In function ‘main’:
    burger1D.c:70:8: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
       Ainv = Matrice(&p.Nbrepoints, &a, &b, &c);
            ^
    burger1D.c:82:6: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         u=Multimatrice(Ainv,B,&p.Nbrepoints);
          ^
    Inverseur.c: In function ‘Matrice’:
    Inverseur.c:71:11: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
        return Inverse;
               ^~~~~~~
    Multimatrice.c: In function ‘Multimatrice’:
    Multimatrice.c:16:10: warning: return from incompatible pointer type [-Wincompatible-pointer-types]
       return mul;
              ^~~
    /tmp/cc3nEme4.o*: Dans la fonction «*main*»*:
    burger1D.c:(.text+0xc3)*: référence indéfinie vers «*pow*»
    burger1D.c:(.text+0x122)*: référence indéfinie vers «*pow*»
    burger1D.c:(.text+0x195)*: référence indéfinie vers «*pow*»
    collect2: error: ld returned 1 exit status

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Suntory Voir le message
    Je suis encore un débutant en c.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      double **Ainv = (double **)malloc(sizeof(double*)*p.Nbrepoints);
      double *tableau2 = (double *)malloc(sizeof(double)*p.Nbrepoints*p.Nbrepoints);
      for(int i = 0 ; i < p.Nbrepoints ; i++)
    	Ainv[i] = &tableau2[i*p.Nbrepoints];
    Ca, et le reste aussi, c'est clair que ce n'est pas un code de débutant !!!

    Citation Envoyé par Suntory Voir le message
    Je chercher un moyen pour retourner un tableau 2D dans mon main grace a la fonction Matrice. mais je ne sais pas comment faire ?
    Ce n'est malheureusement pas possible, un tableau C est un truc trop complexe pour être retourné.
    En revanche, tu peux parfaitement créer un pointeur double **tab dans ta fonction Matrice() que tu alloues avec p pointeurs, et ensuite chaque pointeur est lui-même alloué avec d doubles. Cela ressemble à de la 2D mais ça reste de la 1D (un tableau en 1D de pointeurs, et chaque pointeur étant un tableau 1D de doubles => tout est en 1D). Ensuite tu retournes le tab (et dans ce cas ce n'est pas un tableau que tu retournes mais un simple pointeur) à l'appelant qui peut toutefois s'en servir comme un tableau 2D (il peut taper dans tab[x][y] ce qui placera alors le bouzin sur le pointeur tab[x] puis de là, ira sur le double [y].
    Le souci, c'est que ta fonction Matrice est prévue pour retourner un double * alors qu'il lui faut retourner un double **. Tous tes ennuis de compilation viennent de là. Car même si ce sont tous deux des adresses, ce ne sont pas le même genre d'adresses et ne peuvent pas (et ne doivent pas) être confondus. Un truc * ce n'est pas un truc **, et un truc ** ce n'est pas un truc ***.

    Citation Envoyé par Suntory Voir le message
    Puis j'aimerais que ma deuxieme fonction Multimatrice puisse prendre en parametre un tableau 2D et un tableau 1D pour retourner un tableau 1D.
    Pareil, elle définit un double *tab, le remplit et le retourne. Et doit alors être de type double * et non double **.
    Accessoirement il y a un petit schisme sur le cast du malloc. Certains préfèrent le mettre pour des raisons qui sont tout à fait valides et d'autres (dont je fais partie) ont autant de raisons valides de ne pas le mettre. Donc j'en parle mais tu restes libre sur ce point. Et tu n'es pas obligé de caster en double tes opérandes dans les divisions. Il suffit que l'un des deux soit déjà double (et c'est le cas) pour que la division entière se fasse en double.
    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 averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2018
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2018
    Messages : 45
    Par défaut
    Re-bonjour,

    Merci beaucoup pour ta reponse. Je comprends mieux mon probleme.
    Enfaite c'est comme des poupee russes mais avec des tableaux 1D que je remplis avec mes fonctions grace aux pointeurs.

    Je suis tombe sur ceci et c'est tres interessant :

    https://stackoverflow.com/questions/...nsional-arrays

    J'ai pas encore eu le temps de re-bosser dessus. Je reviendrais poster un message avec des ameliorations.
    Merci,
    a+

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Suntory Voir le message
    Re-bonjour,
    Pas besoin, une fois suffit

    Citation Envoyé par Suntory Voir le message
    Enfaite c'est comme des poupee russes mais avec des tableaux 1D que je remplis avec mes fonctions grace aux pointeurs.
    Il y a aussi une autre technologie: tout gérer en interne en 1D. En effet, un tableau 2D, c'est simplement des lignes empilées. Si tu mets toutes ces lignes "à plat", tu te retrouves avec une seule et unique énorme ligne qui fait tout le tableau. De là, par simple calcul mathématique, tu peux convertir des coordonnées 2D (ex tab[x][y]) en indice 1D (tab[x * taille_ligne + y]) et inversementconvertir un indice 1D (ex tab[i]) en coordonnées 2D (tab[i / taille_ligne][i % taille_ligne]).
    L'avantage de cette technologie (qui peut être extrapolée sur n dimensions), c'est que tu ne fais qu'un seul et unique malloc de p*d doubles au lieu d'allouer p pointeurs puis d'allouer p fois d doubles (surtout qu'en théorie, chaque allocation doit être testée et si une seule échoue, faut alors tout libérer ce qui a été alloué en amont).
    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. [PHP 5.3] Return tableau vide
    Par Bastien10 dans le forum Langage
    Réponses: 2
    Dernier message: 21/03/2012, 16h52
  2. Return tableau d'entiers
    Par mailbox dans le forum Débuter
    Réponses: 5
    Dernier message: 11/11/2010, 00h02
  3. [C# 2.0] Une fonction parametrée en remplacement de code.
    Par Pierre8r dans le forum Windows Forms
    Réponses: 1
    Dernier message: 31/05/2006, 14h06
  4. fonctions parametres
    Par Mat 74 dans le forum C++
    Réponses: 11
    Dernier message: 12/01/2005, 14h13
  5. [VBA-W] [AUTOMATION]Liste Fonctions/Paramètres
    Par Sunny dans le forum VBA Word
    Réponses: 2
    Dernier message: 05/12/2002, 16h35

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