Déréférencer de pointeur

Signaler
Messages postés
15
Date d'inscription
mercredi 2 mars 2011
Statut
Membre
Dernière intervention
20 avril 2011
-
Messages postés
15
Date d'inscription
mercredi 2 mars 2011
Statut
Membre
Dernière intervention
20 avril 2011
-
Bonjour à tous et merci d'avance pour vos réponses.

Je suis actuellement entrain de transposer un code Matlab en c++.
Pour cela j'utilise une petite classe matrice assez élémentaire que j'ai codé, en utilisant des pointeurs de pointeurs (pas de classe template ni de valarray ou vector, seulement des double** et ça marche très bien ^^)

Le problème qui se pose pour moi c'est qu'en mathlab le 1er éléments d'une matrice est (1,1) et le dernier (n,m) alors que bien entendu l’arithmétique des pointeurs en c++ impose de débuter à (0,0) et finir à (n-1,m-1).

Est-il possible pour des raisons de gain de tps de modifier cette contrainte pour ne pas avoir à déréférencer à chaque fois mes boucles, ce qui me ferrait gagner pas mal de tps ...
en gros avoir des pointeurs dont le 1er termes et [1][1] ... [n][m]


Merci d'avance pour vos suggestions.

7 réponses

Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114
Non, ce n'est pas possible :)
Un tableau en C, est une adresse. Donc faire tab[0] équivaut à l'adresse du pointeur tab (décalage de 0), alors que tab[2] correspond à l'adresse de tab décalé de deux éléments (décalage de "type * 2"). C'est la raison pour laquelle on commence à 0. C'est une base très importante du langage, et ce n'est pas bien entendu pas modifiable.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
15
Date d'inscription
mercredi 2 mars 2011
Statut
Membre
Dernière intervention
20 avril 2011

Sauf erreur de ma part. une grande partie Mathlab n'est elle pas codé en C ?
Dans ce cas comment ce fait il que ce soit le cas sous mathlab ?

Je te remercie CptPingu pour ta réponse.

En fait ce que j’espérais n'est pas tant de modifié le langage C en soit mais une technique ou astuce pour palier ce problème .

J'avais par exple pensé d'initialiser ma première ligne et ma première colonne à zéro et d'augmenter de +1 ligne, +1colonne la dimension de ma matrice pour ensuite pouvoir travaillé sur la sous matrice. (idée certes stupides ... vu qu'on consomme de la mémoire pour rien) quoi qu'il en soit c'est une optimisation ou astuce dans ce sens que je cherchais !

En Espérant avoir été plus clair.
Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114
Matlab, a peut être été codé en C, mais son implémentation est différente. Si je code mon propre langage en C, je peux faire commencer les tableaux à la valeur que je veux (pourquoi pas 36 :p).
Le C a été conçu pour que les tableaux commencent à 0, et ça ne peut être changé.

J'ai du mal à cerner en quoi c'est un problème gênant. Si tu as tab[1], tu mets à la place tab[0] et c'est reglé.
Si tu as l'habitude de faire:
for (int i = 1; i <= size; ++i)
tu remplaces par:
for (int i = 0; i < size; ++i)

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114
J'oubliais, rien ne t'empêche de faire une fonction à la place.
Ex:
Au lieu de tab[0][0], tu peux faire un get(tab, 1, 1).

Avec get:
int get(int** tab, int x, int y)
{
  return tab[x - 1][y - 1];
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
15
Date d'inscription
mercredi 2 mars 2011
Statut
Membre
Dernière intervention
20 avril 2011

Oui certes mais ceci est simple qd les cases auxquelles tu veux accéder sont linéaire.

Je m'explique :

prenons un vecteur - je souhaite accéder au composante de la forme 3*i-2, sous mathlab.
ca donne simplement

for i=1:N
T(3*i-2);

en c++ :

for (i=0 ; i<N ; i++) // on décale la boucle jusque là ok !
T[3*i]; // il faut aussi décaler l'indice des Tab

ceci est un exple tout bête, qui devient vite compliqué qd tu travailles sur des matrices et que tu récupères des valeurs d'autre matrice ds tes boucles...
C'est pas infaisable ça fait juste perdre un peu de tps de décaler tes indices,
ça permet surtout de comparer plus facilement les deux codes.

D'où ma question ^^
Messages postés
3829
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
8 janvier 2021
114

for i=1:N
T(3*i-2);


En C++:

template <typename T>
T get(T* tab, int x)
{
  return tab[x - 1];
}
template <typename T>
T get(T** tab, int x, int y)
{
  return tab[x - 1][y - 1];
}
template <typename T>
T get(T*** tab, int x, int y, int z)
{
  return tab[x - 1][y - 1][z - 1];
}


Ensuite, tu peux faire:

for (int i = 1 ; i <= N ; ++i)
  get(T, 3 * i - 2);//T[3 * i - 2];

for (int i = 1 ; i <= N ; ++i)
  for (int j = 1 ; j <= N ; ++j)
    get(T, 3 * i - 2, 3 * j - 2);//T[3 * i - 2][3 * j - 2];


Fonctionne avec n'importe quel type de tableau, de 1 à 3 dimensions.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
15
Date d'inscription
mercredi 2 mars 2011
Statut
Membre
Dernière intervention
20 avril 2011

en effet en effet ... ton idée m'a bien inspiré :

j'ai modifié ma class Matrice comme ceci :

double & Matrice::operator()(unsigned int i, unsigned int j)
{
  if( i>= nbre_lignes || j >=nbre_colonnes)
  {
  throw std::string("Hors plage de valeurs");
  }
  return lignes[i-1][j-1]; // j'avais mis [i][j]
}


Comme j'ai fait cette classe il y as un petit moment déjà ça ne m'est même pas venu à l'idée ^^

En tout cas Merci !!!!!!