Fonction qui renvoie une structure

Fonction qui renvoie une structure - C++ - Programmation

Marsh Posté le 10-05-2017 à 12:21:36    

Salut à tous,
 
Je suis extrêmement novice en c++ (j'ai commencé sérieusement il y a 2 semaines) et je bute sur un problème de renvoie de structure par une fonction. Voici ma fonction :

Code :
  1. #ifndef OPTICALINDEXFUNCTION_H_INCLUDED
  2. #define OPTICALINDEXFUNCTION_H_INCLUDED
  3. double opticalIndexSi3N4(int energy, int energyStart, int energyEnd)               
  4. {
  5.     double const hc(1.987e-25);             
  6.     double const A(1.897);                 
  7.     double const B(17.91e-3);
  8.     double const C(87.285e-5);
  9.     double lambda(0);         
  10.     double nSi3N4[((energyEnd - energyStart) + 1)];           
  11.     for (int i(0); i < ((energyEnd - energyStart) + 1); i++)
  12. {
  13.         energy = energyStart + i;
  14.         lambda = hc/(energy*1e-3*1.602e-19)*1e9;
  15.         nSi3N4[i] = A + B/pow(lambda,2) + C/pow(lambda,4);
  16. }
  17.     struct nSi3N4Structure
  18.     {
  19.         nSi3N4[];
  20.     };
  21.     return nSi3N4Structure;
  22. }
  23. #endif // OPTICALINDEXFUNCTION_H_INCLUDED


 
A la fin je souhaite avoir un tableau de i élément que je pourrais renvoyer dans ma fonction main pour l'utiliser. Le code main est le suivant :  
 

Code :
  1. #include <iostream>           
  2. #include <fstream>             
  3. #include <cmath>               
  4. // Personal function
  5. #include "../opticalIndexFunction.h"
  6. using namespace std;           
  7. int main()
  8. {
  9. int const energyStart(1000);         // Starting energy, in meV
  10. int const energyEnd(3000);         // Ending energy, in meV
  11. int energy(0);
  12. double nSi3N4[((energyEnd - energyStart) + 1)];            // Array declaration for storing optical index of Si3N4
  13. // nSi3N4;
  14. nSi3N4 = opticalIndexSi3N4(energy, energyStart, energyEnd);
  15. // cout << nSi3N4[1] << endl;
  16. }


 
Le problème c'est que ça ne fonctionne pas et j'obtiens l'erreur suivante : ....\opticalIndexFunction.h|23|error: 'nSi3N4' does not name a type|
 
Une idée d'où pourrait venir mon problème ?
 
D'ailleurs si vous avez un bon pdf/site pour apprendre le language, je suis preneur, j'ai commencé avec openclassrooms mais je n'ai pas l'impression que ce soit très complet.
 
Merci d'avance pour votre aide !

Reply

Marsh Posté le 10-05-2017 à 12:21:36   

Reply

Marsh Posté le 10-05-2017 à 13:46:31    

1/ tu ne peux pas avoir un tableau dans une structure sans donner le nombre d'éléments que ce tableau doit contenir (nombre qui doit être connu à la compilation). Si tu veux un nombre variable d'éléments, il va falloir passer par un mécanisme d'allocation dynamique.
 
2/ Tu ne peux pas retourner une structure quand ta fonction annonce qu'elle retourne un double.


---------------
last.fm
Reply

Marsh Posté le 10-05-2017 à 14:57:12    

Ok pour le point 2/, j'imagine qu'il faut mettre struct à la place de double.
Par contre pour le 1/, je déclare bien le nombre d'élément à la ligne : double nSi3N4[((energyEnd - energyStart) + 1)] non ?

Reply

Marsh Posté le 10-05-2017 à 17:21:10    

Moltonnel a écrit :

Ok pour le point 2/, j'imagine qu'il faut mettre struct à la place de double.
Par contre pour le 1/, je déclare bien le nombre d'élément à la ligne : double nSi3N4[((energyEnd - energyStart) + 1)] non ?


 
Hmm, il parle de ta structure "nSi3N4Structure": sa déclaration ne veut rien dire. On dirait que tu espérait encapsuler le tableau "nSi3N4" dans une structure pour retourner la valeur au programme appelant, parce que t'as du lire quelque part que les tableaux ne se manipulent que par adresse.
 
Ce n'est pas pour rien que les tableaux se manipulent par adresse: c'est pour éviter les copies inutiles. Dans ton main(), tu veux modifier ton tableau, donc transmet ça directement à ta fonction :

Code :
  1. #include <iostream>
  2. #include <fstream>
  3. #include <cmath>
  4. // Personal function
  5.  
  6. using namespace std;
  7.  
  8. void opticalIndexSi3N4(double * nSi3N4, int energy, int energyStart, int energyEnd)
  9. {
  10.     double const hc(1.987e-25);
  11.     double const A(1.897);
  12.     double const B(17.91e-3);
  13.     double const C(87.285e-5);
  14.     double lambda(0);
  15.     for (int i(0); i < ((energyEnd - energyStart) + 1); i++)
  16.     {
  17.             energy = energyStart + i;
  18.             lambda = hc/(energy*1e-3*1.602e-19)*1e9;
  19.             nSi3N4[i] = A + B/pow(lambda,2) + C/pow(lambda,4);
  20.     }
  21. }
  22. int main()
  23. {
  24.     int const energyStart(1000);         // Starting energy, in meV
  25.     int const energyEnd(3000);         // Ending energy, in meV
  26.     int energy(0);
  27.     double nSi3N4[((energyEnd - energyStart) + 1)];            // Array declaration for storing optical index of Si3N4
  28.     // nSi3N4;
  29.     opticalIndexSi3N4(nSi3N4, energy, energyStart, energyEnd);
  30.     // cout << nSi3N4[1] << endl;
  31. }


 
Idéalement, ça serait mieux de passer par des std::vector, parce que ton tableau fait quand même 16008 octets, alloués sur la pile. Ça commence à ne pas être négligeable. Mais bon, dans la mesure où tu débutes, on va pas brusquer les choses...

Reply

Marsh Posté le 10-05-2017 à 20:25:46    

Merci pour ton aide !
 

tpierron a écrit :


 
Hmm, il parle de ta structure "nSi3N4Structure": sa déclaration ne veut rien dire. On dirait que tu espérait encapsuler le tableau "nSi3N4" dans une structure pour retourner la valeur au programme appelant, parce que t'as du lire quelque part que les tableaux ne se manipulent que par adresse.
 


 
Effectivement, j'essayais de faire des choses similaires à ce qu'on peut faire avec des langages un peu plus permissif comme python ou matlab, que je maîtrise un peu mieux. Mauvaise idée  [:tinostar] .
 

tpierron a écrit :


 
Ce n'est pas pour rien que les tableaux se manipulent par adresse: c'est pour éviter les copies inutiles. Dans ton main(), tu veux modifier ton tableau, donc transmet ça directement à ta fonction :
 


 
Si j'ai bien compris l'idée c'est d'utiliser un pointeur, d'où le double * nSi3N4, pour éviter la copie. J'ai pourtant cru comprendre qu'il valait mieux éviter et laisser le RVO du compiler gérer ce genre de choses. C'est faux du coup ?
 

tpierron a écrit :


 
Idéalement, ça serait mieux de passer par des std::vector, parce que ton tableau fait quand même 16008 octets, alloués sur la pile. Ça commence à ne pas être négligeable. Mais bon, dans la mesure où tu débutes, on va pas brusquer les choses...
 


 
Quel est l'avantage de passer par un vector puisque je connais dès le départ la taille de mon tableau ? Le fait d'allouer dynamiquement permet d'effectuer les calculs plus rapidement ?

Reply

Marsh Posté le 10-05-2017 à 21:43:48    

Moltonnel a écrit :


Si j'ai bien compris l'idée c'est d'utiliser un pointeur, d'où le double * nSi3N4, pour éviter la copie. J'ai pourtant cru comprendre qu'il valait mieux éviter et laisser le RVO du compiler gérer ce genre de choses. C'est faux du coup ?


 
Non, ce n'est pas faux, mais il faut des objets qui soient pensés avec ça en tête. Avec l'idée que tu avais de ton code, il y avait aucune chance pour qu'il y ait la moindre optimisation de ce genre.
 

Moltonnel a écrit :


Quel est l'avantage de passer par un vector puisque je connais dès le départ la taille de mon tableau ? Le fait d'allouer dynamiquement permet d'effectuer les calculs plus rapidement ?


Ah, es-tu vraiment sûr que c'est figé dans le marbre ? Le programme est trivial pour le moment, mais si jamais tu te rends compte que ça doit varier un moment, si toute ta logique est faite avec des tableaux, ça va être un peu la merde à changer.

Reply

Marsh Posté le 11-05-2017 à 14:02:23    

Ben dans ce cas la, il peut créer (avec new) un objet de classe std::array que retournera sa fonction non?
std::array<float, N> ou N est la constexpr venant de la diff de ses deux constantes.
Pas de manips (insertions/suppressions) sur son objet, donc pourquoi utiliser un std::vector?
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed