Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
841 connectés 

  FORUM HardWare.fr
  Programmation
  C

  matrice statique et dynamique

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

matrice statique et dynamique

n°1508846
exhortae
Membre du Cartel des Médecins
Posté le 30-01-2007 à 21:21:57  profilanswer
 

Bonsoir
 
Voilà je me retrouve confronté à un problème que je n'arrive pas à résoudre
 
le code suivant qui initialise et matrice sous cette forme
1    2    3
4    5    6
 
fonctionne que ce soit en statique ou en dynamique
statique
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5.     int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
  6.    
  7.     int **p;
  8.    
  9.     p = a;
  10.    
  11.     return 0;
  12. }


 
dynamique

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5.     int **a, **p;
  6.     int i, j, k;
  7.    
  8.     /* INITIALISATION MATRICE */
  9.    
  10.     a = malloc (2 * sizeof (int*));
  11.    
  12.     for (i = 0; i < 2; i++)
  13.         a[i] = malloc (3 * sizeof (int));
  14.        
  15.     k = 1;
  16.     for (i = 0; i < 2; i++)
  17.         for (j = 0; j < 3; j++)
  18.             a[i][j] = k++;
  19.            
  20.     p = a;     
  21.    
  22.     return 0;
  23. }


 
 
ensuite je dois faire des opérations sur cette matrice pour celà j'affecte un (int**)p sur (int**)a
 
 
le problème c'est qu'en statique mon compilo me met un warning quand je fais p = a alors qu'il ne me le fait pas en dynamique, et ça j'arrive pas à comprendre pourquoi
 
merci

Message cité 1 fois
Message édité par exhortae le 30-01-2007 à 23:49:17
mood
Publicité
Posté le 30-01-2007 à 21:21:57  profilanswer
 

n°1508853
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 30-01-2007 à 21:39:43  profilanswer
 

Il faut faire une conversion de cast explicite :
p = (int **) a;
 
Le compilateur te met un warning parce que tu pourrais faire une connerie du genre "free(p);" dans la suite de ton programme. Là, tu lui montre que tu sais ce que tu fais.

n°1508855
exhortae
Membre du Cartel des Médecins
Posté le 30-01-2007 à 21:53:00  profilanswer
 

oki
 
maintenant voilà le problème qui se pose  
 
en statique quand je fais ensuite printf ("%d", **p);  le programme plante alors que ça ne plante pas en dynamique
 
 
statique

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5.     int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
  6.    
  7.     int **p;
  8.    
  9.     p = (int**) a;
  10.    
  11.     printf ("%d", **p);
  12.    
  13.     system ("pause" );
  14.     return 0;
  15. }


 
http://img249.imageshack.us/img249/7659/plntjt0.jpg
 
 
 
dynamique

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main (void)
  4. {
  5.     int **a, **p;
  6.     int i, j, k;
  7.    
  8.     /* INITIALISATION MATRICE */
  9.    
  10.     a = malloc (2 * sizeof (int*));
  11.    
  12.     for (i = 0; i < 3; i++)
  13.         a[i] = malloc (3 * sizeof (int));
  14.        
  15.     k = 1;
  16.     for (i = 0; i < 2; i++)
  17.         for (j = 0; j < 3; j++)
  18.             a[i][j] = k++;
  19.            
  20.     p = a; 
  21.    
  22.     printf ("%d", **p);
  23.    
  24.     system ("pause" );   
  25.    
  26.     return 0;
  27. }


 
http://img59.imageshack.us/img59/9011/plnatepasez9.jpg
 

n°1508857
Trap D
Posté le 30-01-2007 à 21:59:05  profilanswer
 

Si tu comptes bien de 0 à 2 inclu il y a trois nombres, pas 2, donc ton a = malloc(2 * sizeof(int *)) est un peu faiblard. En plus tu ne vérifies pas le retour de malloc ce qui n'est jamais une bonne chose.

n°1508858
exhortae
Membre du Cartel des Médecins
Posté le 30-01-2007 à 22:07:52  profilanswer
 

Trap D a écrit :

