Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

simple et sans pointeurs, transposer une matrice

14 réponses
Avatar
bpascal123
Bonjour-soir,

Le code ci-dessous pour transposer une matrice ne fonctionne pas bien
que la compilation a lieu voir le message d'erreur apr=E8s le code ci-
dessous qui se produit lors de l'ex=E9cution. Je voudrais comprendre, =E7a
fait pas mal de temps que je cherche pourquoi mais je n'ai pas assez
de temps pour aller en profondeur.


#include <stdio.h>

int main(void)
{
int Mat[3][2] =3D {1, 4, 2, 5, 3, 6 } ;
int i, j ;
int lig =3D 3 ;
int col =3D 2 ;
int aide ;


printf("\nAFFICHAGE MATRICE AVANT TRANSPOSITION: \n") ;
for ( i =3D 0 ; i < lig ; i++ )
{
for ( j =3D 0 ; j < col ; j++ )
printf("%d", Mat[i][j]) ;
printf("\n") ;
}

/*Permutation : */

for ( i =3D 0 ; i <=3D lig ; i++ )
for ( j =3D 0 ; j <=3D i ; j++ )
{
aide =3D Mat[i][j] ;
Mat[i][j] =3D Mat[j][i] ;
Mat[j][i] =3D aide ;
}
/*Fin permutation */

printf("\nAFFICHAGE MATRICE TRANSPOSEE: \n") ;
for ( i =3D 0 ; i < col ; i++ )
{
for ( j =3D 0 ; j < lig ; j++ )
{
printf("%d", Mat[i][j]) ;
}
printf("\n") ;
}

printf("\n\n") ;
return 0 ;
}

c:>gcc monprog.c -o monprog.exe
fonctionne
c:>monprog
ne fonctionne pas!

Exiting due to signal SIGSEGV
Stack Fault at eip=3D00088c47
eax=3D00000063 ebx=3D00000001 ecx=3D00000256 edx=3D00000000 esi=3D00000054 =
edi=3D0
000ff3e
ebp=3D0008ff30 esp=3D000002da program=3DC:\CODE_C\MONPROG~3.EXE
cs: sel=3D01a7 base=3D029d0000 limit=3D0009ffff
ds: sel=3D01af base=3D029d0000 limit=3D0009ffff
es: sel=3D01af base=3D029d0000 limit=3D0009ffff
fs: sel=3D017f base=3D0000f9c0 limit=3D0000ffff
gs: sel=3D01bf base=3D00000000 limit=3D0010ffff
ss: sel=3D01af base=3D029d0000 limit=3D0009ffff
App stack: [0008ff3c..0000ff3c] Exceptn stack: [0000fe9c..0000df5c]

Call frame traceback EIPs:
0x00088c47
0x00001ac6

Merci
Pascal

4 réponses

1 2
Avatar
bpascal123
Bonjour/soir,

Je voudrais juste ajouter pour m'assurer que le coeur du problème est
bien la déclaration de la matrice avec :
int M[L][C] = { {1,3,5}, {2,4,6} } ;

Il y avait un débordement dans le poste initial à force d'essayer
toute les solutions, en fait c'était une étourderie car j'avais déj à
une solution qui fonctionnait mais avec saisie des valeurs de la
matrice :

int MatA[10][10] ;
int i, j ;
int lig, col ;
int aide ;

do
{
printf("nnEntrez le nombre de lignes [max.10] : ") ;
scanf("%d", &lig) ;
} while ( lig >= 10 ) ;

do
{
printf("nnEntrez le nombre de colonnes [max.10] : ") ;
scanf("%d", &col) ;
} while ( col >= 10 ) ;

Et la suite avec le code de Benoit Izac fonctionne très bien.

Ca veut dire que lors de la saisie "manuelle" des valeurs le programme
range automatiquement les valeurs avec les bracelets pour délimiter
les lignes et les colonnes de la matrice ?

