IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Problème de compilation avec un tableau passé à une fonction


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 31
    Points : 26
    Points
    26
    Par défaut Problème de compilation avec un tableau passé à une fonction
    Bonjour à tous,
    J'ai un soucis avec un code qui, j'ai l'impression, est pourtant tout bête...
    Voilà l'idée : j'ai 2 fichiers séparés.
    Le fichier 1 comporte 2 fonctions :
    - une fonction de création d'un tableau de coefficients :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    double* init_scale(int Ncol, ...)
    {
    	double *coefs = new double [Ncol*2];
    	// Remplissage du tableau coefs
    	for (j=0;j<Ncol;j++)
    	{
    		coefs[2*j] = (b-a)/(xmax - xmin);
    		coefs[2*j+1] = a - xmin * coefs[2*j];
    	}
    Je ne mets cet extrait de code que pour info sur la construction de coefs, il fonctionne en effet très bien.

    - une fonction de calcul d'une data à partir de ces coefficients :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void scale(double* data, int ind, double* coefs)
    {
    	data = coefs[2*ind] * data + coefs[2*ind+1]; // Ligne où a été détecté une erreur par le compilateur
    }
    Dans mon deuxième fichier, j'ai plusieurs fonctions dont notamment la fonction main(...) et une fonction qui fait appel à scale(...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void predict(double* coefs, ...)
    {
    	int ind = 0;
    	double fbuff = 0.;
    	// Boucle sur ind
    	// Donne une valeur non nulle à fbuff, puis :
    	scale(&fbuff,ind,coefs);
    	// Utilisation de fbuff, fin du code
    }
    Je veux donc passer mon tableau de coefs à la fonction scale pour qu'elle modifie la valeur de fbuff (qui est donc passé comme pointeur). Or, quand j'essaye de compiler, j'obtiens l'erreur suivante :
    error C2297: '*' : non conforme, l'opérande droit est du type 'double *'

    J'ai cherché mais je ne vois pas où est l'erreur dans mon code... Merci de m'aider à y voir plus clair !

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    Tu déclare data comme pointeur et tu l'utilises comme variable. Il faut choisir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void scale(double* data, int ind, double* coefs)
    {
    	*data = coefs[2*ind] * (*data) + coefs[2*ind+1]; // Ligne où a été détecté une erreur par le compilateur
    }
    Quelques remarques :
    1/Si tu veux changer la valeur de data, nul besoin de passer par des pointeurs. Tu peux utiliser les références :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void scale(double& data, int ind, double * coefs)
    {
    	data = coefs[2*ind] * data + coefs[2*ind+1];
    }
    2/ Si coefs n'a pas vocation à être modifié, alors passe-le par const :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void scale(double& data, int ind, double const * coefs)
    {
    	data = coefs[2*ind] * data + coefs[2*ind+1];
    }
    3/ Si tu veux vraiment avoir moins de soucis, utilises des conteneurs (std::vector semble approprié à ton cas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     init_scale(int Ncol, std::vector<double> &vect_)
    {
            vect_.resize(Ncol*2);
    	// Remplissage du tableau coefs
    	for (j=0;j<Ncol;j++)
    	{
    		vect_[2*j] = (b-a)/(xmax - xmin);
    		vect_[2*j+1] = a - xmin * vect_[2*j];
    	}
    etc...

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 632
    Points : 30 711
    Points
    30 711
    Par défaut
    Salut,

    Attention au fait que ton argument data est un pointeur...

    C'est à dire que, si tu ne précise pas que tu veux travailler avec "ce qui est pointé" par data, tu va modifier... l'adresse mémoire qui est pointée par data...
    Pour l'instant, ta formule essaye de faire
    data (pointeur) = coef[2*ind](pas pointeur)* data(pointeur)+coef[2*ind+1](pas pointeur)...

    Il faut donc faire de manière à ne travailler qu'avec des pointeurs (mais cela ne donnera pas le réslutat souhaité, dans ce cas) ou qu'avec des... "non pointeurs", ce qui te donnera le résultat souhaité.

    Tu dois donc transformer la formule en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (*data) = coef[2*ind] * (*data) +coef[2*ind+1];
    Ceci dit, L'utilisation des pointeurs est de nature à apporter énormément de problèmes, ainsi que tu as pu t'en rendre compte...

    C'est pourquoi on conseille toujours de préférer les conteneurs fournis par le standard comme, par exemple la classe vector, disponible dans l'espace de noms std par inclusion du fichier d'en-tête <vector>, qui fourni exactement les mêmes comportement qu'un tableau alloué dynamiquement, mais avec une sécurité et une facilité d'utilisation bien supérieure.

    C'est aussi pourquoi on conseille de préférer l'utilisation de référence lorsqu'il s'agit, simplement, de s'assurer que les modification apportées dans une fonction à un argument de celle-ci soient répercutées dans la fonction appelante...

    Une autre solution pour t'éviter d'avoir à manipuler data sous la forme d'un pointeur est de modifier le prototype de ta fonction scale en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    double scale(double data, int ind, double* coefs)
    {
        data = coefs[2*ind] * data + coefs[2*ind+1];
        return data;
    }
    et son appel en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    buf = scale(fbuff,ind,coefs);

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 31
    Points : 26
    Points
    26
    Par défaut
    Merci pour vos réponses très rapides !

    Citation Envoyé par 3DArchi Voir le message
    Bonjour,
    Tu déclare data comme pointeur et tu l'utilises comme variable. Il faut choisir :
    Oups, c'était donc ça

    Merci aussi pour tes remarques judicieuses ! Du coup, j'ai préféré passer data par référence. J'avais aussi bien prévu de passer coefs en const, parce qu'il ne doit pas être changé (comme tu l'as bien imaginé), mais j'avais laissé un peu ça de côté le temps de résoudre mon erreur. J'ai donc à présent ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void scale(double& data, int ind, double const * coefs)
    {
    	data = coefs[2*ind] * data + coefs[2*ind+1];
    }
    et cette nouvelle erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    1>Édition des liens en cours...
    1>svmclassifier.obj : error LNK2019: symbole externe non résolu "void __cdecl scale(double,int,double const *)" (?scale@@YAXNHPBN@Z) référencé dans la fonction "void __cdecl predict(double *,char const *)" (?predict@@YAXPANPBD@Z)
    1>...\svmClassifier\Debug\svmClassifier.exe : fatal error LNK1120: 1 externes non résolus
    svmclassifier étant mon Fichier2. C'est la première fois que je vois ça... Je précise que je travaille sous Windows avec Visual Studio 2005.


    Pour le coup du conteneur vector, j'avoue ne pas avoir le réflexe encore (j'ai commencé le C++ en Octobre 2008, et pas beaucoup pratiqué en dehors des cours). Comme vous êtes deux à m'en parler, je comprends bien que c'est beaucoup plus approprié ! Je vais modifier ça après, à moins que ça n'arrange mes affaires concernant l'erreur au-dessus ? Je vais voir ça, en tout cas.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ton erreur est due à une différence entre la déclaration et la définition : tu as oublié la référence dans la déclaration...
    Je te conseille vivement de passer par les std::vector. C'est fait pour gérer un tableau sans se soucier des problèmes d'allocation.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 31
    Points : 26
    Points
    26
    Par défaut

    Décidément... on va dire que c'est Vendredi et que c'est pas facile...
    C'était bien ça, merci !

    Je vais de ce pas transformer mon tableau coefs en vecteur !

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 31
    Points : 26
    Points
    26
    Par défaut
    Bouh >___<
    J'ai changé mon tableau coefs en conteneur vector. J'ai fait attention (mais peut-être pas assez, visiblement) à ce que ce soit bien cohérent partout où il apparaît dans le code, et que mes définitions et déclarations de fonctions soient bien les mêmes.
    Et j'obtiens deux erreurs à la compilation, portant sur une "erreur de syntaxe" avec un point virgule qui semble manquer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    1>Compilation en cours...
    1>svmclassifier.cpp
    1>c:\program files\microsoft visual studio 8\vc\include\dos.h(34) : error C2144: erreur de syntaxe*: 'int' doit être précédé de ';'
    1>coefsScaleSVM.cpp
    1>e:\svm\svmclassifier\src\coefsscalesvm.cpp(10) : error C2144: erreur de syntaxe*: 'void' doit être précédé de ';'
    La première erreur renvoie sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #ifdef  __cplusplus
    extern "C" { // ICI
    #endif
    dans le fichier dos.h
    (à noter que dans mon fichier principal svmclassifier.cpp, j'ai les lignes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifdef _WIN32
    #include <dos.h>
    #include <conio.h>
    #endif
    )

    Le deuxième erreur renvoie sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <vector>
    #include <cfloat>
    #include "svm.h"
    #include "coefsScaleSVM.h"
     
    /**
    * Calcule les coefficients de mise à l'échelle des données
    * et mise à l'échelle des données d'apprentissage
    */
    //double* init_scale(svm_node** X, int Nrow, int Ncol, double Na, double Nb)
    void init_scale(svm_node** X, std::vector<double> &vect_, int Nrow, int Ncol, double Na, double Nb) // ICI
    {
    ...
    dans coefsScaleSVM.cpp.

    Dans les deux cas, je ne vois même pas le rapport avec le message d'erreur...
    Je peux avoir encore un peu d'aide, s'il vous plaît ?...

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Il doit te manquer un include pour un type (qui n'est pas void, là c'est visual qui a un peu du mal).

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 31
    Points : 26
    Points
    26
    Par défaut
    Re-bonjour,
    J'ai demandé à un collègue de venir voir et en fait, il me manquait un point virgule après la définition de ma deuxième fonction (scale), dans le coefScaleSVM.h.





    Merci pour ton aide 3DArchi, mon code ressemble beaucoup plus à quelque chose de propre maintenant et ça m'a remis quelques idées en place en programmation C++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JpGraph] Erreur avec le tableau dans une fonction
    Par gtraxx dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 12/01/2009, 22h01
  2. Connaître le nom d'un tableau passé à une fonction
    Par amundsen dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 28/12/2008, 22h35
  3. problème avec un tableau passé en paramètre
    Par curley dans le forum Débuter
    Réponses: 1
    Dernier message: 28/10/2007, 03h54
  4. Problème de compilation avec Dev-C++
    Par Rouliann dans le forum Dev-C++
    Réponses: 14
    Dernier message: 14/06/2004, 19h44
  5. Réponses: 1
    Dernier message: 29/10/2003, 13h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo