Somme et produit de deux matrices carrées

Résolu/Fermé
Arnaud3198 Messages postés 6 Date d'inscription samedi 17 janvier 2015 Statut Membre Dernière intervention 4 avril 2015 - Modifié par Whismeril le 17/01/2015 à 21:18
 imenabdelmalek - 17 janv. 2019 à 14:13
bonjour,
j'ai un souci avec l'éxécution de mon programme.
Lorsque je compile, j'ai pas d'erreur mais quand j'éxécute, ça plante! J'aimerai un éclaircissement sur ce problème. Je vous passe le code:

#include <stdio.h>
#include <stdlib.h>
#define NL 50
#define NC 50

//* Déclaration des sous programmes *//
void AfficheMatrice(int n, int **A)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        printf("\n");
        for(j=0;j<n;j++)
        {
            printf("%d \t",A[i][j]);
        }
    }
}
void SommeDeMatrices(int n, int **A, int **B, int **D)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;i<n;j++)
        {
            D[i][j] = A[i][j]+B[i][j];
        }
    }
    AfficheMatrice(n,D);
}
int scalaire(int n, int i, int j, int **A, int **B)
{
    int S,k;
    S=0;
    for(k=0;k<n;k++)
    {
        S=S+A[i][k]*B[k][j];
    }
    return S;
}
void ProduitDeMatrices(int n, int **A, int **B, int **C)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            C[i][j]=scalaire(n,i,j,A,B);
        }
    }
    AfficheMatrice(n,C);
}
void LectureMatrice(int n, int **A)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        printf("entrez les elements de la %d ieme ligne\n",i);
        for(j=0;j<n;j++)
        {
           scanf("%d ",&A[i][j]);
        }
    }
}
int main()
{
    int **A[NL][NC];
    int **B[NL][NC];
    int **D[NL][NC];
    int **C[NL][NC];
    int n;
    printf("entrez la taille des deux matrices carrees\n");
    scanf("%d",&n);
    LectureMatrice(n,**A);
    LectureMatrice(n,**B);
    SommeDeMatrices(n,**A,**B,**D);
    ProduitDeMatrices(n,**A,**B,**C);
    return 0;
}


EDIT: Ajout de la coloration syntaxique.

2 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
17 janv. 2015 à 21:54
Bonsoir,

Remarques de fond :
int **A[NL][NC];
Tu veux une matrice, donc tu as besoin de 2 dimensions. Pourquoi faire un tableau de pointeur sur pointeur ?
Donc, mets plutôt :
int A[NL][NC];

De même pour B et C.

LectureMatrice(n,**A);
Vu la remarque précédente, il faut corriger en A.
De même pour B et C.
Idem pour : SommeDeMatrices(n,**A,**B,**D); et ProduitDeMatrices(n,**A,**B,**C);

N'oublie pas de mettre un '\n' juste avant le return 0; final pour flusher la sortie écran.

Sinon la vraie erreur vient probablement d'ici :
void LectureMatrice(int n, int **A)
Il faut préciser la taille des colonnes à minima.
Donc plutôt : <code c>void LectureMatrice(int n, int A[][NC]);
Note : tu peux préciser le nombre de lignes aussi, mais c'est facultatif.
Même remarque pour le prototype des autres fonctions.

Cdlt,
4
Arnaud3198 Messages postés 6 Date d'inscription samedi 17 janvier 2015 Statut Membre Dernière intervention 4 avril 2015
18 janv. 2015 à 09:00
merci beaucoup mais je comprends pas ce que tu appelles "flusher la sortie écran" et j'aimerai avoir un code c pour flusher
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
18 janv. 2015 à 15:01
Flusher signifie purger. L'idée est de s'assurer que tout soit afficher. Tu peux mettre printf("\n");
0
imenabdelmalek
17 janv. 2019 à 14:13
merci beaucoup pour cette solution
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
18 janv. 2015 à 17:48
Bonjour,
En plus des remarques de @fiddy, ton programme n'a besoin en réalité que de deux matrices la troisième, est optionnel car pour moi, elle ne sert pas à grand-chose ( uniquement pour le résultat, ce qui justifie également la conservation des données de la première matrice).
Plus encore, tu n'as pas besoin de définir une valeur pour la colonne et une valeur pour la ligne
#define NL 50
#define NC 50

une seule constante de la variable suffit
 #define MAX 50 
pour être utilisé a la fois comme colonne & ligne.
Et pour finir, suit les remarques de @fiddy comme il te la indiquer, utilise les syntaxes simples comme dans sont exemple et si tu comptes utilises les pointeurs cela te donnera l'exemple suivant:
#include <stdio.h>
#include <stdlib.h>

#if defined(WIN32) && !defined(UNIX)
	#define CLEAR system("cls")
#elif defined(UNIX) && !defined(WIN32)
	#define CLEAR printf("\033[H\033[2J")
#else
	#define CLEAR printf("\033[H\033[2J")
#endif

#define	MAX	8
#define NBR_A	2
#define NBR_B	4

void f_Reset( void ){

	printf( "\t<taper sur entrer>" );
	while( getchar() !='\n' )
		;
	CLEAR;
}

void f_AffchMatrice( int **p, const char *x ){

	unsigned int i = 0;
	unsigned int j = 0;
	printf( "\t*MATRICE( %s )\n\n", x );
	for( i = 0; i < MAX ; i++){
		printf( "%4d|\t",i );
		for( j = 0; j < MAX; j++ ){
			printf( "%d\t", (*(*(p+i)+j)) );
		}
		printf( "\n" );
	}
	f_Reset();
}

int *pf_Alloc( const size_t size ){

	int *p = NULL;
	p = (int*)calloc( size, sizeof(int) );
	if( p == NULL ){
		return ( p );
	}
	return ( p );
}

void f_ProduitMatrice_2( int **p ){

	unsigned int i = 0;
	unsigned int j = 0;
	for( i = 0; i < MAX; i++ ){
		for( j = 0; j < MAX; j++ ){
			(*(*(p+i)+j)) *= (*(*(p+i)+j));
		}
	}
}

void f_ProduitMatrice( int **p1, int **p2 ){

	unsigned int i = 0;
	unsigned int j = 0;
	for( i = 0; i < MAX; i++){
		for( j = 0; j < MAX; j++ ){
			(*(*(p1+i)+j)) = ( (*(*(p1+i)+j)) * (*(*(p2+i)+j)) );
		}
	}
}

unsigned long f_Scalaire( int **p1, int **p2 ){

	unsigned int i = 0;
	unsigned int j = 0;
	unsigned long s = 0;
	#define UL unsigned long
	for( i = 0; i < MAX; i++ ){
		for( j = 0; j <MAX; j++ ){
			s += (UL)( (*(*(p1+i)+j)) * (*(*(p2+i)+j)) );
		}
	}
	return ( s );
}

void f_SommeMatrice( int **p1, int **p2, const char *x ){
	unsigned int i = 0;
	unsigned int j = 0;
	for( i = 0; i < MAX; i++ ){
		for( j = 0; j < MAX; j++ ){
			( (p1[i][j]) += (p2[i][j]) );
		}
	}
	f_AffchMatrice(p1,x);
}


void f_RemplirMatrice( int **p , const int x, const char *y ){

	unsigned int i = 0;
	unsigned int j = 0;
	printf( "\t( %s ) = %d\n\n", y, x );
	for( i = 0; i < MAX; i++ ){
		for( j = 0; j < MAX; j++ ){
			( (p[i][j]) = x );
		}
	}
	f_AffchMatrice(p,y);
}

/*	Free memoire	*/
void f_FreeMatrice( int **p ){

	unsigned int i = 0;
	for( i = 0; i < MAX; i++ ){
		free( *(p+i) );
	}
	free( p );
}

int main( void ){

	unsigned int i = 0;
	static int **pM_A = NULL;
	static int **pM_B = NULL;

	pM_A = (int**)calloc( MAX, sizeof(int*) );
	pM_B = (int**)calloc( MAX, sizeof(int*) );
	for( i = 0; i < MAX; i++ ){
		*(pM_A+i) = pf_Alloc( MAX );
		*(pM_B+i) = pf_Alloc( MAX );
	}

	CLEAR;
	printf("\tINIT (pM_A & pM_B) = ( 0 )\n");
	f_Reset();
	f_AffchMatrice( pM_A, "pM_A" );
	f_AffchMatrice( pM_B, "pM_B" );

	f_RemplirMatrice( pM_A, NBR_A , "pM_A" );
	f_RemplirMatrice( pM_B, NBR_B , "pM_B" );

	printf( "\tSCALAIRE (pM_A & pM_B) = %6ld\n", f_Scalaire( pM_A, pM_B) );
	f_Reset();

	printf( "\t SOMME (pM_A + pM_B)\n" );
	f_Reset();
	f_SommeMatrice( pM_A, pM_B, "pM_A" );

	f_RemplirMatrice( pM_A, NBR_A , "pM_A" );
	printf( "\tPRODUIT pM_A & pM_B\n" );
	f_ProduitMatrice( pM_A, pM_B );
	f_AffchMatrice( pM_A, "pM_A" );

	f_RemplirMatrice( pM_A, MAX , "pM_A" );
	printf( "\tMATRICE² (pM_A)²\n" );
	f_ProduitMatrice_2( pM_A );
	f_AffchMatrice( pM_A, "pM_A" );

	printf( "\tFREE MATRICE\n" );
	f_FreeMatrice( pM_A );
	f_FreeMatrice( pM_B );
	f_Reset();

	return( EXIT_SUCCESS );
}


à bientôt
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 18/01/2015 à 18:48
C'est mieux à mon avis de laisser NL et NC. Car le jour où il souhaitera une matrice non carrée (et pour l'addition par exemple, pas besoin qu'elles le soient), il n'aura pas à tout modifier.

static int **pM_A = NULL;
Pourquoi le définir en static ?

(*(*(p1+i)+j))
p1[i][j] est plus lisible, non ?

Sinon, on est loin de son programme original ;-)
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
18 janv. 2015 à 19:00
Bon j'avoue on est loin de son programme initial j'ai la mauvaise habitude de faire plus compliquer les choses simples mais, pas faut, j'airai dû mettre des instructions simples pour les pointeurs ceci dit, j'ai volontairement écrit ainsi d'un côté pour réviser mes pointeurs.
Quant au static c'était pour limiter le tableau au fichier car j'avais fait des teste d'un autre genre.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
18 janv. 2015 à 19:06
Ca ne limite pas le tableau au fichier... Tu confonds certainement avec l'utilisation de static devant les noms de fonction...
Là, ton tableau est limité au main().
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
18 janv. 2015 à 19:07
au tant pour moi ;)
0
Arnaud3198 Messages postés 6 Date d'inscription samedi 17 janvier 2015 Statut Membre Dernière intervention 4 avril 2015 > fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022
18 janv. 2015 à 20:02
vrai je comprenais pas son programme je suis encore un amateur!! =D
0