Si tu comptes bien de 0 à 2 inclu . En plus tu ne vérifies pas le retour de malloc ce qui n'est jamais une bonne chose.


 
 
le 2 n'est pas inclu ;)
 
sinon j'ai juste pas mis de if (a == NULL) et if (a[i] == NULL) afin de montrer juste le strict minimum pour voir ce qui tourne pas, mais d'habitude je le mets tjs (ainsi que le free)

n°1508859
0x90
Posté le 30-01-2007 à 22:07:56  profilanswer
 

dave_tetehi a écrit :

Il faut faire une conversion de cast explicite :
p = (int **) a;

 

Le compilateur te met un warning parce que tu pourrais faire une connerie du genre "free(p);" dans la suite de ton programme. Là, tu lui montre que tu sais ce que tu fais.

 

[:rofl]

 

en aucun cas 'a' ne peut être casté en (int **), c'est pas un tableau de pointeurs vers des tableaux d'entiers, c'est un tableau de tableaux d'entier.

Message cité 1 fois
Message édité par 0x90 le 30-01-2007 à 22:08:37

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1508865
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 30-01-2007 à 22:30:26  profilanswer
 

Ah bon. Quelle différence y'a t-il entre un tableau de pointeur, et un tableau de tableau ? Je ne comprend pas pourquoi on ne peut pas faire ça. gcc -Wall -pedantic ne bronche pas.

n°1508866
0x90
Posté le 30-01-2007 à 22:33:04  profilanswer
 

dave_tetehi a écrit :

Ah bon. Quelle différence y'a t-il entre un tableau de pointeur, et un tableau de tableau ? Je ne comprend pas pourquoi on ne peut pas faire ça. gcc -Wall -pedantic ne bronche pas.


 
Dessine la mémoire tu va bien voir la différence ... (ou alors ouvre un bouquin de C...)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1508871
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 30-01-2007 à 22:43:48  profilanswer
 

Je me trompe surement, mais le tableau statique est alloué dans le segment data, peut importe le nombre de dimension, l'allocation est faite de manière continue, nen ? desolé, si je suis dur d'oreille, mais je comprend tjs pas.

n°1508875
Trap D
Posté le 30-01-2007 à 22:56:06  profilanswer
 

Excuse moi d'insister mais quand je vois

Code :
  1. // tu alloues la place pour 2 pointeur vers des entiers
  2. a = malloc(2 * sizeof (int*));
  3. // Tu en affectes trois a[0], a[1] et a[2]
  4. for (i = 0; i < 3; i++)
  5.         a[i] = malloc (3 * sizeof (int));

Je me dis qu'il y a un problème et que ça peut fonctionner quelques fois, mais ça risque tout de même de planter un jour.

mood
Publicité
Posté le 30-01-2007 à 22:56:06  profilanswer
 

n°1508888
dave_teteh​i
cat /dev/urandom &gt; /dev/fb0
Posté le 30-01-2007 à 23:47:40  profilanswer
 

0x90 a écrit :

Dessine la mémoire tu va bien voir la différence ... (ou alors ouvre un bouquin de C...)


 
Effectivement je me suis bien planté, je pense que ce genre de chose est beaucoup plus propre :

Code :
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int i;
  5. int a[4][5];
  6. int * b;
  7. b = (int *) a;
  8. printf("%p\n", (void *) a);
  9. printf("%p\n\n", (void *) b);
  10. for(i=1; i < 21; i++)
  11.  *(b++) = i;
  12. printf("%d\n", a[0][0]);
  13. printf("%d\n", a[1][0]);
  14. printf("%d\n", a[2][0]);
  15. printf("%d\n", a[3][0]);
  16. return 0;
  17. }

n°1508889
exhortae
Membre du Cartel des Médecins
Posté le 30-01-2007 à 23:48:58  profilanswer
 

Trap D a écrit :

Excuse moi d'insister mais quand je vois

Code :
  1. // tu alloues la place pour 2 pointeur vers des entiers
  2. a = malloc(2 * sizeof (int*));
  3. // Tu en affectes trois a[0], a[1] et a[2]
  4. for (i = 0; i < 3; i++)
  5.         a[i] = malloc (3 * sizeof (int));

Je me dis qu'il y a un problème et que ça peut fonctionner quelques fois, mais ça risque tout de même de planter un jour.


 
 
oui tu as raison, juste une erreur d'innatention, je corrige ça tout de suite, merci

n°1508890
exhortae
Membre du Cartel des Médecins
Posté le 30-01-2007 à 23:52:51  profilanswer
 

0x90 a écrit :

[:rofl]
 
en aucun cas 'a' ne peut être casté en (int **), c'est pas un tableau de pointeurs vers des tableaux d'entiers, c'est un tableau de tableaux d'entier.


 
 
je vois ce que tu veux dire, mais je n'arrive pas à visualiser la différence au niveau mémoire, tu aurais un lien qui explique tout ça

n°1508893
Emmanuel D​elahaye
C is a sharp tool
Posté le 31-01-2007 à 00:23:48  profilanswer
 

dave_tetehi a écrit :

Effectivement je me suis bien planté, je pense que ce genre de chose est beaucoup plus propre :

Code :
  1. int a[4][5];
  2. int * b;
  3. b = (int *) a;



 [:arrakys] Mais c'est quoi ce cast de la mort qui tue ? Tu ne sais pas écrire du C correct ?


---------------
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/
n°1508894
Emmanuel D​elahaye
C is a sharp tool
Posté le 31-01-2007 à 00:25:19  profilanswer
 

exhortae a écrit :

je vois ce que tu veux dire, mais je n'arrive pas à visualiser la différence au niveau mémoire, tu aurais un lien qui explique tout ça


Dessine ce qui se passe avec les pointeurs. C'est à toi de le faire, personne ne peut le faire a ta place. Et désolé si tu grilles trois neurones en faisant ça, mais c'est indispensable...

 

Message cité 1 fois
Message édité par Emmanuel Delahaye le 31-01-2007 à 00:25:41

---------------
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/
n°1510353
exhortae
Membre du Cartel des Médecins
Posté le 03-02-2007 à 05:15:48  profilanswer
 

Emmanuel Delahaye a écrit :

Dessine ce qui se passe avec les pointeurs. C'est à toi de le faire, personne ne peut le faire a ta place. Et désolé si tu grilles trois neurones en faisant ça, mais c'est indispensable...


 
 
Voilà comment je vois ça, si quelqu'un pourrais me dire si c'est bon je pourrais expliquer ensuite comment je vois la chose.
 
Merci
 
 
http://img128.imageshack.us/img128/7986/tableauxao2.jpg
 
 
 
PS : ça ma coûté mes 6 derniers neuronnes  :sweat:

Message cité 1 fois
Message édité par exhortae le 03-02-2007 à 05:16:48
n°1510408
Sve@r
Posté le 03-02-2007 à 13:22:01  profilanswer
 

exhortae a écrit :

Bonsoir
 
Voilà je me retrouve confronté à un problème que je n'arrive pas à résoudre
 
le problème c'est qu'en statique mon compilo me met un warning quand je fais p = a alors qu'il ne me le fait pas en dynamique, et ça j'arrive pas à comprendre pourquoi
 
merci


 
Va ici http://forum.hardware.fr/hfr/Progr [...] 0049_1.htm relire mon post du 9 janvier dernier. Il s'agit de la même question !!!!
 
La partie importante qui ne t'as probablement pas sautée aux yeux est celle-ci "Le pb du débutant, c'est qu'il a tendance à croire que [] <=> * donc [][] <=> **  
L'équivalence n'est vrai que pour une seule dimension. Pourquoi ? parce que la mémoire n'est définie, en mémoire, que sur une seule dimension. Les cases mémoires sont alignées sur une seule et immense ligne
."
 

exhortae a écrit :

Voilà comment je vois ça, si quelqu'un pourrais me dire si c'est bon je pourrais expliquer ensuite comment je vois la chose.
http://img128.imageshack.us/img128/7986/tableauxao2.jpg


Un tableau de tableaux style "int tab[2][3]={{1, 2, 3}, {4, 5, 6}}" se présente ainsi

Citation :


adresse     xxx          0x1000      0x1004        0x1008        0x100c      0x1010        0x1014
nom          tab        tab[0][0]   tab[0][1]     tab[0][2]     tab[1][0]   tab[1][1]     tab[1][2]
contenu   0x1000          1              2                3                4              5                 6


 
Un tableau de pointeurs, style "int **tab" (avec les malloc qui vont bien) se présente ainsi

Citation :


adresse     xxx          0x1000      0x1004    
nom          tab          tab[0]      tab[1]    
contenu   0x1000      0x5000      0x7120
 
adresse     0x5000     0x5004      0x5008    
nom         tab[0][0]  tab[0][1]   tab[0][2]
contenu        1             2              3
 
adresse     0x7120     0x7124      0x7128
nom         tab[1][0]  tab[1][1]   tab[1][2]
contenu         4            5               6

Message cité 1 fois
Message édité par Sve@r le 03-02-2007 à 14:18:05

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1510776
exhortae
Membre du Cartel des Médecins
Posté le 05-02-2007 à 08:51:09  profilanswer
 

Sve@r a écrit :

Va ici http://forum.hardware.fr/hfr/Progr [...] 0049_1.htm  
 
Un tableau de tableaux style "int tab[2][3]={{1, 2, 3}, {4, 5, 6}}" se présente ainsi
 

Citation :


adresse     xxx          0x1000      0x1004        0x1008        0x100c      0x1010        0x1014
nom          tab        tab[0][0]   tab[0][1]     tab[0][2]     tab[1][0]   tab[1][1]     tab[1][2]
contenu   0x1000          1              2                3                4              5                 6  


 
 


 
en faite ce que je n'arrive pas à comprendre quand je vois cette présentation c'est pourquoi quand je fais tab + 1, il part à l'adresse 0x100c (c'est à dire vers le 2ème tableau, au lieu d'aller à l'adresse 0x1004.
 
j'ai compris que pour le faire il faut faire  
 

Code :
  1. int *p;
  2. p = (int*) tab;


 
puis on peux faire *(p + 1) pour acceder à la case tab[0][1], mais je ne vois pas pourquoi tab + 1 ne serait pas égale à 0x1004.
 
sinon j'avais bien lu ta réponse dans le post du 9 janvier mais le problème c'est qu'en c il utilise tab[i][j] pour tab[..][..] ou **tab et ça ça me perturbe toujours un peu
 
merci.

Message cité 1 fois
Message édité par exhortae le 05-02-2007 à 08:54:33
n°1511160
Sve@r
Posté le 05-02-2007 à 22:13:46  profilanswer
 

exhortae a écrit :

en faite ce que je n'arrive pas à comprendre quand je vois cette présentation c'est pourquoi quand je fais tab + 1, il part à l'adresse 0x100c (c'est à dire vers le 2ème tableau, au lieu d'aller à l'adresse 0x1004.
 
j'ai compris que pour le faire il faut faire  
 

Code :
  1. int *p;
  2. p = (int*) tab;


 
puis on peux faire *(p + 1) pour acceder à la case tab[0][1], mais je ne vois pas pourquoi tab + 1 ne serait pas égale à 0x1004.


TU N'AS PAS LE DROIT DE COPIER tab DANS p => ce ne sont pas des variables de même type

  • p est de type "int étoile"
  • tab peut être vu comme un type "int étoile étoile" bien que ce ne soit pas la réalité (c'est juste une illustration pour montrer qu'il y a 2 indirections)

En tout cas un type "int étoile" n'est pas un type "int étoile étoile". C'est d'ailleurs pour ça que tu fais un cast => parce que ton compilo râle !!!
Il s'ensuit qu'ensuite il essaye de s'en sortir avec ce qu'il peut et te donne un résultat un peu batard
Essaye d'ailleurs, juste pour voir, d'afficher "tab" avec "%p" et d'afficher aussi "*tab" avec "%p"...
 

exhortae a écrit :

sinon j'avais bien lu ta réponse dans le post du 9 janvier mais le problème c'est qu'en c il utilise tab[i][j] pour tab[..][..] ou **tab et ça ça me perturbe toujours un peu


Parce que tu cherches à assimiler [][] à "étoile étoile" alors que ce n'est pas le cas.

Message cité 1 fois
Message édité par Sve@r le 05-02-2007 à 22:16:01

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1511193
exhortae
Membre du Cartel des Médecins
Posté le 05-02-2007 à 23:22:10  profilanswer
 

Sve@r a écrit :

TU N'AS PAS LE DROIT DE COPIER tab DANS p => ce ne sont pas des variables de même type

  • p est de type "int étoile"
  • tab peut être vu comme un type "int étoile étoile" bien que ce ne soit pas la réalité (c'est juste une illustration pour montrer qu'il y a 2 indirections)

En tout cas un type "int étoile" n'est pas un type "int étoile étoile". C'est d'ailleurs pour ça que tu fais un cast => parce que ton compilo râle !!!
Il s'ensuit qu'ensuite il essaye de s'en sortir avec ce qu'il peut et te donne un résultat un peu batard


 
Dans ce cas là est-ce que je peux utiliser la formule suivante :  
 

Code :
  1. scanf ("%d", (int*) a + 1);


 

Sve@r a écrit :


Essaye d'ailleurs, juste pour voir, d'afficher "tab" avec "%p" et d'afficher aussi "*tab" avec "%p"...


 
Elles ont la même valeur, je l'avais remarqué lors de mes expérimentations ;)
 
par contre son explication  reste un mystère pour moi, est-ce que ça veut dire que tab pointe sur tab  :??:
 
et là à bien y penser j'aurais plutôt utilisé  

Code :
  1. scanf ("%d", *a + 1);


 
bref je suis perdu...

Message cité 1 fois
Message édité par exhortae le 05-02-2007 à 23:28:20
n°1511276
Sve@r
Posté le 06-02-2007 à 10:50:07  profilanswer
 

exhortae a écrit :

par contre son explication  reste un mystère pour moi, est-ce que ça veut dire que tab pointe sur tab  :??:


Ca veut dire que si l'équivalence entre "int[]" et "int *" est vraie, l'équivalence entre "int[][]" et "int **" ne l'est pas. On peut éventuellement essayer de la faire dans un but très très illustratif mais seulement dans ce but là et non dans des termes d'égalité mathématique.
Donc si t'essayes de la faire, tu obtiendras des résultats incohérents avec ton raisonnement...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1511380
0x90
Posté le 06-02-2007 à 14:17:02  profilanswer
 

Sve@r a écrit :

Ca veut dire que si l'équivalence entre "int[]" et "int *" est vraie, l'équivalence entre "int[][]" et "int **" ne l'est pas. On peut éventuellement essayer de la faire dans un but très très illustratif mais seulement dans ce but là et non dans des termes d'égalité mathématique.
Donc si t'essayes de la faire, tu obtiendras des résultats incohérents avec ton raisonnement...


 
Syntaxiquement ça passe la plupart du temps, mais c'est pas exactement vrai, gaffe aux sizeofs ;)


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
n°1511884
Sve@r
Posté le 07-02-2007 à 17:11:31  profilanswer
 

0x90 a écrit :

Syntaxiquement ça passe la plupart du temps, mais c'est pas exactement vrai, gaffe aux sizeofs ;)


Ah ? On peut avoir des problèmes si on utilise de façon équivalente "tab[x]" et "*(tab + x)" ???


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  matrice statique et dynamique

 

Sujets relatifs
Chargement dynamique de newspassage de matrice en parametre
[MySQL v5] [Procédure Stockée] construire une requête dynamique ?[Résolu] Matrice et fonctions
[Résolu] Accès à une variable statiqueCréation dynamique de classe en PHP5 ?
Tableau dynamique sous ASP.net (C# et SQL Server)[SQL Server 2005] Procédure stockée dynamique ?
[AJAX] Problème de chargement dynamique de CSSinverse matrice en c
Plus de sujets relatifs à : matrice statique et dynamique


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR