Rechercher : dans
Par :

Comment renvoyer un tableau en C++ ??

Dernière réponse le 15 jan 2005 à 21:13:23 pom, le 10 jan 2005 à 10:19:27 
 Signaler ce message aux modérateurs

Bonjour, j'ai un std::vector v d'une longueur L (L=v.size()) et je sais que L est un multiple de N (const int N). N est connu.
Je voudrais convertir v en un tableau de tableau.

Mon idée est la suivante :
const unsigned int ligne=v.size()/N; // nombre de ligne de mon tableau à N colonnes

double tab[ligne][N]={0.};

unsigned long int compteur=0;
for(int i=0;i<ligne;i++)
for(int j=0;j<N;j++)
{
tab[i][j]=v[compteur];
compteur++;
}

Jusqu'à là, l'algo est facile.
Je voudrais en fait faire une fonction conversion qui me convertit mon std::vector en tableau de tableau. Mais comment déclarer cette fonction ??

double mon_tableau_de_tableau conversion(const std::vector<double> & v,const int & N)
{
// je recopie l'algo ci-dessus

return tab;
}

mais comment renvoyer un tableau de tableau avec une fonction ?

Merci beaucoup
Pom

Meilleures réponses pour « comment renvoyer un tableau en C++ ?? » dans :
Décaler les éléments d'un tableau (Rotation) -Récursivité- VoirVoici une procédure récursive qui permet de décaler tous les éléments d’un tableau d’une position à droite à partir de la position p Procedure Decaler (Var t : Tab; p, n : integer); Begin If p
Trier un tableau sans utiliser la fonction sort VoirTrier un tableau sans utiliser la fonction sort D'abord on initialise une variable $max avec la 1ère valeur de tableau. Ensuite on va faire une boucle tant que le tableau contient encore des éléments. C'est avec la fonction splice qui a le rôle...
Les structures en langage C VoirDifférence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de...
Langage C - Les chaînes de caractères VoirQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C, une chaîne...
Langage C - Les tableaux VoirType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes...

1

tafiscobar, le 10 jan 2005 à 10:37:47

Pour renvoyer un tableau en C/C++, c'est impossible. D'ou l'interet des pointeurs. Tu declares ton tableau coe pointeur et tu renvoies ce pointeur.

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

2

pom, le 10 jan 2005 à 11:12:20

Ah d'accord, mais comme je voudrais avoir un tableau de tableau (car après ce trace mes courbes avec Matalb) je dois donc faire un pointeur sur un pointeur d'un double ou qqch comme ca non ?

Répondre à pom

3

pom, le 10 jan 2005 à 11:20:22

Voici ma fonction conversion qui renvoie dont un pointeur sur un double

#include<iostream>
#include<vector>

using namespace std;

double * conversion(vector<double> & v,const int & N)
{

const int ligne=v.size()/N;
double tab[ligne][N];
unsigned int compteur=0;

for(int i=0;i<ligne;i++)
for(int j=0;j<N;j++)
{
tab[i][j]=v[compteur];
compteur++;
}

return tab;
}

mais voici le message d'erreur :
cannot convert `double (*)[N]' to `double*' in return

j'ai essayé de renvoyer un double ** mais ca ne marche pas vraiment...

Merci encore

Répondre à pom

5

tafiscobar, le 11 jan 2005 à 12:14:07

double **f (-) {
double **tab ; // tu lui alloue aprés de la mémoire
...
return tab;
}

RM: n'oublie pas de désallouer ce q te retourne ta fct lorsq t'en auras plus besoin, sinon t'auras des fuites de mémoire.

L'autre solution, c'est de déclarer ton tableau a l'extérieur de ta fct et tu le donnes en paramétres a ta fonction. Mais ce n'est pas propre et pas joli, mais cela dépend de ce que tu fais ds ton code.

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

4

Ravachol, le 10 jan 2005 à 11:33:41

Salut,
Si tu renvois double ** il faut écrire return &tab. Mais tab étant alloué dans la fonction tu risques te te retrouver avec un pointeur pointant sur une zone désallouée.

A++

C'est pas parce qu'ils sont nombreux à avoir tort
qu'ils ont raison! (COLUCHE)

Répondre à Ravachol

6

pom, le 11 jan 2005 à 16:02:37

Bonjour, je suis un peu perdu pas vos réponses...
Voici ce que j'ai fait :

double ** conversion(vector<double> & v,const int & N)
{

const int ligne=v.size()/N;
double** tab; // ne faudrait-il pas faire double ** tab=new qqch ?
unsigned int compteur=0;

for(int i=0;i<ligne;i++)
for(int j=0;j<N;j++)
{
tab[i][j]=v[compteur]; // comment lui faire comprendre l'élément (i,j) ?
compteur++;
}

return tab;
}

Mais ca plante à tab[i][j]=v[compteur];

Merci encore

Répondre à pom

7

Ravachol, le 11 jan 2005 à 18:48:22

Salut,
Tu pourrais peut-être t'inspirer de cet exemple:
http://perso.enst-bretagne.fr/~brunet/Cours/Gestion_Memoire/­TutCpp_Mem_Part1.html

A++

C'est pas parce qu'ils sont nombreux à avoir tort
qu'ils ont raison! (COLUCHE)

Répondre à Ravachol

8

pom, le 12 jan 2005 à 09:13:00

Merci ! je pense qu'avec ton lien je vais trouver mon bonheur !
Mais si je veux "pousser le bouchon un peu plus loin" : je m'étais fait une classe Matrice de la manière suivante :
double * m=new double[nb_ligne*nb_colonne];

L'avantage, comme l'explique ton lien que tu m'as envoyé, est que si je veux remplacer une ligne, c'est plus rapide que par ma classe matrice. Mais d'un point de vu temps d'accès à un élément d'une matrice, lequel sera plus rapide ? Le double **m; ou bien mon double * m ?

Merci bcp en tout cas !
Pom

Répondre à pom

9

Ravachol, le 12 jan 2005 à 09:48:09

Salut,
Pour ma part, n'ayant pas une très grosse expérience en C++ je ne me hazarderais pas à te donner une réponse en terme de différence du tps d'accès à un élément, au risque de dire une ânerie. Joker donc ;-)
Plus sérieusement, je préfère laisser l'éventuelle réponse à un spécialiste C++.

A++

C'est pas parce qu'ils sont nombreux à avoir tort
qu'ils ont raison! (COLUCHE)

Répondre à Ravachol

11

tafiscobar, le 12 jan 2005 à 15:00:47

Si on réfléchit en terme de "ticks" d'horloge, c'est plus cher car il ya une indirection de plus. Mais, je ne pense pas que cela soit couteux ds ton cas.

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

12

pom, le 12 jan 2005 à 16:50:35

Salut, j'ai fait des tests et voici mes résultats :

class Matrice
{
double * m;

blabla
};

class Matrice2
{
double **m;
blabla
}

Matrice m1(50,50)
Matrice m2(50,50)

Matrice m3=m1*m2

Matrice2 m4(50,50)
Matrice2 m5(50,50)

Matrice2 m6=m4*m5

double m7[50][50];
double m8[50][50];
double m9[50][50];

m9=m7*m8 (a été programé)

Je répète 10 000 fois chaque multiplication et je calcule le temps mis.

Matrice 37 s
Matrice2 33s
sans les pointeurs (variables m9) : 30 s

Je comprends tout à fait que sans les pointeurs cela aille plus vite mais je ne comprend pas pourquoi avec un double ** ca va plus vite qu'avec un double * (meme si le gain n'est pas probant)

Répondre à pom

13

tafiscobar, le 13 jan 2005 à 20:16:27

Salut, je peux voir comment tu accédes a tes elts ds le cas double* ?

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

14

pom, le 14 jan 2005 à 10:03:35

Salut, dans le cas d'un double * :
c est le nb de colonne, et mes elements vont de 1 a nb ligne ou nb colonne (et non de 0 a nb ligne-1)

inline const double& Matrice::operator()(ulong i,ulong j) const {assert((i<=l) && (i>0) && (j>0) && (j<=c)); return m[(i-1)*c+(j-1)];}

inline double& Matrice::operator()(ulong i,ulong j) {assert((i<=l) && (i>0) && (j>0) && (j<=c)); return m[(i-1)*c+(j-1)];}

Dans le cas d'un double ** :

inline const double& Matrice::operator()(uint i,uint j) const {assert((i<=NB_LIGNE) && (i>0) && (j>0) && (j<=NB_COL)); return m[i-1][j-1];}

inline double& Matrice::operator()(uint i,uint j) {assert((i<=NB_LIGNE) && (i>0) && (j>0) && (j<=NB_COL)); return m[i-1][j-1];}

Voila, j'espere que c'est comprehensible

Répondre à pom

15

tafiscobar, le 14 jan 2005 à 16:35:51

Salut, c'est normal que double* coute plus cher car tu fais une multiplication et c'est plus couteux q'une addition. Et voila.

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

16

pom, le 14 jan 2005 à 22:43:59

Evidemment, dis comme ça...

Merci encore de ton aide !

Répondre à pom

17

 tafiscobar, le 15 jan 2005 à 21:13:23

Lorsq je te disais que matrice avec double* coute moins cher, je pensais a l'acces direct (tab[i]).

tafiscobar "lou waye def bopame"
la nullite n'existe pas, l'ignorance oui, ah je suppose!!!

Répondre à tafiscobar

10

pom, le 12 jan 2005 à 10:46:01

Ok, merci de ton honneté (et de ton immense coup de main)

Pom

Répondre à pom