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 :

Variables non-déclarées qui le sont déjà


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2011
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Variables non-déclarées qui le sont déjà
    Bonjour,

    Nouveau au C++ depuis deux mois, un travail d'école requiert un prog qui calcule les jeux d'impressions d'une imprimerie. La compilation se fait sans problème mais lors de l'éxécution, je reçois plusieurs erreurs de variables utilisées non-initialisées. L'entête du programme est comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <conio.h>
    #include <cctype>
    #include "c:\\cvm.h"
     
    using namespace std;
     
    void main (void)
     
    {
    	//déclaration des variables
    	char FormatPapier, TypeImpression, TypePapier, Aperforer, TypeFaconnage;
    	int NbOri, NbExe, NbImpR, NbImpRV, Reste;
    	float CoutR, CoutRV, CoutPapier, CoutFaconnage, CoutProduction, CoutTotal, CoutTPS, CoutTVQ;
    	const float Prix8x11R=31, Prix8x11RV=60, Prix11x17R=61, Prix11x17RV=100,
    			PrixPapier1=20.50, PrixPapier2=67.34, PrixPapier3=122.94,
    			PrixBroche=0.03, PrixEncoller=0.6, PrixTable=0.35, PrixDosCheval=0.10, PrixPerforer=3,
    			TPS=0.05, TVQ=0.075;
    L'usage initial des variables NbImpR et NbImpRV :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    if (TypeImpression == 'R')
    	{
    		if (TypePapier == '1' || TypePapier == '2')
    		{
    			NbImpR = NbOri*NbExe;
    			NbImpRV = 0;
    		}
    		else if (TypePapier == '3')
    		{
    			Reste = NbOri % 2;
    			if (Reste = 0)
    				NbOri=NbOri+1;
    			else if (Reste != 0) 
    			{
    				NbOri = NbOri+1;
    				NbImpR = (NbOri*NbExe) / 2;
    				NbImpRV = 0;
    			}
    		}
    	}
    	else if (TypeImpression == 'V')
    	{
    		if (TypePapier == '1' || TypePapier == '2')
    		{
    			Reste = NbOri % 2;
    			if (Reste != 0)
    			{
    				NbImpR=NbExe;
    				NbImpRV= ((NbOri-1)*NbExe) / 2;
    			}
    			else if (Reste = 0)
    			{
    				NbImpR=0;
    				NbImpRV= (NbOri*NbExe) / 2;
    			}
    		}
    		else if (TypePapier == '3')
    		{
    			Reste = NbOri % 4;
    			if (Reste == 0)
    				NbImpRV= (NbOri*NbExe) / 4;
    			if (Reste == 1 || Reste == 2)
    			{
    				NbImpRV=NbExe;
    				NbImpRV= ((NbOri-Reste) *NbExe) /4;
    			}
    			if (Reste==3)
    				NbImpR = 0;
    				NbImpRV = ((NbOri+1)*NbExe) / 4;
    		}
    	}
    Le début des erreurs commence ici avec NbImpR et NbImpRV:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if ((NbImpR + NbImpRV) / NbExe == 1)
    	{
    		cout << "\nVoulez-vous des documents perfor\x82s ? (O/N)";
    		cin >> Aperforer;
    	}
    	else if ((NbImpR+NbImpRV)/NbExe != 1)
    	{
    		cout << "\nVoulez-vous des documents perfor\x82s ? (O/N)";
    		cin >> Aperforer;
    	}
    il y a d'autres cas du même genre plus bas dans le programme mais la tendance se maintient; il semble que lors d'un nouveau if-else, les valeurs assignées aux variables auparavant ne suivent pas (si je comprend bien). Avec le faible bagage de connaissances que nous possèdons à ce moment (if, else, switch), je vois mal comment y remédier.

    Je ne veux pas alourdir le message en affichant tout le code dès le début (260+ lignes) mais je peux si vous croyez cela utile.

    Merci pour tout commentaire ou suggestion.

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je suis assez d'accord avec ton compilateur : Par exemple, si TypeImpression vaut R et TypePapier vaut 3 et Reste vaut 0 (cf plus bas), on n'a alors initialisé ni NbImpR ni NbImpRV.

    Autre problème : if (Reste = 0) : On affecte la valeur 0 à Reste, puis on teste si cette valeur est non nulle. Pour comparer Reste et 0, écrire : if (Reste == 0)
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je suis assez d'accord avec ton compilateur : Par exemple, si TypeImpression vaut R et TypePapier vaut 3 et Reste vaut 0 (cf plus bas), on n'a alors initialisé ni NbImpR ni NbImpRV.

    Autre problème : if (Reste = 0) : On affecte la valeur 0 à Reste, puis on teste si cette valeur est non nulle. Pour comparer Reste et 0, écrire : if (Reste == 0)
    Ou if (!Reste), ce qui est plus idiomatique et moins error-prone. Ou if (0 == Reste), ce qui détecte tout seul l'erreur dans le cas où un = a été oublié (c'est généralement ce qui est conseillé à ceux qui n'ont pas une grande pratique du C ou du C++).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    576
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 576
    Points : 1 528
    Points
    1 528
    Par défaut
    Personnellement je ne suis pas partisan du if(!reste). "reste" est un entier, les entiers représentent des quantités et non des prédicats. Ce n'est pas strictement le même type d'objet.
    Attribuer à 0 la valeur false n'est pas une très bonne idée car d'un point de vue purement algébrique "0" peut être beaucoup plus compliqué que le simple 0 entier (neutre d'un groupe additif).

    @Marin Échoué, tu peux aussi simplifier tes tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if ( reste == 0){
     ...
    }
    else if (reste != 0 ) {
    ...
    }
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if ( reste == 0){
     ...
    }
    else {
    ...
    }
    En effet, faire un if/else if peut laisser entendre qu'il s'agit de 2 cas particuliers, et qu'il manque le cas général que l'on ne traite pas alors que faire un if/else montre que l'on traine un cas particulier et le cas général.
    La perfection est atteinte, non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retirer. - Antoine de Saint-Exupéry

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par pyros Voir le message
    Personnellement je ne suis pas partisan du if(!reste). "reste" est un entier, les entiers représentent des quantités et non des prédicats. Ce n'est pas strictement le même type d'objet.
    C'est plus ou moins vrai ; outre le fait que ça soit idiomatique, c'est aussi garanti par deux clauses de la norme C++03. L'opérateur ! est un opérateur unaire qui ne vérifie pas si le paramètre est 0, mais si la relation (paramètre == 0) est vraie (il y a une conversion vers bool implicite lorsqu'on utilise cet opérateur. cf. section 5.3.1§8 de la norme C++03, et section 4.12 de la même norme).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2011
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Corrections apportées mais...
    Rebonsoir,

    Merci de vos conseils. J'ai pû corriger certains éléments de départ mais la problématique perdure. C'est-à-dire, l'erreur de variable utilisée mais non-initialisée revient. En passant, la validation de Reste n'a pas causé de problème (bien que je l'ai probablement codé comme une brute)

    En suivant le progrès de l'éxécution, je vois bien que les variables sont créées lors de la déclaration mais je vois plus bas qu'une valeur "insensée" leur est ensuite assignée. Je crois bien comprendre qu'à moins qu'une valeur spécifique est assignée, ce qui se trouve à l'adresse en mémoire prend sa place.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	int NbOri, NbExe, NbImpR, NbImpRV, Reste;
    	float CoutR, CoutRV, CoutPapier, CoutFaconnage, CoutProduction, CoutTotal, CoutTPS, CoutTVQ;
    sont toutes déclarées au début mais "CoutR, CoutRV, CoutPapier" reviennent avec des erreurs de non-initialisation à partir d'ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CoutProduction = CoutR + CoutRV + CoutPapier + CoutFaconnage;
    CoutR, CoutRV et CoutPapier ont été traitées plus tôt dans des switch et des if comme celui-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    	//calcul du nombre d'impressions rectos et versos
    	switch (TypeImpression)
    	{
    		case 'R':
    			if (FormatPapier == '1' || FormatPapier == '2')
    			{
    				CoutR = (NbImpR /1000)*Prix8x11R;
    				CoutRV = 0;
    			}
    			else if (FormatPapier == '3')
    			{
    				CoutR = (NbImpR /1000)*Prix11x17R;
    				CoutRV = 0;
    			}
    			break;
     
    		case 'V':
    			if (FormatPapier == '1' || FormatPapier == '2')
    			{
    				CoutRV = (NbImpRV /1000)*Prix8x11RV;
    				CoutR = 0;
    			}
    			else if (FormatPapier == '3')
    			{
    				CoutRV = (NbImpRV /1000)*Prix11x17RV;
    				CoutR = 0;
    			}
    			break;
    	}
    Ce que je ne comprends pas, c'est (1) comment initialiser une variable à partir d'autres variables et (2) comment retirer la valeur d'une variable traitée dans un (if) ou un (switch) pour la manipuler plus tard dans le programme.

    Désolé si je ne suis pas clair lors de mes explications. Merci encore pour vos suggestions.

  7. #7
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bonjour.

    Citation Envoyé par Marin Échoué Voir le message
    Ce que je ne comprends pas, c'est (1) comment initialiser une variable à partir d'autres variables.
    Euh, bah comme tu initialiserais une variable autrement...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    un_type une_variable = ...; // Initialisation de la première variable
    (...)
    un_type_lie une_autre_variable = une_variable; // BINGO !
     
    //////////////////////////////////////
     
    un_type une_variable;
    un_type_lie une_autre_variable;
    (...) // On définit une valeur pour une_variable, on ne touche pas à une_autre_variable
    une_autre_variable = une_variable; // BINGO !
    Bon, dans le deuxième cas, une_autre_variable n'est pas vraiment initialisée avec une autre variable, mais qu'on ne s'en sert pas entre sa déclaration et son affectation, c'est tout comme.

    Citation Envoyé par Marin Échoué Voir le message
    Ce que je ne comprends pas, c'est (2) comment retirer la valeur d'une variable traitée dans un (if) ou un (switch) pour la manipuler plus tard dans le programme.
    Euh, pas bien compris ce que tu veux.
    Si tu n'as plus besoin de la valeur d'une variable, eh bien tu ne t'en sers pas.
    Si tu veux absolument réinitialiser la variable, tu peux utiliser le constructeur par défaut, mais je ne suis pas sûr que ça a un quelconque intérêt...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    un_type une_variable;
    (...) // Utilisation de une_variable
    une_variable = un_type(); // Effacement de la valeur de la variable
    Évidemment, je donne là le cas général.
    Pour les types natifs (entier, réel, caractère, booléen, pointeur), il suffit d'affecter la valeur nulle.

    Bon courage !

Discussions similaires

  1. Réponses: 6
    Dernier message: 31/12/2008, 10h59
  2. Option Explicit et erreur variable non déclarée
    Par petitours dans le forum VBA Access
    Réponses: 2
    Dernier message: 23/04/2008, 15h38
  3. [Design] Erreur variable non déclarée ou non assignée
    Par Arnard dans le forum Visual Studio
    Réponses: 3
    Dernier message: 19/12/2007, 17h53
  4. Problème de variable non déclarée
    Par jncoffy dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 24
    Dernier message: 06/06/2007, 11h01
  5. variable non déclarée?
    Par carole8 dans le forum C
    Réponses: 15
    Dernier message: 30/11/2006, 16h13

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