Bład undeclared (first use this function)

0

Mam nastepujacy program:

#include <iostream>
using namespace std ;


// zbiór symboli
enum symbol {liczba, plus, minus, lnaw, pnaw, koniec};
char ch = ' '; // ostatni przeczytany znak
int lz = 0; // licznik znaków
char *wyr; // łańcuch znaków z wyrażeniem
symbol sym; // ostatni przeczytany symbol
int wart_liczby; // wartość ostatniej przeczytanej liczby
int wart_wyrazenia; // wartość wyrażenia

// Funkcje związane z analizą leksykalną
// Zamiana znaku na symbol
symbol zamien(char ch)
{
       switch (ch)
       {
              case '+' : return plus;
              case '-' : return minus;
              case '(' : return lnaw;
              case ')' : return pnaw;
              case NULL: return koniec;
       }
}

// Umieszcza następny znak w ch, zwiększa lz
void pob_znak()
{
       ch = wyr[lz++];
}

// Oblicza wartość liczby naturalnej
void liczba_naturalna()
{
       sym = liczba;
       wart_liczby = int(ch) - int('0');
       pob_znak();
       while (isdigit(ch))
       {
             wart_liczby = wart_liczby * 10 + int(ch) - int('0');
             pob_znak();
       };
}

void pob_symbol()
{
     // pomin wszystkie spacje
     while (ch != '\n' && isspace(ch)) pob_znak();
     if (isdigit(ch))
        liczba_naturalna();
     else
     {
         sym = zamien(ch);
         pob_znak();
     }
}

// Funkcje związane z analizą składni
void blad(int b)
{
     cout << wyr << endl;
     switch (b)
     { 
            case 1: cout.width(lz); cout << "^"
            << "nieoczekiwany koniec wyrazenia" << endl; break;
            case 2: cout.width(lz-1); cout << "^"
            << "oczekiwana cyfra lub \(" << endl; break;
            case 3: cout.width(lz-1); cout << "^"
            << "oczekiwany \")\""<< endl; break;
            case 4: cout.width(lz-1); cout << "^"
            << "oczekiwany operator lub koniec wyrazenia" <<endl;
     };
     exit(0);
}

//Interpretacja wyrażeń
void wyrazenie (int&);
// deklaracja zapowiadająca; funkcja wyrażenie wywołuje funkcję
// składnik, a funkcja składnik – funkcję wyrażenie
void skladnik (int &cz)
{ 
     switch (sym)
     { 
            case liczba: cz = wart_liczby; pob_symbol(); break;
            case lnaw: pob_symbol();
            wyrazenie(cz);
            if (sym == pnaw)
            pob_symbol();
            else
            blad(3);
            break;
            default: blad(2);
     }
}

void wyrazenie (int &wyr)
{ 
     int skl1, skl2;
     symbol oper;
     skladnik(skl1);
     while (sym == plus || sym == minus)
     {
           oper = sym;
           pob_symbol();
           skladnik(skl2);
           switch (oper)
           {
                  case plus : skl1 = skl1 + skl2; break;
                  case minus: skl1 = skl1 - skl2; break;
           }
     }
     wyr = skl1;
}

void main()
{
     char w[] = "(2 + 3) - (2 + 3)";
     wyr = new char(strlen(w)+1);
     strcpy(wyr, w);
     pob_symbol();
     if (sym == koniec) blad(1);
        wyrazenie(wart_wyrazenia);
     if (sym != koniec)
        blad(4);
     else
     cout << wyr << " = " << wart_wyrazenia << endl;
     delete [] wyr;
}

Po skompilowaniu pojawia sie bledy:
20 D:\kalkulator.cpp plus' undeclared (first use this function) 21 D:\kalkulator.cpp minus' undeclared (first use this function)
118 D:\kalkulator.cpp main' must return int'
Dlaczego?

0

po 1 int maint main a nie void main
po 2 nie mozna urzywac niezadeklarowanych rzeczy {tam w enum wpisywales wartosci}
a po 3 to w ogóle mi sie to nie podoba

0

W typie enum, jeśli jawnie nie przypiszemy wartości kolejnym elementom, to automatycznie ich wartości tworzą ciąg LICZBA = 0, PLUS = 1, MINUS=2 ...

W ten sposób skompiluje się wszystko.

// zbiór symboli
enum symbol
{
    LICZBA,
    PLUS,
    MINUS,
    LNAW,
    PNAW,
    KONIEC
};

symbol zamien(char ch)
{
       switch (ch)
       {
              case '+' : return PLUS;
              case '-' : return MINUS;
              case '(' : return LNAW;
              case ')' : return PNAW;
              case NULL: return KONIEC;
       }
}

poza tym, zamiast :

case NULL: return KONIEC;

usuń to i zastąp

default: return KONIEC;

inaczej tracisz kontrolę nad wartością zwracaną przez tą funkcję.

0
Ikubrava napisał(a)

po 1 int maint main a nie void main
po 2 nie mozna urzywac niezadeklarowanych rzeczy {tam w enum wpisywales wartosci}
a po 3 to w ogóle mi sie to nie podoba

  1. void main jest uzywane np w borlandzie
  2. poczytaj jak dziala enum i ku sobie slownik ortograficzny
  3. o rety
0

;-P ale tu po prostu pokićkały się przestrzenie nazw :

#include <iostream>

namespace symbole {
enum symbol {liczba, plus, minus, lnaw, pnaw, koniec};
}

void pob_znak();
void liczba_naturalna();
void wyrazenie (int &wyr);
void blad(int b);



char ch = ' '; // ostatni przeczytany znak
int lz = 0; // licznik znaków
char *wyr; // łańcuch znaków z wyrażeniem
symbole::symbol sym; // ostatni przeczytany symbol
int wart_liczby; // wartość ostatniej przeczytanej liczby
int wart_wyrazenia; // wartość wyrażenia

// Funkcje związane z analizą leksykalną
// Zamiana znaku na symbol
symbole::symbol zamien(char ch)
{
        
       switch (ch)
       {
              case '+' : return symbole::plus ;
              case '-' : return symbole::minus;
              case '(' : return symbole::lnaw;
              case ')' : return symbole::pnaw;
              case NULL: return symbole::koniec;
       }
}


void pob_symbol()
{
     // pomin wszystkie spacje
     while (ch != '\n' && isspace(ch)) pob_znak();
     if (isdigit(ch))
        liczba_naturalna();
     else
     {
         sym = zamien(ch);
         pob_znak();
     }
}

// składnik, a funkcja składnik – funkcję wyrażenie

void skladnik (int &cz)
{
     switch (sym)
     {
            case symbole::liczba: cz = wart_liczby; pob_symbol(); break;
            case symbole::lnaw: pob_symbol();
            wyrazenie(cz);
            if (sym == symbole::pnaw)
            pob_symbol();
            else
            blad(3);
            break;
            default: blad(2);
     }
}
void wyrazenie (int &wyr)
{
     int skl1, skl2;
     symbole::symbol oper;
     skladnik(skl1);
     while (sym == symbole::plus || sym == symbole::minus)
     {
           oper = sym;
           pob_symbol();
           skladnik(skl2);
           switch (oper)
           {
                  case symbole::plus : skl1 = skl1 + skl2; break;
                  case symbole::minus: skl1 = skl1 - skl2; break;
           }
     }
     wyr = skl1;
}

using namespace std ;
// Umieszcza następny znak w ch, zwiększa lz
void pob_znak()
{
       ch = wyr[lz++];
}

// Oblicza wartość liczby naturalnej
void liczba_naturalna()
{
       sym = symbole::liczba;
       wart_liczby = int(ch) - int('0');
       pob_znak();
       while (isdigit(ch))
       {
             wart_liczby = wart_liczby * 10 + int(ch) - int('0');
             pob_znak();
       };
}



// Funkcje związane z analizą składni
void blad(int b)
{
     cout << wyr << endl;
     switch (b)
     {
            case 1: cout.width(lz); cout << "^"
            << "nieoczekiwany koniec wyrazenia" << endl; break;
            case 2: cout.width(lz-1); cout << "^"
            << "oczekiwana cyfra lub \(" << endl; break;
            case 3: cout.width(lz-1); cout << "^"
            << "oczekiwany \")\""<< endl; break;
            case 4: cout.width(lz-1); cout << "^"
            << "oczekiwany operator lub koniec wyrazenia" <<endl;
     };
     exit(0);
}




int main()
{
     char w[] = "(2 + 8) - (2 + 3)";
     wyr = new char(strlen(w)+1);
     strcpy(wyr,w);
     pob_symbol();
     if (sym == symbole::koniec) blad(1);
        wyrazenie(wart_wyrazenia);
     if (sym != symbole::koniec)
        blad(4);
     else
     cout << wyr << " = " << wart_wyrazenia << endl;
     delete [] wyr;
     system("Pause");
    return 0;

}

0
khadgar napisał(a)
  1. void main jest uzywane np w borlandzie

Ta? Szczególnie, że z punktu widzenia standardu języka jest to konstrukcja zabroniona? Jeżeli kompilator coś takiego dopuszcza to tylko dla jaj.

1 użytkowników online, w tym zalogowanych: 0, gości: 1