nieuzasadniony error o braku deklaracji zmiennych i enumów w funkcji

0

wiecie z jakiego powodu kompilator może zgłaszać errory o braku deklaracji dla zmiennych i enumów w funkcji, skoro deklaracje są (w main) i przed wywołaniem funkcji? jak ten error naprawić?

2

POKAŻ KOD

0

wiecie z jakiego powodu kompilator może zgłaszać errory o braku deklaracji dla zmiennych i enumów w funkcji, skoro deklaracje są (w main) i przed wywołaniem funkcji? jak ten error naprawić?

Czytając ten fragment, nawet bez kodu powiem ci tak: powodem jest brak deklaracji zmiennych i enumów!
Załóż, że kompilator jest mądrzejszy od ciebie, i rzucany błąd nie jest nieuzasadniony. Zastanów się nad tym.

Poza tym, zmienne zadeklarowane w main nie są w magiczny sposób zadeklarowane na zawsze i wszędzie w każdym miejscu programu. Musisz je przekazać do funkcji.

0
int KolejnyAkt(string NazwaAktu, char Sciezka)
{
    cout << "---------------------------------------------------" << endl;           
    cout << NazwaAktu << " - ";
    
    if (Sciezka == 'p') cout << Przyborow.strCaloscNazwy << endl;
    else if (Sciezka == 's') cout << Slonsk.strCaloscNazwy << endl;
    
    cout << "---------------------------------------------------" << endl;
    cout << "Imie i nazwisko bohatera: " << Gracz.strImie << " " << Gracz.strNazwisko << endl;
    cout << "Przydomek bohatera: " << Gracz.strPrzydomek << endl;
    cout << "Gra po stronie: ";
    
    if (Sciezka == 'p') cout << "Ksiestwa Przyborowskiego" << endl;
    else if (Sciezka == 's') cout << "Imperium Slonska" << endl;
    
    cout << "Punkty zycia: " << Gracz.nZycie << endl;
    cout << "Stan zdrowia: ";
       
    if (Gracz.nZycie = 100) cout << "Wysmienity" << endl;
    else if (Gracz.nZycie > 90 && Gracz.nZycie < 100) cout << "Bardzo dobry" << endl;
    else if (Gracz.nZycie > 60 && Gracz.nZycie < 90) cout << "Dobry" << endl;
    else if (Gracz.nZycie > 45 && Gracz.nZycie < 60) cout << "Przecietny" << endl;
    else if (Gracz.nZycie > 30 && Gracz.nZycie < 45) cout << "Zly" << endl;
    else if (Gracz.nZycie > 15 && Gracz.nZycie < 30) cout << "Bardzo zly" << endl;
    else if (Gracz.nZycie > 5 && Gracz.nZycie < 15) cout << "Tragiczny" << endl;
    else if (Gracz.nZycie <= 5) cout << "Na lozu smierci" << endl;
    
    cout << "Reputacja w ";
    
    if (Sciezka == 's') cout << "Imperium";
    else if (Sciezka == 'p') cout << "Ksiestwie Przyborowskim";
    
    cout << ": ";
    if (Gracz.repReputacja == REP_OBCY) cout << "obcy" << endl;
    if (Gracz.repReputacja == REP_ZNANA_TWARZ) cout << "znana twarz" << endl;
    if (Gracz.repReputacja == REP_MIEJSCOWY) cout << "miejscowy" << endl;
    if (Gracz.repReputacja == REP_ZOLNIERZ) cout << "zolnierz" << endl;
    if (Gracz.repReputacja == REP_DORADCA) cout << "doradca" << endl;
    if (Gracz.repReputacja == REP_GENERAL) cout << "general" << endl;
    if (Gracz.repReputacja == REP_OFICER) cout << "oficer" << endl;
    if (Gracz.repReputacja == REP_SZLACHCIC) cout << "szlachcic" << endl;
    if (Gracz.repReputacja == REP_WLADCA) cout << "wladca" << endl;
    
    cout << "---------------------------------------------------" << endl;
}

int main()
{
    // bardzo ważne enum'y
    enum NASTAWIENIE_DO_GRACZA { NDG_PRZYJAZNE, NDG_WROGIE, NDG_NEUTRALNE };
    enum REPUTACJA { RG_OBCY, RG_ZNANA_TWARZ, RG_MIEJSCOWY, RG_ZOLNIERZ, RG_SZLACHCIC, RG_DORADCA, RG_GENERAL, RG_OFICER, RG_WLADCA };
    enum OBYWATELSTWO { OB_PRZYBOROW, OB_SLONSK, OB_KOSTRZYN, OB_FRANKFURT, OB_OWNICE, OB_KRZESZYCE };
    enum STAN_FIZYCZNY { STF_ZYWY, STF_MARTWY, STF_CHORY };
    enum RELACJE_MIEDZYNARODOWE { REL_WOJNA, REL_POKOJ, REL_ZAWIESZENIE_BRONI };
    
    // bardzo ważne klasy definiujące postacie w grze
    struct cPOSTAC {
          string strImie, strNazwisko, strPrzydomek;
          
          NASTAWIENIE_DO_GRACZA ndgNastawienie;
          REPUTACJA repReputacja;
          OBYWATELSTWO obObywatelstwo;
          STAN_FIZYCZNY stfStan;
          
          unsigned int nZycie;
    };
    
    struct cPANSTWO {
           string strNazwa, strTytul, strCaloscNazwy;
           
           RELACJE_MIEDZYNARODOWE relRelacje;
           
           unsigned int nMieszkancy, nSurowce;
           int nZloto;
    };
    
    struct cREGION {
           string strNazwa;
           
           OBYWATELSTWO obRegionNalezyDo;
    };
    
    // Przypisanie elementom rozgrywki ze struktur odpowiednich wartości DOMYŚLNYCH NA POCZĄTKU
    // UWAGA! Wartości będą zmieniać się w trakcie rozgrywki
    
/* tutaj byłoby te przypisanie wartości, tyle że dość długie jest i nie wiem czy zamieszczać, NA PRZYKŁAD...
    Slonsk.strNazwa = "Slonsk";
    Slonsk.strTytul = "Imperium";
    Slonsk.strCaloscNazwy = "Imperium Slonskie";
    Slonsk.relRelacje = REL_POKOJ;
    Slonsk.nMieszkancy = 1455;
    Slonsk.nSurowce = 52000;
    Slonsk.nZloto = 12000000; */
    
    // Wstep do opowiesci
    cout << "---------------------------------------------------" << endl;
    cout << " ROZMOWA..." << endl;
    
    Gracz.nZycie = 10;
    Gracz.stfStan = STF_CHORY;
    
    cout << "ROZMOWA... " << endl;
    
    cout << "" << endl << endl;
    // Wybór stronnictwa, decyduje o całej fabule i epilogu
    string WyborStronnictwa;
    cout << "[Za ktora strona chcesz sie opowiedziec? - DECYZJA NA CALA GRE!]" << endl;
    cout << "Przyborow | Slonsk" << endl;
    do {
        cin >> WyborStronnictwa;
    } while (WyborStronnictwa != "Przyborow" && WyborStronnictwa != "Slonsk");
    
    if (WyborStronnictwa == "Przyborow") {
                         /* Gra po stronie Przyborowa */ 
                         Gracz.obObywatelstwo = OB_PRZYBOROW; 
                         cout << "- Pojde z wami, do Przyborowa." << endl;
    }
    else {
         /* Gra po stronie Słońska */
         Gracz.obObywatelstwo = OB_SLONSK;
         cout << "- Chodzmy do Slonska, zolnierze." << endl;
    }
    
    Dalej();
    
    /* SCIEŻKA PRZYBOROWA                                PROLOG
    -----------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------
    */
    
    KolejnyAkt("PROLOG", 'p');
    
    if (Gracz.obObywatelstwo == OB_PRZYBOROW)
    {
       
       Dalej();
        
    }
     // w tworzeniu

    getch();
    return 0;
}
0

Error jest uzasadniony. Nie masz enumów REP_* (masz za to RG_* ale one i tak nie będą widoczne w funkcji).
Może zastanów się czy nie byłoby... rozsądniejsze wyjęcie deklaracji enumów poza main(). Pomyśl też o zastosowaniu klas zamiast struktur.

0

dziękuję za pomoc.
[quote]ogólnie bajzel w tym kodzie jest[/quote]
wiem, muszę się wreszcie nauczyć rozkładać go na pojedyncze pliki .h i .cpp a nie wszytko w jednym...

0

Kiedy zaczynałem z C też podchodziłem do dzielenia kodu na pliki jak do jeża, ale potem przekonałem się, że nie ma w tym nic magicznego, ani trudnego. Zasada jest bardzo prosta: rozrzucasz kod na pliki .c/.cpp, tworzysz do nich pliki .h z deklaracjami, a w plikach źródłowych które korzystają z obiektów w innych plikach includujesz odpowiedni plik nagłówkowy (.h). To jest cała filozofia.
Przykładowo w Twoim kodzie zrobiłbym tak (zakładając, że nadal chcesz to robić na strukturach, a nie klasach):

  1. w pliku country.h umieściłbym strukturę przechowującą dane państwa oraz deklaracje funkcji na niej operujących, zaś w pliku coutry.cpp kod tych funkcji,
  2. analogicznie dla regionu stworzyłbym plik region.h oraz region.cpp,
  3. analogicznie dla gracza - player.h i player.cpp.

Nie wiem jak chcesz zorganizować akty (i co właściwie one robią), ale można pomyśleć o wydzieleniu także ich.
W ten sposób struktury i funkcje operujące na graczu (np. funkcja zwracająca const char* opisujący stan zdrowia gracza) będą zgrupowane w jednym miejscu, ale będzie można ich używać w kilku.

Budowanie np. krajów można umieścić w pliku country.cpp lub w oddzielnym, jednakże to aż się prosi o wczytywanie danych z zewnątrz. Hardkodowanie takich rzeczy jest zabawne (do pewnego momentu), ale uciążliwe w utrzymaniu i generuje mnóstwo redundantnego kodu. Pomyśl co będzie kiedy zdefiniujesz sobie np. 300 krajów, a w trakcie rozwoju postanowisz dodać jakiś nowy element do struktury... ponad 300 zmian w kodzie potrafi zniechęcić nawet najwytrwalszych (chociaż przy użyciu odpowiednich narzędzi można ten ból zmniejszyć).

0

ciekawe rady, jestem bardzo wdzięczny.
próbowałem takie pliki stworzyć jednak ciągle mam błędy z niewykrywaniem przez kompilator ich deklaracji. trzeba używac externu?

0

przepraszam że tak was nękam ale umieszczając w country.cpp danych do struktur musze je wziasc pod main'a, a includujac plik w glownym pliku spowoduje wystapienie dwoch main'ów!

0

Nie, nie, nie... nie.
Funkcja main() może być tylko jedna. Nie twórz jej innych plikach. Przykład:

Plik country.h:

struct country { ... };

int  country_blah(struct country  *cn);
const char *country_foo(struct country  *cn, int  bar);

Plik country.cpp:

#include "country.h"

int country_blah(struct country  *cn) { ... }

const char *country_foo(struct country  *cn, int  bar) { ... }

Plik game.cpp:

#include "country.h"

int main(void)
{
	struct country	country_foobaria;
	int		blah;

	// ...
	blah = country_blah(&country_foobaria);

	// ...
	printf("Foo in %s is %s\n", country_foobaria.name, country_foo(&country_foobaria, 666));

	// ...
}

Potem kompilujesz to tak (przykład dla g++, sprawdź w dokumentacji jak wywoływać Twój kompilator):
g++ -o game country.cpp game.cpp

Albo zgodnie ze sztuką:

g++ -o country.o -c country.cpp
g++ -o game.o -c game.cpp
g++ -o game country.o game.o
0

ale czemu do game.cpp nie można przypisać np. country.cpp?
jak wartości tam dodane będą uwzględnione w game?

0
von_ilnicki napisał(a)

ale czemu do game.cpp nie można przypisać np. country.cpp?

W jakim sensie "przypisać"?

von_ilnicki napisał(a)

jak wartości tam dodane będą uwzględnione w game?

Zmieniasz wartości w strukturach, które poprzez wskaźnik (lub referencję) przekazujesz do różnych funkcji. Jeśli nie wiesz co to są wskaźniki/referencje i/lub nie wiesz jak ich używać, to musisz o nich poczytać, bo bez tego w C i C++ można tworzyć tylko proste programy.
W skrócie, dane do funkcji przekazujesz poprzez wartość lub wskaźnik (w C++ możesz też uzyć referencji, które są takimi zubożonymi wskaźnikami). Kiedy przekazujesz przez wartość (np. strukturę) funkcja działa na jej kopii i wszelkie zmiany jakie w niej wprowadzi będą widoczne tylko w obrębie tej funkcji. Wskaźnik natomiast mówi funkcji "wykonaj obliczenia na obiekcie, który znajduje się pod tym adresem w pamięci", zatem funkcja działa bezpośrednio na obiekcie i wszelkie zmiany zachodzą od razu w nim. Po zakończeniu działania funkcji zmiany są też widoczne poza nią.

Przykład:

/* Przekazanie przez wartość */
void add_one_byval(int  val)
{
	val += 1;
	/* w tym miejscu val ma wartość 2, ale po wyjściu z funkcji val jest niszczone wraz z zawartością */
}

/* Przekazanie przez wskaźnik */
void add_one_byptr(int  *val)
{
	*val += 1;
	/* w tym miejscu val wskazuje na wartość 2; po wyjściu z funkcji val jest niszczone */
}


int main(void)
{
	int	foo;

	foo = 1;
	add_one_byval(foo);
	/* w tym miejscu foo nie zmieniła wartości */

	add_one_byptr(&foo);
	/* w tym miejscu foo ma wartość 2 */

	/* ... */
}

Tak samo robisz ze strukturami, np:

struct foo_s {
	int   val;
};


void add_one_byptr(struct foo_s  *s)
{
	s->val += 1;
}


int main(void)
{
	struct foo_s	foo;

	foo.val = 1;
	add_one_byptr(&foo);
	/* w tym miejscu foo.val ma wartość 2 */

	/* ... */
}

Poczytaj o wskaźnikach i referencjach. Z tymi pierwszymi trzeba postępować roztropnie, gdyż nieumiejętne użycie może prowadzić do trudnych do zlokalizowania błędów.

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