affectation de valeur aux éléments d'une matrice

affectation de valeur aux éléments d'une matrice - C - Programmation

Marsh Posté le 11-05-2005 à 20:34:39    

une petite partie d'un code permettant de chnger quelques valeurs d'une matrice initialement nulle :
 
int matriceD (dPoint2D *p,matrice *la_matrice){
   matrice mat;
alloc_matrice(&mat,4,4);
intmatrice(mat);
 
mat[0][2]=p->y;
mat[1][3]=34;
 
*la_matrice=mat;
afficherMatrice(*la_matrice);
 
}
int main()
  matrice mat;
    matrice tmat;
    alloc_matrice(&mat,4,4);
Point2D p;    
    p.x=3;
    p.y=2;
  intmatrice(mat);
  matriceQ(&p,&mat);
  afficherMatrice(mat);
 return EXIT_SUCCESS;
  }
 
 
comme résultat j'la matrice suivante :
 0.000000 0.000000 2.000000 0.000000
 0.000000 0.000000 0.000000 34.000000
 34.000000 0.000000 0.000000 0.000000
 0.000000 0.000000 0.000000 0.000000
 
Ma question c pourquoi y 2 fois 34 alors que je n'ai demandé que d'affecter mat[1][3] par 34 !
voilà!
merci d'avance!

Reply

Marsh Posté le 11-05-2005 à 20:34:39   

Reply

Marsh Posté le 11-05-2005 à 20:59:58    

sam15 a écrit :

une petite partie d'un code


On veut tout le code réduit au minimum compilable montrant le défaut. L'erreur peut avoir des origines diverses...
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-05-2005 à 21:42:52    

ok ! je vais ajouter les fonctions qui manquent  
 double **matrice;
 typedef struct dPoint2D {
  double x;
  double y;
} dPoint2D;
 
 
 
 
double** alloc_matrice(matrice *mat,int xsize,int ysize){
 
  register int i;
 *mat=(matrice) malloc( sizeof(int *) * ysize );
  if ((*mat)==NULL) printf("probleme d'allocation memoire" );
 
 for(i=0;i<ysize;i++){
   (*mat)[i] =(double*) malloc( sizeof(int) *xsize );
    if ((*mat)[i]==NULL) printf("probleme d'allocation memoire" );
 
  }
 
return *mat;
}
 
 
 
void afficherMatrice(matrice mat){
  int i,j;
 
  for (i=0;i<4;i++){
    // printf("\n" );
    for (j=0;j<4;j++){
 
      printf(" %f",mat[i][j]);
 
    }
     printf("\n" );
}
}
 

Reply

Marsh Posté le 11-05-2005 à 21:48:31    

Citation :

if ((*mat)==NULL) printf("probleme d'allocation memoire" );


chouette, on sait pourquoi ca plante (si ca s'affiche)
 

Citation :

*mat=(matrice) malloc( sizeof(int *) * ysize );


what ?
cast inutile et sizeof **mat tellement plus prudent
 

Citation :

printf("\n" );


 :love:  
putchar par exemple

Reply

Marsh Posté le 11-05-2005 à 22:10:08    

je crois avoir cerné l'origine du mauvais calcul ! à priori c'est la fonction allocation ! pourtant j'ai cru bien appliquer tes conseils( je m'adresse à  "Emmanuel D elahaye" ).

Reply

Marsh Posté le 11-05-2005 à 23:40:47    

sam15 a écrit :

je crois avoir cerné l'origine du mauvais calcul ! à priori c'est la fonction allocation ! pourtant j'ai cru bien appliquer tes conseils( je m'adresse à  "Emmanuel Delahaye" ).


( Alors utilise le bouton [ ]-> )
 
Ton code est gravement endommagé... Commence par ça. Si tu ne comprends pas pose des questions.


#include <stdlib.h>
#include <stdio.h>
 
typedef double **matrice;
 
void free_matrice (matrice mat, int xsize, int ysize)
{
   int i;
   for (i = 0; i < ysize; i++)
   {
      free (mat[i]), mat[i] = NULL;
   }
   free (mat), mat = NULL;
}
 
matrice alloc_matrice (int xsize, int ysize)
{
   int i;
   matrice mat = malloc (sizeof *mat * ysize);
 
   if (mat == NULL)
   {
      printf ("probleme d'allocation memoire\n" );
   }
   else
   {
      int err = 0;
      for (i = 0; i < ysize; i++)
      {
         mat[i] = malloc (sizeof mat[i] * xsize);
         if (mat[i] == NULL)
         {
            printf ("probleme d'allocation memoire\n" );
            err = 1;
         }
      }
 
      if (err)
      {
         free_matrice (mat, xsize, ysize), mat = NULL;
      }
   }
   return mat;
}
 
void afficherMatrice (matrice mat, int xsize, int ysize)
{
   int i, j;
 
   for (i = 0; i < ysize; i++)
   {
      for (j = 0; j < xsize; j++)
      {
         printf (" %f", mat[i][j]);
      }
      printf ("\n" );
   }
}
 
void init_matrice (matrice mat, int xsize, int ysize)
{
   int i;
 
   for (i = 0; i < ysize; i++)
   {
      int j;
 
      for (j = 0; j < xsize; j++)
      {
         mat[i][j] = 0;
      }
   }
}
 
int main (void)
{
   int x = 4;
   int y = 4;
   matrice mat = alloc_matrice (x, y);
   if (mat != NULL)
   {
      init_matrice (mat, x, y);
      afficherMatrice (mat, x, y);
      free_matrice (mat, x, y), mat = NULL;
   }
   return EXIT_SUCCESS;
}


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-05-2005 à 10:18:43    

Bonjour,
 
Petite question stupide concernant le passage de tableaux en parametre de fonction. Je lis ici et la que le C n'autorise pas le passage d'un tableau en parametre a une fonction. J'aimerai juste comprendre pourquoi le code suivant fonctionne:
 

Code :
  1. #include <stdio.h>
  2. void printMatrix(double matrix[2][2])
  3. {
  4.   int i,j;
  5.   for (i=0; i<2; i++) {
  6.     for (j=0; j<2; j++)
  7.       printf("%f ", matrix[i][j]);
  8.     printf("\n" );
  9.   }
  10. }
  11. void changeMatrix(double matrix[2][2])
  12. {
  13.   int i,j;
  14.   double htmp[2][2];
  15.   htmp[0][0] = 10.0;         htmp[0][1] = 20.0;
  16.   htmp[1][0] = matrix[0][0]; htmp[1][1] = matrix[0][1];
  17.   for (i=0; i<2; i++)
  18.     for (j=0; j<2; j++)
  19.       matrix[i][j] = htmp[i][j];
  20. }
  21. int main(int argc, char* argv[])
  22. {
  23.   double testMatrix[2][2] = {{1.0, 2.0},{3.0, 4.0}};
  24.   printMatrix(testMatrix);
  25.   changeMatrix(testMatrix);
  26.   printMatrix(testMatrix);
  27.   return 0;
  28. }


 
Ok c'est laid, les arguments etant passes par copie, je risque d'avoir rapidemment des problemes de memoire. Mais qu'y a t'il de fondammentalement mauvais dans ce code?  :??:  
Merci d'avance pour vos reponses, et mes excuses pour les accents!

Reply

Marsh Posté le 20-05-2005 à 10:42:44    

Non il n'y a pas de copie du tableau, lors de l'appel de fonction ton tableau est implicitement converti en pointeur sur l'adresse de se dernier (tu peux faire &testMatrix d'ailleurs c'est pareil)
 
Puis comme dans ta fonction tu a précisé que c'était un tableau, tu vas pouvoir l'utiliser comme tel (ça permet de simplifier l'écriture).
 
Mais tu n'utilises donc qu'un "pointeur", pas de copie du tableau, la preuve, le tableau original est modifié par tes fonctions.
 
PS : le deuxième argument du tableau dans ta fonction est indispensable pour savoir combien d'élément "sauté" pour passer à la ligne suivante mais le premier est inutile.

Reply

Marsh Posté le 20-05-2005 à 11:03:13    

Mich-- a écrit :

Petite question stupide concernant le passage de tableaux en parametre de fonction. Je lis ici et la que le C n'autorise pas le passage d'un tableau en parametre a une fonction. J'aimerai juste comprendre pourquoi le code suivant fonctionne:


http://mapage.noos.fr/emdel/notes.htm#param_tab


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-05-2005 à 14:04:20    

Dans le code que tu donnes Emmanuel, ca veut dire quoi la virgule de cette ligne ?
 

Code :
  1. free (mat[i]), mat[i] = NULL;


 
J'ai pas fait de C depuis longtemps (Java all the time :x) et je ne me souviens pas avoir déjà vu ca :x


Message édité par c0wb0y le 20-05-2005 à 14:05:06
Reply

Marsh Posté le 20-05-2005 à 14:04:20   

Reply

Marsh Posté le 20-05-2005 à 14:25:09    

c0wb0y a écrit :

Dans le code que tu donnes Emmanuel, ca veut dire quoi la virgule de cette ligne ?
 

Code :
  1. free (mat[i]), mat[i] = NULL;


 
J'ai pas fait de C depuis longtemps (Java all the time :x) et je ne me souviens pas avoir déjà vu ca :x


 
Bah, c'est l'opérateur ',' que tout le monde utilise dans for.  

for (i=0, j=0; ...)


L'execution est séquentielle.  
 
Je l'utilise ici pour 'atomiser' le code source, c'est à dire pour éviter ça:


free (mat[i]);  
mat[i] = NULL;  


Qui évolurait en


free (mat[i]);  
mat[i][j]=123; /* grave bug! pas forcement detecte a l'execution */
mat[i] = NULL;  


alors que


free (mat[i]);  
mat[i] = NULL;  
mat[i][j]=123; /* plus facilement detectable */


detection que l'on peut aussi instrumenter comme ceci


free (mat[i]);  
mat[i] = NULL;  
assert(mat[i] != NULL);
mat[i][j]=123; /* plus facilement detectable */


alors que


free (mat[i]);  
assert(mat[i] != NULL);
mat[i][j]=123; /* grave bug! pas forcement detecte a l'execution */
mat[i] = NULL;  


echapperait à l'instrumentation...
 
Donc, je tiens à "l'atomicité" de l'opération, d'où l'opérateur ',' (on est moins tenté d'insérer du code entre les deux instructions...)


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-05-2005 à 14:31:05    

dans ce cas pourquoi pas une macro ?

Reply

Marsh Posté le 20-05-2005 à 16:42:44    

skelter a écrit :

dans ce cas pourquoi pas une macro ?


 
Les macros c'ets le mal :o

Reply

Marsh Posté le 20-05-2005 à 16:55:46    

ce qui est mal c'est de confondre macro et fonction, la je veux savoir pourquoi dans ce cas ca serais mal ?? pour moi ca rendrais le code plus sur

Reply

Marsh Posté le 20-05-2005 à 18:12:13    

skelter a écrit :

dans ce cas pourquoi pas une macro ?


J'ai effectvement ça dans ma bibliothèque:
 
http://mapage.noos.fr/emdel/clib/ed/inc/sysalloc.h

#define FREE(p) (free(p),(p)=NULL)


Mais on m'a fait remarqué que le paramètre était évalué 2 fois, ce qui est 'mal'. (Je dirais qu'il y a un point de séquence entre les deux, donc tout va bien...). Dans l'usage courant, il n'y a pas de risque, mais dans des cas tordus, il faut voir...
 
 
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-05-2005 à 18:25:50    

Citation :

Mais on m'a fait remarqué que le paramètre était évalué 2 fois, ce qui est 'mal'.


 
Pourquoi ?

Reply

Marsh Posté le 20-05-2005 à 18:38:21    

ben imagine
FREE(p++)
 
edit: c'est juste un exemple, il y a sans doute bien plus tordu


Message édité par skelter le 20-05-2005 à 18:39:10
Reply

Marsh Posté le 20-05-2005 à 18:39:48    

skelter a écrit :

ben imagine
FREE(p++)
 
edit: c'est juste un exemple, il y a sans doute bien plus tordu


 
 [:hide]  
 
C'est hideux, mais j'ai compris l'idée.  :jap:

Reply

Marsh Posté le 20-05-2005 à 19:08:05    

skelter a écrit :

ben imagine
FREE(p++)
edit: c'est juste un exemple, il y a sans doute bien plus tordu


Oui, c'est techniquement possible, mais qui ferait ça ? Un fou probablement...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 20-05-2005 à 19:10:01    

:pt1cable: Mais oui super idée :pt1cable:  

int **pfin;
for (pfin = p + TAILLE; p < pfin; FREE(*p++));


 :sweat:


Message édité par Tarabiscote le 20-05-2005 à 19:15:09
Reply

Marsh Posté le 20-05-2005 à 19:20:48    

Emmanuel Delahaye a écrit :

Oui, c'est techniquement possible, mais qui ferait ça ? Un fou probablement...


 
genre un gars qui a un tableau de pointeurs et qui ve se la dilater 'code condensé' fait pour liberer les pointeurs

Code :
  1. for( i = 0, p = tab; i < N; i++, FREE(p++) )
  2.     ;


je sais c'est largement tiré par les cheuveux  :D  mais sémantiquement FREE doit liberer et mettre à NULL un pointeur et il ne peut pas le garantir
 
c'est peut etre une connerie mais  ca ne resoudrais pas ce probleme ?
edit: non en fait c'etait une connerie


Message édité par skelter le 20-05-2005 à 19:33:34
Reply

Marsh Posté le 23-05-2005 à 23:00:52    

a la limite pourquoi pas faire
 

Code :
  1. void secure_free(void** ptr)
  2. (
  3.    free(*ptr);
  4.    *ptr = NULL
  5. )
  6. // mon code :
  7. char* ptr = /* plein de trucs */ ;
  8. secure_free(&ptr)


 
En C++, on passerai par un zoli tempalte et une surcharge de delete :jap:


Message édité par Joel F le 23-05-2005 à 23:01:07
Reply

Marsh Posté le 24-05-2005 à 09:47:25    

une surcharge de delete en C++ peut etre pas, sinon comment on libere un pointeur constant ?

Reply

Marsh Posté le 31-05-2005 à 01:07:34    

bonjour les gars je veut un programme qui camlcul l'inverse d'une matrice  
l'ai unn devoire a rendre qui comporte ce programme pourrier vou m'aider m
mmmmmeeeeeerrrrrcccciiiii    beaucop d'avence

Reply

Marsh Posté le 31-05-2005 à 01:16:46    

j ai' oublier de vous dire un programme en c
merci

Reply

Marsh Posté le 31-05-2005 à 07:10:22    

cat stevens a écrit :

bonjour les gars je veut un programme qui camlcul l'inverse d'une matrice  
l'ai unn devoire a rendre qui comporte ce programme pourrier vou m'aider


 
On n'est pas là pour faire tes devoirs (cf. la charte).

Reply

Marsh Posté le 02-06-2005 à 00:07:21    

merci de m'avoire averti je nerecomenerai plus  
promis
 

Reply

Marsh Posté le 02-06-2005 à 00:19:44    

a l'aide d'un ami jai reliser le programme qui calcul le determinant d'un e mat
le voici
#include <stdio.h>
#include <stdlib.h>
#define DIM 10
typedef float ligne[DIM];
typedef ligne matrice[DIM];
typedef float *pointeur;
long nb_appels;
 
void lecture(matrice t,int *lig)
/* lit une matrice (au clavier) */
 {
  int l,c;
  float f;
  puts("dimension de la matrice ?" );
  scanf("%d",lig);
  for (l=0;l<*lig;l++) for(c=0;c<*lig;c++)
   {
    printf("élément [%d,%d] ? ",l,c);
    scanf("%f",&f);
    t[l][c]=f;
   }
 }
void zero(matrice t,int dim)
/* met toute la matrice à 0 */
 {
  int i,j;
  for(i=0;i<dim;i++)for(j=0;j<dim;j++) t[i][j]=0;
 }
void unit(matrice t, int dim)
/* remplit la matrice unité (1 diagonale, 0 autre) */
 {
  int i;
  zero(t,dim);
  for(i=0;i<dim;i++) t[i][i]=1;
 }
void affiche(matrice t,int l)
/*  puts("affichage du tableau ligne par ligne :" ); */
 {
  int i,j;
  for(i=0;i<l;i++)
   {
    printf("ligne %d : ",i);
    for(j=0;j<l;j++) printf("%3.1f ",t[i][j]);
    printf("\n" );
   }
 }
void copiesauflc(matrice source,matrice dest,int dim,int ligavirer)
 {
  int l,c,ld=0;
  for (l=0;l<dim;l++) if (l!=ligavirer)
   {
    for (c=1;c<dim;c++) dest[ld][c-1]=source[l][c];
    ld++;
   }
 }
float determinant(matrice m,int dim)
 {
  matrice sous_m;
  int l,signe=1;
  float det=0;
  nb_appels++;
  if (dim=!1) return(m[0][0]);
  for(l=0;l<dim;l++)
   {
    copiesauflc(m,sous_m,dim,l);
    det+=signe*m[l][0]*determinant(sous_m,dim-1);
    signe=-signe;
   }
  return(det);
 }
void produit(matrice a,matrice b,matrice c,int dim)
/* calcul du produit */
 {
  int im,il,in;
  zero(c,dim);
  for(im=0;im<dim;im++)
    for(in=0;in<dim;in++)
      for(il=0;il<dim;il++)
        c[im][in]+=a[im][il]*b[il][in];
 }
void main(int argc,char *argv[])
 {
  int taille;
  matrice mat;
/*  lecture(mat,&taille);  */
      taille=atoi(argv[1]); /* test avec matrice unité, */
      unit(mat,taille);     /* au moins je connais le résultat*/
  affiche(mat,taille);
  printf("déterminant : %20.17f ",determinant(mat,taille));
  printf(" en %ld appels\n",nb_appels);
 }
mais ca ne marche pas corriger le pour moi

Reply

Marsh Posté le 02-06-2005 à 00:42:10    

100 balles et un mars aussi?
 
- edites ton post et met ton code entre les balises cpp, c'est illisible.

Code :
  1. /* mon code entre balise */
  2. #include <stdio.h>
  3. int main( void ) {
  4.   printf( "prout\n" );
  5.   return 0;
  6. }


- vire tes scanf
- met tes pointeurs à NULL une fois qu'ils servent plus
- commente ton code au niveau programme, fonction, paramètre, variable, portion de code pas clair
- indente ton code correctement  
- compile ton programme en faisant en sorte d'avoir les warnings (-Wall /Wall -w.. suivant ton compilateur) jusqu'à ce que justement il n'y est plus de warning
- utilise lint un coup dessus et corrige ce qui te parait opportunt
- et si tu n'as toujours pas trouver d'où vient l'erreur poste le message d'erreur
- apprend à te servir d'un débuggueur

Reply

Marsh Posté le 02-06-2005 à 03:05:12    

cat stevens a écrit :

a l'aide d'un ami jai reliser le programme qui calcul le determinant d'un e mat
le voici
<...>
mais ca ne marche pas corriger le pour moi


A vos ordres, Chef !

  • main() retourne int. Toujours.
  • argc n'est pas testé. On ne sais pas si des arguments ont été passés...
  • le domaine de l'argument 1 n'est pas testé.
  • "if (dim = !1)" est probablement un erreur : "if (dim != 1)"
  • les fonctions 'lecture()' et 'produit()' ne sont pas utilisées.


Sinon, c'est pas mal comme code. Quel est le problème exactement ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 02-06-2005 à 22:56:28    

je dois avoire une oeil de l'egggle pour voire toues ces erreures

Reply

Marsh Posté le 02-06-2005 à 22:59:12    

MERCI

Reply

Marsh Posté le 02-06-2005 à 23:15:02    

cat stevens a écrit :

je dois avoire une oeil de l'egggle pour voire toues ces erreures


Ah, "un oeil de l'aigle"!  
 
Tu fais très fort... Les ravages de la méthode globale...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-06-2005 à 23:00:39    

Emmanuel Delahaye a écrit :

Ah, "un oeil de l'aigle"!  
 
Tu fais très fort... Les ravages de la méthode globale...


 
J'sais pas... Je suis de cette génération aussi.
Je pense plutôt que ce sont les ravages du "je veux tout, et tout de suite".  [:itm]

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed