[C++] Błąd kompilacji


(501) #1

Witam wszystkich, dopiero wczoraj zacząłem się uczyć języka C++, więc proszę o wyrozumiałość.

Mam problem z kompilacją mojego dzisiejszego "eksperymentu", oto kod źródłowy:

#include 

#include 


int main()

{

    int liczba1 = rand() %11;

    int liczba2;


    std::cout << "Wylosowa³em liczbê z zakresu 0-10." << std::endl;

    std::cout << "Zgadnij jaka to liczba... " << std::endl;

    std::cin >> liczba2;


int check()

{

    if (liczba2 == liczba1)

    {

        system ("cls");

        std::cout << "Brawo! Zgad³eœ, to " << liczba1 << "." << std::endl;

        getchar();

        liczba1 = rand() %11;

        system ("cls");

        std::cout << "Zagrajmy jeszcze raz... " << std::endl;

        std::cin >> liczba2;

        return check();

    }

    else

    {

        if (liczba2 > liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest wiêksza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }

        if (liczba2 < liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest mniejsza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }


    }

}

}

A oto błędy (dotyczą 13 linijki):

error: expected primary-expression before "int"

error: expected `;' before "int"

Aha, prawie bym zapomniał: używam Code::Blocks 10.5 z domyślnym kompilatorem.

Proszę o wytłumaczenie mi mojego błędu, poprawienie mnie i nie odsyłania do wujka google. :smiley:

Z góry dziękuję. :slight_smile:


(cropas) #2

int main()

{

int liczba1 = rand() %11;

int liczba2;

std::cout << "Wylosowa³em liczbê z zakresu 0-10." << std::endl;

std::cout << "Zgadnij jaka to liczba... " << std::endl;

std::cin >> liczba2;

} //brak konca funkcji main

i chyba na koncu jest o jedna klamre za duzo. wyglada jakby funcja byla w funkcji main


(Sawyer47) #3

1) Nagłówki w bibliotece standardowej C++ nie mają na końcu nazwy rozszerzenia, więc załączaj

2) Funkcja rand() znajduje się w nagłówku cstdlib, więc powinieneś go załąćzyć

3) C++ nie pozwala na zagnieżdżanie definicji funkcji, stąd błąd (taki kod dla zabawy to możesz cały w main dać)

4) Masz świadomość, że wywoływanie komend za pomocą funkcji system jest nieprzenośne?


(Xeon Bloomfield) #4
#include 

#include 


int check();


int main()

{

    int liczba1 = rand() %11;

    int liczba2;


    std::cout << "Wylosowa³em liczbê z zakresu 0-10." << std::endl;

    std::cout << "Zgadnij jaka to liczba... " << std::endl;

    std::cin >> liczba2;

    check();

    return 0;

}


int check()

{

    if (liczba2 == liczba1)

    {

        system ("cls");

        std::cout << "Brawo! Zgad³eœ, to " << liczba1 << "." << std::endl;

        getchar();

        liczba1 = rand() %11;

        system ("cls");

        std::cout << "Zagrajmy jeszcze raz... " << std::endl;

        std::cin >> liczba2;

        return check();

    }

    else

    {

        if (liczba2 > liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest wiêksza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }

        if (liczba2 < liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest mniejsza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }

    }

}

Ten kod zadziała.


(Darkvifon) #5

Nie zadziała. liczba1 i liczba2 nie istnieją wewnątrz funkcji check. Trzeba by przekazać je jako argumenty.


(Xeon Bloomfield) #6

Nie popatrzyłem głębiej w kod.

#include 

#include 


int liczba1;

int liczba2;


int check();




int main()

{

    liczba1 = rand() %11;


    std::cout << "Wylosowa³em liczbê z zakresu 0-10." << std::endl;

    std::cout << "Zgadnij jaka to liczba... " << std::endl;

    std::cin >> liczba2;

    check();

    return 0;

}


int check()

{

    if (liczba2 == liczba1)

    {

        system ("cls");

        std::cout << "Brawo! Zgad³eœ, to " << liczba1 << "." << std::endl;

        getchar();

        liczba1 = rand() %11;

        system ("cls");

        std::cout << "Zagrajmy jeszcze raz... " << std::endl;

        std::cin >> liczba2;

        return check();

    }

    else

    {

        if (liczba2 > liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest wiêksza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }

        if (liczba2 < liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest mniejsza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

            return check();

        }

    }

}

Ten zadziała.


(Sawyer47) #7

1) Nie powinien dać się skompilować w takiej postaci (patrz wyżej)

2) Nie ma to jak prezentować początkującemu dobre nawyki takie jak nadużywanie zmiennych globalnych...

Jeszcze do autora wątku: warto kompilować kod z możliwie najwyższym poziomem ostrzeżeń.


(Xeon Bloomfield) #8
#include 

#include 

#include 


int liczba1;

int liczba2;


void check();




int main()

{

    liczba1 = rand() %11;


    std::cout << "Wylosowa³em liczbê z zakresu 0-10." << std::endl;

    std::cout << "Zgadnij jaka to liczba... " << std::endl;

    std::cin >> liczba2;

    check();

    return 0;

}


void check()

{

    if (liczba2 == liczba1)

    {

        system ("cls");

        std::cout << "Brawo! Zgad³eœ, to " << liczba1 << "." << std::endl;

        getchar();

        liczba1 = rand() %11;

        system ("cls");

        std::cout << "Zagrajmy jeszcze raz... " << std::endl;

        std::cin >> liczba2;

    }

    else

    {

        if (liczba2 > liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest wiêksza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

        }

        if (liczba2 < liczba1)

        {

            system ("cls");

            std::cout << "Moja liczba jest mniejsza." << std::endl;

            std::cout << "Spróbuj jeszcze raz... " << std::endl;

            std::cin >> liczba2;

        }

    }

}

Kod poprawiony i przetestowany - działa.


(501) #9

Dzięki wszystkim.

Kod da się skompilować, tylko że później nie działa do końca tak jak miał, ale tym już sam muszę się zająć. :wink:

Mam jeszcze dwa pytania.

1.Co to oznacza:

void check();

2.Dlaczego nie powinno się nadużywać zmiennych globalnych, czym je można zastąpić?


(Xeon Bloomfield) #10
  1. Deklaracja, że taka funkcja istnieje, ponieważ plik z kodem jest czytany od góry do dołu - funkcja może być wywołana w innej funkcji wyżej...

  2. Zmiennymi lokalnymi...


(Sawyer47) #11

Deklaracja funkcji. Daje znać kompilatorowi, że kiedy napotka coś o nazwie check to jest to funkcja, która zwraca to a to i przyjmuje takie a takie parametry - dzięki temu kompilator może zweryfikować poprawność wywołania funkcji jeszcze przed poznaniem jej ciała. (innymi słowy: można wywołać funkcję przed jej definicją - ale najpierw trzeba ją przynajmniej zadeklarować)

Zły nawyk, w większości przypadków nie powinno się używać (wyjątki w C++ to np. właśnie std::cout i std::cin). Zmienne globalne mają zasięg - omen nomen - globalny. Jeśli powiedzmy po paru tygodniach od napisania kodu będziesz chciał napisać funkcję czy inną zmienną o tej samej nazwie zupełnie gdzie indziej, możesz dostać błąd kompilacji w związku z konfliktem nazw, albo jeszcze gorzej, kod będzie się kompilował, ale działał zupełnie inaczej niż było zamierzone. Funkcje nie powinny sięgać do zmiennych globalnych - od tego są parametry funkcji, żeby zmienną przekazać. No i nad kodem ze zbyt dużą liczbą zmiennych globalnych trudno zapanować.

Jeszcze co do kodu: jeśli chcesz powtarzać, zamiast rekurencji tutaj o wiele lepiej nada się pętla do..while.


(501) #12

Zrozumiałem, dzięki.


(Ryan) #13

Nie demonizujmy zmiennych globalnych. Póki żadna nie jest klasą, a program nie jest wielowątkowy, powinno być ok. ;]