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 :

Votre avis pour améliorer mon code (opérations matricielles)


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut Votre avis pour améliorer mon code (opérations matricielles)
    Bonjour,

    Je suis débutant en C et également nouveau sur ce forum, c'est pour cette raison que j'aurais voulu avoir des conseils pour l'amélioration de mes codes.
    Mon projet consiste, à terme, à réaliser un programme d'ajustement de courbe expérimental avec équations théoriques, pour une application dans le domaine de la physique. J'ai choisis la méthode des moindres carrées pour réalisé mon projet : http://fr.wikipedia.org/wiki/M%C3%A9...es_carr%C3%A9s
    et plus particulièrement la méthode matricielle.

    J'ai donc redéfinie des fonctions qui opère sur des matrices, j'en ai fais trois, une qui transpose la matrice, une permettant effectuer des produits de matrices, et la dernière qui fais l'inverse de la matrice par la méthode du pivot de Gauss.

    Je vais donc commencer par mettre ici mon code de transposée, pour avoir quelques conseils sur celui ci :

    Mon 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
    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
    96
    97
    98
    99
    100
    101
    #include <stdio.h>
     
    #include <stdlib.h>
    #include <math.h>
     
    #include "fonctions.h"
     
     
     
    int main()
     
    {
        int nbreligneA = 0, nbrecolonneA = 0, i = 0, j = 0;
     
        //Valeurs test :
     
        nbreligneA = 3;
        nbrecolonneA = 2;
     
     
        //Matrice A et T
     
        double **A = malloc(nbreligneA * sizeof(double));
        for (i = 0; i < nbreligneA; i++)
        {
            A[i] = malloc(nbrecolonneA*sizeof(double));
        }
     
        double **T ;
     
     
        //Valeurs test(suite) :
     
        A[0][0] = 1;
        A[0][1] = 2;
        A[1][0] = 3;
        A[1][1] = 4;
        A[2][0] = 5;
        A[2][1] = 6;
     
     
        //Création des structures pour ces matrices
     
        Matrice As = {A, nbreligneA, nbrecolonneA};
        Matrice Ts = {T, 0, 0};
     
        //Creation pointeurs vers ces structures
     
        Matrice *pAs = &As;
        Matrice *pTs = &Ts;
     
        //Envois de ces pointeurs à la fonction Transposée
     
        Transposee(pAs, pTs);
     
        //Affichage provisoire de l'essais
     
        for (i = 0; i < As.nbreligne; i++)
        {
            printf("\n|");
     
            for (j = 0; j < As.nbrecolonne; j++)
            {
                printf(" %f", As.matrice[i][j]);
            }
     
            printf(" |");
     
        }
     
        printf("\n\n");
     
        for (i = 0; i < Ts.nbreligne; i++)
        {
            printf("\n|");
     
            for (j = 0; j < Ts.nbrecolonne; j++)
            {
                printf(" %f ", Ts.matrice[i][j]);
            }
     
            printf(" |");
        }
     
        //On libère l'espace pour les matrice A et T
     
        for (i = 0; i < nbreligneA; i++)
        {
            free(A[i]);
        }
        free(A);
     
        for (i = 0; i < Ts.nbreligne; i++)
        {
            free(Ts.matrice[i]);
        }
        free(Ts.matrice);
     
        return 0;
     
    }
    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
    65
    66
    67
    68
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    #include "fonctions.h"
     
    struct Matrice *Transposee(struct Matrice *A, struct Matrice *T)
    {
        int i = 0, j = 0;
     
        //Allocation pour matrice provisoir de travail
     
        double **Ap = malloc(A->nbreligne*sizeof(double));
        for (i = 0; i < A->nbreligne; i++)
        {
            Ap[i] = malloc(A->nbrecolonne*sizeof(double));
        }
     
        //Structure de matrice provisoire
     
        Matrice Aps = {Ap, A->nbreligne, A->nbrecolonne};
     
        //Copie Matrice A dans Ap
     
        for (i = 0; i < Aps.nbreligne; i++)
        {
            for (j = 0; j < Aps.nbrecolonne; j++)
            {
                Ap[i][j] = A->matrice[i][j];
            }
        }
     
        //Allocation de T en fonction de A (ou Aps puisque copie)
     
        T->matrice = malloc(Aps.nbrecolonne*sizeof(double));
        for (i = 0; i < Aps.nbrecolonne; i++)
        {
            T->matrice[i] = malloc(Aps.nbreligne*sizeof(double));
        }
     
        //On remplace le nombre de lignes et de colonnes dans la structure Ts présente dans le main
     
        T->nbreligne = Aps.nbrecolonne;
        T->nbrecolonne = Aps.nbreligne;
     
     
        //Transposé à partir de la matrice provisoire
     
        for (i = 0; i < T->nbreligne; i++)
        {
            for (j = 0; j < T->nbrecolonne; j++)
            {
                T->matrice[i][j] = Aps.matrice[j][i];
            }
        }
     
        //On libère l'espace de la matrice Ap
     
        for (i = 0; i < Aps.nbreligne; i++)
        {
            free(Aps.matrice[i]);
        }
        free(Aps.matrice);
     
        //On retourne T pointeur vers la matrice d'accueil du résultat
     
        return T;
    }
    et les structures et prototypes :

    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
    #ifndef FONCTIONS_H_INCLUDED
     
    #define FONCTIONS_H_INCLUDED
     
    //Protos
     
    struct Matrice *Transposee(struct Matrice *A, struct Matrice *T);
     
     
    //Structures
     
     
    typedef struct Matrice Matrice;
    struct Matrice
    {
        double **matrice;
        int nbreligne;
        int nbrecolonne;
    };
     
     
     
    #endif // FONCTIONS_H_INCLUDED
    Voilà, je remercie d'avance ceux qui me lirons, et les remercies pour leur éventuel conseils.

  2. #2
    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
        int nbreligneA = 0, nbrecolonneA = 0, i = 0, j = 0;
    Ces initialisations sont inutiles et non pertinentes puisque soit ces valeurs sont changées quelques lignes plus loin, soit elles sont utilisées comme compteur de boucles dans un for et sont initialisées à ce moment là.
    Je ne suis pas partisan des initialisations systématiques (contrairement à d'autres personnes) mais uniquement lorsqu'elles sont utiles (notamment parce que (1) ça empêche certains warnings du compilateur et (2) ça peut éviter au programme de planter franchement si la véritable initialisation n'a pas été faite (3) ça peut tromper le lecteur en fournissant une information fausse)

    -- Ceci est faux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       double **A = malloc(nbreligneA * sizeof(double));
    on devrait avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       double *A = malloc(nbreligneA * sizeof(double));
    // ou
       double **A = malloc(nbreligneA * sizeof(double*));
    (en fait, c'est le second cas dans ton code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Matrice *pAs = &As;
        Matrice *pTs = &Ts; 
        //Envois de ces pointeurs à la fonction Transposée 
        Transposee(pAs, pTs);
    Je ne suis pas non plus partisan de créer des pointeurs inutilement qui obligent le lecteur à retrouver leur valeur. Personnellement, je préfère ici
    -- Je conseille de structurer un peu le code :

    - Faire une fonction pour construire une Matrice et en profiter pour la coder correctement en testant les allocations.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Matrice * CreerMatrice(int nbreligne,int nbrecolonne)
    {
        double **A = malloc(nbreligne * sizeof(double *));
        // et tester toutes les allocations 
        // En cas d'échec d'une allocation : 
        // libérer les allocations réussies et renvoyer NULL
    /*    for (i = 0; i < nbreligne; i++)
        {
            A[i] = malloc(nbrecolonne*sizeof(double));
        }*/
    return A;
    - Faire une fonction de destruction d'une Matrice
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void DetruireMatrice(Matrice * matrice)
    {
       if(matrice != NULL)
    ....
    }
    - Faire une fonction d'affichage d'une Matrice
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void AfficheMatrice(Matrice * matrice, FILE * out)
    {
       if(matrice != NULL)
    ....
    }
    Le main() devient alors :
    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
    int main(void) 
    {
      Matrice * T;  
      Matrice * A = CreerMatrice(3,2);
      if(A != NULL)
      {
        A[0][0] = 1;
        A[0][1] = 2;
        A[1][0] = 3;
        A[1][1] = 4;
        A[2][0] = 5;
        A[2][1] = 6;
        AfficheMatrice(A,stdout);
        T = Transposee(A);
        AfficheMatrice(T,stdout);
        DetruireMatrice(A);
        DetruireMatrice(T);
      }   
    }
    Avec la fonction Transposee() (pourquoi passer par une Matrice temporaire ??) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Matrice *Transposee(Matrice *A)
    {
       Matrice * T = NULL;  
       if(A != NULL)
       {
          T = CreerMatrice( A->nbrecolonne, A->nbreligne);
          if(T != NULL)      
             for (i = 0; i < T->nbreligne; i++)
                for (j = 0; j < T->nbrecolonne; j++) T->matrice[i][j] = A->matrice[j][i];
       }
       return T;
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Merci beaucoup diogene d'avoir pris le temps de répondre avec autant de détails, je vais m'efforcer de corriger tout cela, dans les deux autres codes aussi, puisqu'il sont codé sur le même exemple.

    Pour ce qui est de la matrice provisoire elle était là, (si je le souvient bien, je l'ai codé il y a un petit moment), pour permettre d'effectuer la transposée de la transposée, bien entendu faire cela n'a pas grand intérêt mais c'était pour s'entrainer à coder une fonction qui pouvais se prendre en paramètre. Mais peu être que cette matrice temporaire est inutile même dans ce cas ... je vais y réfléchir.

    Merci encore.


    Edit : J'ai juste une petite question, peu être idiote, mais si je n'envoies pas en paramètre un pointeurs vers une matrice qui recueil ma transposé, et que ma transposé renvois comme dans ton exemple un pointeur sur une structure créé dans la fonction, je ne comprend pas comment dans le main on retrouve cette structure comprenant la matrice, n'est telle pas supprimé au moment de la sortie de la fonction (puisque créé via malloc dans cette fonction) ? Ou alors le malloc permet de garder tout cela en mémoire entre temps ... ? J'aurais besoin qu'on éclaire ma lanterne sur ce point.

  4. #4
    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
    - Les variables en allocation automatique (variables locales) sont créées à l'entrée du bloc {} où elles sont définies et seront détruites en sortie du bloc.

    - Les variables en allocation statique (variables globales ou variables déclarées static) sont créées au lancement du programme et seront détruites en fin d'exécution du programme

    - Les variables en allocation dynamique sont créées par malloc() (ou consoeurs) et ne sont détruites que par appel à free(). Ce sont les seules qui demandent une création/destruction explicite.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    D'accord merci beaucoup, c'était un point un peu obscur pour moi, ça devrais me permettre de réalisé les choses bien plus simplement normalement.

    Je reposte lorsque j'aurais modifié tout cela.

  6. #6
    Invité
    Invité(e)
    Par défaut
    on devrait avoir
    Code :

    double *A = malloc(nbreligneA * sizeof(double));
    // ou
    double **A = malloc(nbreligneA * sizeof(double*));

    (en fait, c'est le second cas dans ton code)
    Je crois qu'il vaudrait mieux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double **A = (double**)malloc(nbreligneA * sizeof(double*));

  7. #7
    Invité
    Invité(e)
    Par défaut
    Je vais vous donner mon avis.
    Il y a une application de la méthode des moindres carrés qui est l'ajustement d'un ensemble de points pour trouver, une parmi quatre, la fonction qui satisfait le mieux, c'est à dire pour laquelle la somme des carrés des écarts est minimale.
    Les formules sont connues.
    Ceci offre deux avantages, d'abord vous savez exactement ce que vous codez, et surtout, l'outil, une fois terminé, vous servira fréquemment dans le domaine de la physique.
    Si cela vous intéresse, je posterai une copie du document avec les explications et les formules.

  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
    Citation Envoyé par Pierre Dolez Voir le message
    Je crois qu'il vaudrait mieux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      double **A = (double**)malloc(nbreligneA * sizeof(double*));
    Le cast est absolument inutile en C (et certains le trouvent plutôt néfaste).
    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
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Oui merci beaucoup cela pourrais m'être très utile, car je ne sais pas encore dans quel domaine je vais appliquer ce programme.

    J'avais fais un test avec les fonctions que j'avais créé, transposée, produit matriciel et inversion avec méthode de Gauss et cela a fonctionné sur une simple droite, mais je n'ai pas fais d'autres test. La technique que j'emploie ici consiste à créé des matrices de dimension nombre de points par nombre de constantes à déterminer plus une matrice d'incertitudes sur les mesures. J'ai envie pour le moment de créé un programme pour ajuster uniquement des courbe de couple (torque) d'aimantation dans le domaine du nanomagnétisme, et dans ces conditions l'équation de base est déjà connu, il s'agit d'une équation linéaire composé de somme de sinus/cosinus, et ce qui nous intéresse c'est de déterminer les constantes de ce matériaux magnétique. Il existe bien entendu des logiciel qui font cela très bien, mais j'avais envie de coder un ptit truc à moi pour m'exercer.

    Mais si vous disposer d'un document plus général sur le codage de la méthode des moindres carrées je serais content d'y jeter un œil.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Non, en fait, ce n'est pas un document général, mais une application dans le cas de quatre fonctions (linéaire, exponentielle, logarithmique et puissance).

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Oui oui c'est bien à cela que je pensais quand j'ai dis "plus général", mais c'est très bien cela m'intéresse également.

    Merci.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Voila le document. Le titre est "Ajustement de courbes" Source Hewlett-Packard (1979 N° 00041-90028)
    Images attachées Images attachées  

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Merci

    J'ai une petite question encore, sur ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Matrice * CreerMatrice(int nbreligne,int nbrecolonne)
    {
        double **A = malloc(nbreligne * sizeof(double *));
        // et tester toutes les allocations 
        // En cas d'échec d'une allocation : 
        // libérer les allocations réussies et renvoyer NULL
    /*    for (i = 0; i < nbreligne; i++)
        {
            A[i] = malloc(nbrecolonne*sizeof(double));
        }*/
    return A;
    Je ne comprend pas comment tester toutes les allocations, je pensais qu'il suffisait de vérifier que le premier malloc ne renvoyais pas NULL. J'aimerais bien avoir quelque infos sur ce sujet.
    Merci.

    Ah ... je crois avoir trouvé la solution à mon problème dans "Description des mécanismes d'allocation dynamique de mémoire en langage C par Romuald Perrot (Cyber-Avenue)"
    ici même.

    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
    int **matrice , i;
    matrice = malloc( 3 * sizeof(int*));
    if( matrice == NULL )
    {
         fprintf(stderr,"Allocation impossible");
         exit(EXIT_FAILURE);
    }
    for( i = 0 ; i < 3 ; i++ )
    {
         matrice[i] = calloc (3, sizeof(int));
         if( matrice[i] == NULL )
         {
              fprintf(stderr,"Allocation impossible");
              exit(EXIT_FAILURE);
         }
    }
    /* remplissage */
    for( i = 0 ; i<3 ; i++ )
         matrice[i][i] = 1;
    Donc je pense que c'est bon.

  14. #14
    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
    Ce code est incorrect : si une erreur d'allocation a lieu dans la boucle for, alors la mémoire précédemment allouée n'est pas libérée (notamment pas celle de matrice ).

    De plus, il est préférable en cas d'échec d'allocation de renvoyer NULL et de laisser au programme appelant la liberté d'agir en conséquence plutôt que d'imposer un message intempestif et une sortie brutale du programme.

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Matrice * CreerMatrice(int nbreligne,int nbrecolonne)
    {
        int i;
        Matrice *  mat = malloc(sizeof (Matrice));
        if( mat != NULL)
        {
            mat->nbreligne  = nbreligne ;
            mat->nbrecolonne = nbrecolonne;
            mat->matrice =  malloc(nbreligne * sizeof (double *));
            if( mat->matrice != NULL)
            {
               mat->matrice[0] = malloc(nbreligne*  nbrecolonne * sizeof (double));
               if(mat->matrice[0] != NULL)
               {
                   for (i = 1; i < nbreligne; i++) mat->matrice[i] = mat->matrice[i-1] + nbrecolonne;
               }
               else
               {
                  DetruireMatrice(mat);
                  mat = NULL;
               }
            }
            else
            {
               DetruireMatrice(mat);
               mat = NULL;
            }
        }
       return mat;
    }
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void DetruireMatrice(Matrice * mat)
    {
       if(mat != NULL)
       {
         if(mat->matrice!= NULL)
         {
            free(mat->matrice[0]);
            free(mat->matrice);
         }
         free(mat);
       }
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Merci diogène, ton code semble en effet plus propre je vais l'étudier avec attention dès demain.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    J'ai bien observé ce code, je vais énuméré ce que j'y ai compris car il me semble essentiel de bien assimiler ces notions avant de poursuivre (l'allocation dynamique me paraissait simple au début je m'aperçois qu'en fin de compte j'ai pas compris grand chose )

    J'ai placé en commentaire ce que j'ai crus comprendre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Matrice * CreerMatrice(int nbreligne,int nbrecolonne)
    {
        int i;
        Matrice *  mat = malloc(sizeof (Matrice)); /*allocation pour la taille
     d'une structure de type Matrice*/
        if( mat != NULL) //Vérification que l'allocation à fonctionné
        {
            mat->nbreligne  = nbreligne ; /*On remplace chaque éléments de la 
    structure par leurs valeurs*/
            mat->nbrecolonne = nbrecolonne;
            mat->matrice =  malloc(nbreligne * sizeof (double *));/*On
     alloue la mémoire pour autant de pointeur sur double qu'il y a de lignes*/
            if( mat->matrice != NULL) //On vérifie que l'alloc à fonctionné
    J'avoue que ensuite le code est obscure pour moi, peu tu me l'expliquer que j'assimile bien tout cela ?

  17. #17
    Invité
    Invité(e)
    Par défaut
    Un bon moyen de comprendre un code est de l'exécuter, voir ce qu'il donne, faire des modifs, regarder encore, jusqu'à avoir tout compris.
    D'autre part, il me parait illusoire de vouloir apprendre un langage sans essayer d'exécuter le binaire, une fois compilé et lié.

  18. #18
    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
    @Schopenhauer
    J'avoue que ensuite le code est obscure pour moi, peu tu me l'expliquer que j'assimile bien tout cela ?
    Une fois que le tableau de pointeurs est alloué, tu as deux solutions :

    1- Pour chaque pointeur tu alloues la quantité mémoire pour un ligne. Tu fais nbreligne allocations de nbrecolonne éléments (que tu dois vérifier) et tu as autant de libération à faire. En mémoire, chaque ligne se situe sans rapport avec les autres.

    ou

    2- Tu alloues d'un coup la quantité totale dont tu as besoin (nbreligne*nbrecolonne éléments) et tu mets dans chaque pointeur l'adresse du début de chaque ligne (qui est décalée par rapport au début de la précédente de nbrecolonne éléments). Tu n'as alors qu'une allocation à faire (et à vérifier) et une libération à faire. En mémoire, les lignes sont contigues comme dans un tableau 2D.
    C'est cette solution que j'ai codée.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Août 2010
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 42
    Points : 21
    Points
    21
    Par défaut
    Ahhh ! ... J'avais pourtant suivit le conseil du post précédent, j'ai exécuté le code et j'ai, mis des printf aux endroits clé pour observé les adresses, mais je n'ai pas vue ça ! C'est cool merci !
    Je ne devrais plus t'embêter avant un petit moment maintenant, merci encore .

  20. #20
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Petit complément à l'explication de Diogène.
    La première technique est utilisée pour les très gros tableaux, comme les rasters. Dans les librairies utilisant ce type de données (en tout cas, celles que je connais) le seul moyen d'adresser un pixel, c'est à dire une case, est l'utilisation d'une fonction ScanLine() qui renvoie un pointeur sur la lignes recherchée.

    La seconde technique est utilisée pour les petits tableaux comme les matrices d'application, c'est à dire le cas présent. C'est naturellement beaucoup plus facile de travailler au niveau de cases. Par exemple, un échange ligne <-> colonne se fera comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    float t=tab[il][ic];
    tab[il][ic] = tab[ic][il];
    tab{ic][il]=t;

Discussions similaires

  1. [Débutant] idée pour améliorer mon code ?
    Par Imène_23 dans le forum MATLAB
    Réponses: 7
    Dernier message: 27/08/2011, 23h54
  2. avis pour améliorer mon cv
    Par Nath_k dans le forum CV
    Réponses: 4
    Dernier message: 20/09/2009, 12h45
  3. Réponses: 30
    Dernier message: 05/08/2009, 19h25
  4. [CV] Avis pour améliorer mon cv
    Par lapanne dans le forum CV
    Réponses: 7
    Dernier message: 17/10/2007, 15h04
  5. Réponses: 4
    Dernier message: 26/04/2006, 14h36

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