Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 26/04/2021, à 13:04

zephyre123

Compréhension notation pointeur avec les matrices ?

Bonjour,

J'essaye de comprendre la notation pointeur <=> notation entre crochet.
- j'obtiens bien les mêmes résultats avec les deux notations pour ce qui est des tableaux => OK
- je n'obtiens pas les mêmes résultats avec les deux notations pour les matrices => KO

Je ne vois  pas ou est mon erreur, pouvez vous m'aidez ?
Pour les tableaux nous avons l'équivalence suivante : t[x] = *(p + x) = intermédiare
Donc je me suis dit qu'on fait exactement la même chose pour un tableau à deux dimensions (matrice) = *(intermediare + j) = *(*(matrice +i) + j)
avec *(matrice + i) = pointeur de ligne
mais je n'obtiens pas les mêmes résultats => équivalence FAUX (mais je ne vois pas ou ?)

Le programme en question ci dessous :

#include <stdio.h>
#include <stdlib.h>

// Soit un tableau de char à 1 dimension
char tableau[2] =
{'A', 'B'};

char matrice[2][3] =
{
	{'A', 'B', 'C'},
	{'D', 'E', 'F'}
};

void affichageTableau(char *tableau)
{
	// Affichage avec la notation entre crochet :
	for (int i = 0; i < 2; i++)
		printf("Le tableau[%d] = %c et a pour adresse : %p\n", i, tableau[i], &tableau[i]);

	printf("\n\n");

	// Affichage avec la notation pointeur :
	for (int i = 0; i < 2; i++)
		printf("Le tableau[%d] = %c et a pour adresse : %p\n", i, *(tableau + i), tableau + i);
}


void affichageMatrice(char (*pMatrice)[2][3])
{
	// Affichage avec la notation entre crochet :
	for (int ligne = 0; ligne < 2; ligne++)
		for (int colonne = 0; colonne < 3; colonne++)
			printf("La matrice[%d][%d] = %c et a pour adresse : %p\n", ligne, colonne, matrice[ligne][colonne], &matrice[ligne][colonne]);

	printf("\n\n");

	// Affichage avec la notation pointeur :
	for (int ligne = 0; ligne < 2; ligne++)
	{
		printf("L'adresse de la ligne : %d = %p\n",ligne + 1,  *(pMatrice + ligne));
		// (*pMatrice + ligne) = pointeur sur la ligne i + 1
		

		for (int colonne = 0; colonne < 3; colonne++)
		{
			char *pLigne = *(matrice + ligne);
			printf("La matrice[%d][%d] = %c et à pour adresse : %p\n", ligne, colonne, *(pLigne + colonne), (*(pMatrice + ligne)) + colonne);

		}
	
	}
}


int main(void)
{
  	affichageMatrice(&matrice);
//	affichageTableau(tableau);
	return EXIT_SUCCESS;
}

Hors ligne

#2 Le 26/04/2021, à 13:22

grigouille

Re : Compréhension notation pointeur avec les matrices ?

Je ne réponds pas vraiment à ta question mais je te suggère de ne pas utiliser les tableaux de tableaux.
Si tu veux manipuler les matrices, regarde du côté de la GNU Scientific library :

https://www.gnu.org/software/gsl/doc/ht … l#matrices

Tu peux aller voir le code source, très instructif.


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#3 Le 26/04/2021, à 13:59

zephyre123

Re : Compréhension notation pointeur avec les matrices ?

Non mais grirouille le but c'est justement de manipuler des tableaux de tableaux pour comprendre les pointeurs.
A la limite je me fou des matrices.

Hors ligne

#4 Le 26/04/2021, à 21:34

kamaris

Re : Compréhension notation pointeur avec les matrices ?

Sur le principe tu as bon, mais tu t'embrouilles simplement entre variables globales et locales.
Utilise soit uniquement matrice, soit uniquement pMatrice dans affichageMatrice(), et tu t'y retrouveras déjà mieux.
Ensuite, garde à l'esprit que matrice équivaut à *pMatrice, puisque tu passes matrice par référence.
Enfin, mets les parenthèses comme il faut, ce qui n'est pas toujours le cas dans ton exemple, et au final, tu auras bien le même résultat en passant par la notation tableau ou la notation pointeur.

Hors ligne

#5 Le 26/04/2021, à 23:42

zephyre123

Re : Compréhension notation pointeur avec les matrices ?

Ok Kamaris merci pour les conseils  je vais testé, on se tient au courant.

Hors ligne

#6 Le 27/04/2021, à 07:31

grigouille

Re : Compréhension notation pointeur avec les matrices ?

Si tu veux travailler avec des matrices, il faut travailler avec un objet matrice.

Voici le même exercice avec ta matrice ABC DEF.
Remarque que ma fonction d'affichage peut afficher n'importe quelle taille de matrices

$ cat matrix.c 
#include <stdio.h>
#include <stdlib.h>

void* my_malloc(size_t n);

void* my_malloc(size_t n) {
	if(n == 0) return NULL;
	void *p = malloc(n);
	if(p == NULL) {
		exit(EXIT_FAILURE);
	}
	return p;
}

typedef struct Matrix {
	int n1;
	int n2;
	char *p;
} Matrix;


char* begin_matrix(Matrix *m);
char* end_matrix(Matrix *m);
Matrix* create_matrix(int n1, int n2);
void free_matrix(Matrix *m);
char get_matrix(Matrix *m, int i, int j);
void set_matrix(Matrix *m, int i, int j, char c);
void affiche_matrix(Matrix *m);

char* begin_matrix(Matrix *m) {
	return m->p;
}
char* end_matrix(Matrix *m) {
	return m->p + (m->n1 * m->n2);
}

Matrix* create_matrix(int n1, int n2) {
	if(n1 <= 0) {
		fprintf(stderr, "bad matrix dim1: %d", n1);
		exit(EXIT_FAILURE);
	}
	if(n2 <= 0) {
		fprintf(stderr, "bad matrix dim2: %d", n2);
		exit(EXIT_FAILURE);
	}
	Matrix *m = my_malloc(sizeof(*m));
	m->n1 = n1;
	m->n2 = n2;
	m->p = my_malloc(n1*n2*sizeof(*(m->p)));
	return m;
}

void free_matrix(Matrix *m) {
	if(m == NULL) return;
	free(m->p);
	free(m);
}

char get_matrix(Matrix *m, int i, int j) {
	return m->p[(i * m->n2) + j];
}
void set_matrix(Matrix *m, int i, int j, char c) {
	m->p[(i * m->n2) + j] = c;
}

void affiche_matrix(Matrix *m) {
	char * first = begin_matrix(m);
	for(int i = 0 ; i < m->n1 ; ++i) {
		for(int j = 0 ; j < m->n2 ; ++j) {
			printf("%c ", *first++);
		}
		printf("\n");
	}
}

int main() {
	Matrix *m = create_matrix(2,3);
	char c = 'A';
	char *first = begin_matrix(m);
	char *last = end_matrix(m);
	//matrice ABC DEF
	while(first != last) *first++ = c++;

	affiche_matrix(m);

	free_matrix(m);
	m = NULL;
}
$ gcc -o test matrix.c && ./test
A B C 
D E F 

Dernière modification par grigouille (Le 27/04/2021, à 08:05)


Debian (xfce) 12
HP LaserJet M1132 MFP

Hors ligne

#7 Le 30/04/2021, à 18:17

zephyre123

Re : Compréhension notation pointeur avec les matrices ?

J'ai modifié le code la j'obtiens bien les mêmes adresses :
code ci dessous :

#include <stdio.h>
#include <stdlib.h>

// SOIT UN TABLEAU DE CHAR À 1 DIMENSION
char tableau[2] =
{'A', 'B'};

char matrice[2][3] =
{
	{'A', 'B', 'C'},
	{'D', 'E', 'F'}
};

void affichageTableau(char *tableau)
{
	// AFFICHAGE AVEC LA NOTATION ENTRE CROCHET :
	for (int i = 0; i < 2; i++)
		printf("Le tableau[%d] = %c et a pour adresse : %p\n", i, tableau[i], &tableau[i]);

	printf("\n\n");

	// AFFICHAGE AVEC LA NOTATION POINTEUR :
	for (int i = 0; i < 2; i++)
		printf("Le tableau[%d] = %c et a pour adresse : %p\n", i, *(tableau + i), tableau + i);
}


void affichageMatrice(char (*pMatrice)[2][3])
{
	// AFFICHAGE AVEC LA NOTATION ENTRE CROCHET :
	for (int ligne = 0; ligne < 2; ligne++)
		for (int colonne = 0; colonne < 3; colonne++)
			printf("La matrice[%d][%d] = %c et a pour adresse : %p\n", ligne, colonne, matrice[ligne][colonne], &matrice[ligne][colonne]);

	printf("\n\n");

	// AFFICHAGE AVEC LA NOTATION POINTEUR :
	for (int ligne = 0; ligne < 2; ligne++)
	{
		printf("L'adresse de la ligne : %d = %p\n",ligne + 1,  *(pMatrice + ligne));
		// *(pMatrice + ligne) = pointeur sur la ligne i + 1
		

		for (int colonne = 0; colonne < 3; colonne++)
		{
			char *pLigne = *(matrice + ligne);
			printf("La matrice[%d][%d] = %c et à pour adresse : %p\n", ligne, colonne, *(pLigne + colonne), (*(matrice + ligne)) + colonne);
		}
	
	}
}


int main(void)
{
//	affichageTableau(tableau);
  	affichageMatrice(&matrice);
	return EXIT_SUCCESS;
}

	/* SE RAPPELER DE L'ÉQUIVALENCE SUIVANTE :
	 * Soit T un tableau  :
	 * T[0] (valeur) <=> *(T + 0) = *T (T est l'adresse du premier elemement du tableau)
	 * T[1] (valeur) <=> *(T + 1)      
	 * ...
	 * T[i] (valeur <=> *(T + i)
	 */

	/* C'EST EXACTEMENT LA MÊME CHOSE  POUR UNE MATRICE
	 * Soit M une matrice  de deux dimensions, nombre de ligne = i et nombre de colonne = j :
	 * *(M + i) = pointeur de ligne
	 * M[i][j] = * (*(M + i) + j)
	 * 
	 * Les deux opérateur '&' et '*' sont complémentaire
	 * M[i][j] = * (*(M + i) + j) <=> & (...) = &(*(....)) = (...)
	 */

Es ce que tu peux me confirmer @Kamaris que je n'ai pas fais d'erreur stp ?
J'attends ta confirmation avant de fermer le sujet.

Dernière modification par zephyre123 (Le 30/04/2021, à 18:20)

Hors ligne

#8 Le 01/05/2021, à 12:28

kamaris

Re : Compréhension notation pointeur avec les matrices ?

C'est bon pour les éléments de la matrice, mais il reste une erreur sur l'affichage de la seconde ligne dans affichageMatrice(), car tu mélanges toujours variables globales et locales, et que tu ne déréférences pas pMatrice.

Voici, partant de ton code, un code qui sépare bien les trois cas :
* notation tableau ;
* notation pointeur passé par référence ;
* notation pointeur global.

#include <stdio.h>
#include <stdlib.h>

char matrice[2][3] =
{
  {'A', 'B', 'C'},
  {'D', 'E', 'F'}
};

static void affichageMatriceReference (char (*pMatrice)[2][3])
{
  for (int ligne = 0; ligne < 2; ligne++)
  {
    printf("L'adresse de la ligne : %d = %p\n", ligne + 1,  *(*pMatrice + ligne));

    for (int colonne = 0; colonne < 3; colonne++)
    {
      char *pLigne = *(*pMatrice + ligne);
      printf("La matrice[%d][%d] = %c et à pour adresse : %p\n", ligne, colonne, *(pLigne + colonne), *(*pMatrice + ligne) + colonne);
    }
  }
}

static void affichageMatriceGlobale (void)
{
  for (int ligne = 0; ligne < 2; ligne++)
  {
    printf("L'adresse de la ligne : %d = %p\n", ligne + 1,  *(matrice + ligne));

    for (int colonne = 0; colonne < 3; colonne++)
    {
      char *pLigne = *(matrice + ligne);
      printf("La matrice[%d][%d] = %c et à pour adresse : %p\n", ligne, colonne, *(pLigne + colonne), *(matrice + ligne) + colonne);
    }
  }
}

int main(void)
{
  printf("\nAFFICHAGE AVEC LA NOTATION ENTRE CROCHETS\n");
  for (int ligne = 0; ligne < 2; ligne++)
    for (int colonne = 0; colonne < 3; colonne++)
      printf("La matrice[%d][%d] = %c et a pour adresse : %p\n", ligne, colonne, matrice[ligne][colonne], &matrice[ligne][colonne]);

  printf("\nAFFICHAGE AVEC LA NOTATION POINTEUR PAR REFERENCE\n");
  affichageMatriceReference (&matrice);

  printf("\nAFFICHAGE AVEC LA NOTATION POINTEUR GLOBAL\n");
  affichageMatriceGlobale ();

  return EXIT_SUCCESS;
}

Hors ligne