J'espère ne pas être trop redondant et que le fait que je veux être
sûre de bien comprendre ce chapitre n'est pas une perte de temps à vos
yeux.

Merci,
Pascal
Avatar
zwim
Le Sun, 11 Apr 2010 09:57:26 -0700 (PDT)
a écrit

Ca veut dire que lors de la saisie "manuelle" des valeurs le programme
range automatiquement les valeurs avec les bracelets pour délimiter
les lignes et les colonnes de la matrice ?



En fait en C les tableaux qu'ils soient à 1 ou plusieurs dimensions,
si déclarés comme int M[n1][n2]...[nx] sont toujours une zone contiguë
de mémoire.

En cela ils sont donc toujours équivalents à un tableau à 1 dimension
int M[n1*n2*...*nx];

Prenons l'exemple suivant et les déclarations possibles pour ranger 6
valeurs :

int A[6] = { 1,2,3,4,5,6 };

(1 2 3 4 5 6)

int B[2][3] = { {1,2,3}, {4,5,6} };

(1 2 3)
(4 5 6)

int C[3][2] = { {1,2}, {3,4}, {5,6} };

(1 2)
(3 4)
(5 6)

int D[6][1] = { {1}, {2}, {3}, {4}, {5}, {6} };

(1)
(2)
(3)
(4)
(5)
(6)

int E[1][6] = { {1,2,3,4,5,6} };

( (1 2 3 4 5 6) )

La déclaration avec des { }, donne la façon dont les données sont
rangées dans le tableau en commençant par remplir toujours la dernière
dimension (i.e. la plus à droite, càd nx).

Même chose avec un exemple à 3 dimensions.

int A[24] = { 1,2,3,...,24 };

(1 2 3 4 ... 24)

int B[2][3][4] = {
{ {1,2,3,4} , {5,6,7,8} , {9,10,11,12} },
{ {13,14,15,16} , {17,18,19,20} , {21,22,23,24} }
};

Il y a 3 dimensions, donc les {{{ s'emboitent sur 3 niveaux.
Il y a 2 lignes.
Dans chacune des lignes, il y a 3 colonnes
Et dans chacune des colonnes il y a 4 nombres

Si tu définis ton tableau autrement, par exemple
int C[4][2][3] peux-tu écrire la déclaration correspondante ?

Ce qu'il faut bien voir c'est qu'en mémoire, rien ne change, il s'agit
toujours de 24 * sizeof(int) octets contigus, avec 1 dans le premier
int, et 24 dans le dernier.

Quant à l'équivalence entre
int T1[LIGNE*COL];
int T2[LIGNE][COL];

Tu as T2[i][j] = T1[COL*i+j], pour i=0..LIGNE-1 et j=0..COL-1

Donc pour transposer int M[LIGNE][COL] vers int tM[COL][LIGNE], tu
dois avoir la relation que j'ai évoquée dans mon précédent post.

tM[i][j] = M[j][i]

càd tM[i*LIGNE+j] = M[j*COL+i]

--
zwim.
Rien n'est impossible que la mesure de la volonté humaine...
Avatar
Antoine Leca
zwim écrivit :
En fait en C les tableaux qu'ils soient à 1 ou plusieurs dimensions,
si déclarés comme int M[n1][n2]...[nx] sont toujours une zone contiguë
de mémoire.



Oui.

En cela ils sont donc toujours équivalents à un tableau à 1 dimension


^^^^^^^^
int M[n1*n2*...*nx];



<NIVEAU:AVANCÉ>
Pas /toujours/. Même si c'est vrai dans la quasi-totalité des machines
actuelles, cette propriété n'est pas imposée par le langage C, et il y a
des machines (à architecture segmentée) qui ne sont pas capables
d'adresser directement le tableau à une dimension, et qui nécessite donc
de passer par l'écriture avec N dimensions (et c'est le compilateur qui
fait la jointure).
</NIVEAU>


Antoine
Avatar
bpascal123
merci pour toutça
1 2