Partage
  • Partager sur Facebook
  • Partager sur Twitter

identificateur introuvable C++

Sujet résolu
25 août 2016 à 19:23:44

Bonjour je suis débutant en c++ et en écrivant un morceau de code je rencontre toujours la même erreur: "identificateur introuvable"

j'utilise visual studio si ca peut vous aider

voici le code:

// learn c++.cpp : définit le point d'entrée pour l'application console.
//

#include "stdafx.h"
#include "iostream"
using namespace std;



int main()
{
	system("pause");
	double a(2), b(3);
	fonction(a, b);
	cout << "a = " << a << "et b = " << b << endl;
	
    return 0;
}



//fonctions


void fonction(double& a, double& b)
{
	double temp(a);
	a = b;
	b = temp;
	
}



  • Partager sur Facebook
  • Partager sur Twitter
25 août 2016 à 19:36:38

Lu'!

Utiliser "using namespace std" est une mauvaise pratique. Pour un certain nombre de raisons, mais elles ne te sont pas très utiles à comprendre pour le moment, il est juste plus sain de s'habituer à ne pas le faire maintenant.

Il vaut mieux, soit nommer complètement les éléments :

#include <iostream>

int main()
{
  double a(2), b(3);
  fonction(a, b);
  std::cout << "a = " << a << "et b = " << b << std::endl;
}

Soit ajouter sélectivement les noms :

#include <iostream>

using std::cout;
using std::endl;

int main()
{
  double a(2), b(3);
  fonction(a, b);
  cout << "a = " << a << "et b = " << b << endl;
}

_________________________

Utiliser les opérations "system" machin est également une mauvaise idée. Si tu veux faire une pause qui ne soit pas celle fournie par ton IDE, tu peux plutôt utiliser un code comme celui -ci : faire une pause.

_________________________

Concernant ton problème. Tu utilises ta fonction dans le code avant que ton compilateur ne puisse la connaître car elle est déclarée et définie après cet usage. Tu peux soit la définir avant la fonction :

void fonction(double& a, double& b)
{
    double temp(a);
    a = b;
    b = temp;
     
}

int main()
{
    system("pause");
    double a(2), b(3);
    fonction(a, b);
    cout << "a = " << a << "et b = " << b << endl;
     
    return 0;
}

Soit la déclarer avant en indiquant son prototype et la définir plus tard :

//déclaration
void fonction(double& a, double& b);

int main()
{
    system("pause");
    double a(2), b(3);
    fonction(a, b);
    cout << "a = " << a << "et b = " << b << endl;
     
    return 0;
}
 
//fonctions
 
//définition
void fonction(double& a, double& b)
{
    double temp(a);
    a = b;
    b = temp;
     
}
  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

25 août 2016 à 19:45:30

merci de cette reponse j'en ai plus que ce qu'il me fallait mais ce n'est pas plus mal !!

mais j'ai quand meme deux autres question.

pourquoi utiliser "using namespace std" est un mauvaise pratique ?

et pourquoi utiliser les operation "system" est une mauvaise idée ?

merci

  • Partager sur Facebook
  • Partager sur Twitter
26 août 2016 à 0:34:10

Les appels système ne sont pas portable, tu n'as aucune garantie que les commandes utilisées sur un système X soient également disponible sur un système Y (essaye d'utiliser "ls" sous Windows par exemple).
Ce qui va à l'encontre de l'une des philosophie du C++ (et du C aussi): Write once, compile everywhere.
  • Partager sur Facebook
  • Partager sur Twitter
26 août 2016 à 8:58:40

fryzegaming a écrit:

pourquoi utiliser "using namespace std" est un mauvaise pratique ?

Le C++ fournit un moyen d'organiser les noms dans un programme au travers de la notion de namespace (espace de nom), cela va être des boîtes nommées dans lesquelles les noms vont être rangés. Par exemple, si je veux créer une bibliothèque de fonctions de dessins, je pourrais avoir quelque chose comme :

namespace draw{
  void line(vertex b, vertex e);
  void curved_line(vectex b, vertex e, vertex i);
  void circle(vertex c, unsigned r);

  //etc
}

Et si je veux par la suite utiliser ces noms, je ferai comme ceci :

draw::line(v1, v2);

L'intérêt est que dans un autre namespace, tous les noms que j'ai définit dans celui-ci restent disponible. Par exemple :

namespace n1{
  void foo();
}

namespace n2{
  void foo();
}

int main(){
  n1::foo();
  n2::foo();
}

En effet, il n'est pas rare qu'un nom de fonctionnalité puisse avoir un sens différent selon de quoi on parle, ou même simplement selon comment on les a classifié. Par exemple, on peut imaginer avoir une fonction de calcul sur les matrices qui peut fonctionner en algorithme séquentiel et puis en avoir une autre version pour les processeur multi-coeur. Dans ce cas, on pourrait avoir :

namespace sequential{
  Matrix operator*(Matrix const& m1, Matrix const& m2);
}
namespace parallel{
  Matrix operator*(Matrix const& m1, Matrix const& m2);
}

Les deux opérations font la même chose mais pas de la même manière et sont donc classées dans deux espaces de noms différents.

En C++, il y a un namespace par défaut pour tous les éléments faisant partie de la bibliothèque standard C++. Ce namespace est "std". C'est là qu'on va trouver cout, endl, vector, etc. Pourquoi ne pas utiliser "using namespace std" et même très souvent "using namespace <tout nom>" ? Parce que cela va faire exploser le risque de conflit entre les noms. En effet, si tu écris par exemple :

#include <iostream>

using namespace std;

int main(){

}

Tous les noms du standard qui sont présents dans le header <iostream> sont maintenant réservés. Tu ne peux plus les utiliser. Cela peut sembler anodin parce que tu n'as que <iostream> d'inclus (et ça fait déjà un certain nombre de noms ;) ), mais il ne sera pas rare au fil de tes projets que tu aies beaucoup d'includes dans un fichier. A titre personnel, je me retrouve assez souvent avec au minimum :

#include <vector>
#include <array>
#include <functional>
#include <algorithm>
#include <cassert>
#include <memory>

Ce qui fait déjà beaucoup de noms (et c'est un minimum), donc tu peux te retrouver assez vite à blinder l'espace global de noms avec des mots dont tu pourrais avoir besoin. On peut construire un exemple un peu bêbête :

#include <iostream>

using namespace std;

int main(int argc, char** argv){
  int prix_ht = 42;
  float tva = 0.2;
  
  int cout = prix_ht * (1. + tva);
  
  cout<<cout<<endl; // ???
}

Avec une jolie erreur due à ce conflit. Erreur qui n’apparaît pas si on nomme complètement les éléments :

#include <iostream>

int main(int argc, char** argv){
  int prix_ht = 42;
  float tva = 0.2;
  
  int cout = prix_ht * (1. + tva);
  
  std::cout<<cout<<std::endl; // ???
}

Ici j'ai volontairement rendu l'erreur compréhensible en mettant "std::cout" et "cout" côte à côte. Maintenant imagine si dans ton code tu n'as pas fait ce genre d'affichage immédiatement mais que tu utilises std::cout bien plus tard avec d'autres variables. Tu vas te retrouver avec une erreur comme ça :

main.cpp: In function 'int main(int, char**)':
main.cpp:11:7: error: invalid operands of types 'int' and 'float' to binary 'operator<<'
   cout<<tva<<endl; // ???
   ~~~~^~~~~

Soit "cout est de type 'int' et tu lui donnes des paramètres qui conviennent pas". De quoi tomber chèvre.

Donc on préférera généralement nommer complètement les éléments, et si vraiment il y a un nom qu'on va utiliser partout tout le temps, on l'importera sélectivement dans l'espace global :

using std::cout;

int main(){
  cout<<"lapin";
}

Ou mieux encore, si on a identifié une fonction ou un bloc où la fonctionnalité en question va nous être très souvent utile on peut l'ajouter localement :

int main(){
  using std::cout;

  cout<<"lapin";
}

void fonction(){
  //ici std::cout doit être utilisé en toutes lettres
  std::cout<<"nain";
}

---

A la base, l'introduction de "using namespace std" en début de code a été conseillée, à la première standardisation de C++ en 1998, pour un but précis : porter facilement et rapidement du vieux code (pré-standardisation) vers du C++ standard au regard de la norme. Cela évitait d'aller modifier du code valide existant (qui avait donc été conçu sans notion de namespace standard) pour assurer le passage vers la nouvelle norme. Dans un nouveau code, il n'y a pas de raison de l'utiliser, cela ne fait que supprimer une fonctionnalité du langage qui peut nous être très utile.

-
Edité par Ksass`Peuk 30 août 2017 à 8:53:04

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

26 août 2016 à 10:45:22

merci pour toutes ces reponses
  • Partager sur Facebook
  • Partager sur Twitter
15 mai 2020 à 11:39:41

a

-
Edité par unel 15 mai 2020 à 11:40:33

  • Partager sur Facebook
  • Partager sur Twitter
15 mai 2020 à 12:38:34

Bonjour,

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter

Pas d'aide concernant le code par MP, le forum est là pour ça :)