Błąd przy komplikacji prostego kalkulatora

Witam . Mam problem z prostym programikiem . Uczę się z e-książki " Od zera do gier kodera " . Jest tam kod kalkulatora.

Niestety podczas komplikacji Dev C++ znajduje błąd przy linijce “case 2 : …” .

Oto kod "

#include

#include


using namespace std;


int main()

{

    int Opcja;

    cout<<"Wybierz dzialanie : \n 1.Dodawanie \n 2.Odejmowanie\n 3.Mnożenie \n 4.Dzielenie \n 0.Wyjdz";

    cin>>Opcja;


    int L1;

    cout<<"Dodawanie : \n";

    cin>>L1;


    int L2;

    cout<<" + ";

    cin>>L2;


    switch (Opcja)

    {

           case 1 : int Wynik = L1 + L2;

           cout<<"Wynik to "<
           cin>>Wynik; break;


           case 2 : int Wynik1 = L1 - L2;

           cout<<"Wynik to "<
           cin>>Wynik1; break;


            case 3 :int Wynik2 = L1 * L2;

           cout<<"Wynik to "<
           cin>>Wynik3;break;


            case 4 : 

                       if ( L2 == 0 )

                 {

                     cout<<"Dzielnik nie moze byc rozny zero -.-";

                     }

                     else

                     {

                     int Wynik3 = L1 / L2;

           cout<<"Wynik to "<
           cin>>Wynik3;break;

           }


            case 0 : 

                 cout<<"Kliknij dowolny klawisz aby zakonczyc " ;

                 default : cout<<"Opcja nie znana";

                 }       

getch();

}

Wie ktoś o co chodzi ?

Jeśli chcesz zadeklarować zmienne po instrukcji case, musisz je objąć zakresem({ i }).

Ale w którym miejscu mam to wstawić ?

Jak wstawiam między case 2: a int j=nadal jest błąd .

A dev c++ komplikacja zaznacza na czerwono linijkę w której wykrył błąd , po komplikacji zaznaczył mi case 2 : .

Zadeklaruj sobie zmienną na wynik wcześniej.

Jestem zielony w C++ ;\

Ale za każdym razem deklaracja na wynik zmienia się znakiem ,+ ,- ,*,\ .

Robisz tak:

case 1:

{

   int wynik = 1+2;

   break;

}

case 2:

{

   int wynik = 4 + 5;

   break;

}

Zacznijmy od tego, że kompilacji a nie komplikacji :confused:

Słuchaj, chodzi o to, że powinieneś objąć klamrami ({}) wszystkie instrukcje, jakie chcesz, aby były wykonywane po naciśnięciu 1 (case 1:). Tzn., ze jeśli napiszesz tak:

case 1 : int Wynik = L1 + L2;

To instrukcje kończą się dla case zaraz po napotkaniu średnika. Czyli zmienna Wynik jest znana tylko w zakresie case 1 :slight_smile: Dalej już nie :slight_smile: Czyli tu:

cout<<"Wynik to "<

Zmienna Wynik jest już nieznana, więc kompilator protestuje, ponieważ nie zna tej zmiennej :slight_smile: Więc jeśli chcesz, aby była ona znana w całym bloku case 1:, powinieneś umieścić wszystkie instrukcje, w których chcesz użyć tej zmiennej, i które mają być wykonane po naciśnięciu 1, pomiędzy klamrami. Przykład:

case 1 : 

{

           int Wynik = L1 + L2;

           cout<<"Wynik to "<
           cin>>Wynik; 

           break;

}

Resztę powinieneś już sam zrobić :slight_smile:

Dzięki wszystko działa tylko teraz mam następny problem .

Wszystkie obliczenie działają ale gdy naciskam 0 czyli wyjście program pyta mnie o Liczbe pierwszą i drugą

tak wygląda działający program

#include

#include

using namespace std;

int main()

{

    int Opcja;

    cout<<"Wybierz dzialanie : \n 1.Dodawanie \n 2.Odejmowanie\n 3.Mnożenie \n 4.Dzielenie \n 0.Wyjdz\n";

    cin>>Opcja;


        int L1;

    cout<<"Piodaj pierwsza liczbe\n";

    cin>>L1;


    int L2;

    cout<<"Podaj druga liczbę";


    switch (Opcja)

    {

           case 1 : 

   {

           int Wynik = L1 + L2;

           cout<<"Wynik to "<
           cin>>Wynik;

           break;

}

           case 2 : 

                {


                    int Wynik1 = L1 - L2;

           cout<<"Wynik to "<
           cin>>Wynik1; break;

           }


            case 3 :

                 {

                        int Wynik2 = L1 * L2;

           cout<<"Wynik to "<
           cin>>Wynik2; break;

           }


            case 4 :

                       if ( L2 == 0 )

                 {

                     cout<<"Dzielnik nie moze byc rozny zero -.-";

                     }

                     else

                     {

                     int Wynik3 = L1 / L2;

           cout<<"Wynik to "<
           cin>>Wynik3;break;

           }


            case 0 :

                 cout<<"Kliknij dowolny klawisz aby zakonczyc " ;

                 default : cout<<"Opcja nie znana";

                 }       

getch();

}

A tak gdy go troche zmodyfikowałem :

#include

#include

using namespace std;


int liczba1()

{

  int L1;

    cout<<"Piodaj pierwsza liczbe\n";

    cin>>L1;


    int L2;

    cout<<"Podaj druga liczbę";

}

int main()

{

    int Opcja;

    cout<<"Wybierz dzialanie : \n 1.Dodawanie \n 2.Odejmowanie\n 3.Mnożenie \n 4.Dzielenie \n 0.Wyjdz\n";

    cin>>Opcja;


    switch (Opcja)

    {

           case 1 : 

   {

           liczba1();

           int Wynik = L1 + L2;

           cout<<"Wynik to "<
           cin>>Wynik;

           break;

}

           case 2 : 

                {

                    liczba1();

                    int Wynik1 = L1 - L2;

           cout<<"Wynik to "<
           cin>>Wynik1; break;

           }


            case 3 :

                 {

                        liczba1();

                        int Wynik2 = L1 * L2;

           cout<<"Wynik to "<
           cin>>Wynik2; break;

           }


            case 4 :

                       liczba1();

                       if ( L2 == 0 )

                 {


                     cout<<"Dzielnik nie moze byc rozny zero -.-";

                     }

                     else

                     {

                     int Wynik3 = L1 / L2;

           cout<<"Wynik to "<
           cin>>Wynik3;break;

           }


            case 0 :

                 cout<<"Kliknij dowolny klawisz aby zakonczyc " ;

                 default : cout<<"Opcja nie znana";

                 }       

getch();

}

Poprostu z zadeklarowanie liczb zrobiłem osobną funkcję i dodałem do każdego case .

Ale niestety program mówi że L1 i L2 nie są zadeklarowane .

Wiem że mogę dodać deklaracje tych 2 liczb a każdym case ale wtedy kod będzie znacznie dłuższy

a powinno być raczej odwrotnie

Dawno nie widziałem czegoś takiego.

Moje uwagi:

  1. Słyszałeś o czymś takim jak formatowanie kodu? Przecież tego nie da się czytać! :expressionless: W czym Ty to piszesz? Obstawiam Dev-Cpp.

  2. Nazwy zmiennych piszemy małymi literami (np. “l1”), natomiast w nazwach funkcji każde słowo zaczynamy wielką (np. Liczba1())

  3. Nazwy funkcji powinny jasno mówić, co dana funkcja robi. Twoja “liczba1” nie mówi nic. Natomiast np. “PobierzLiczbyOdUzytkownika” wygląda zdecydowanie lepiej.

  4. Dlaczego Twoja funkcja ma zadeklarowany zwracany typ int, mimo że niczego nie zwraca? Nie sądzisz, że powinien być to typ void?

  5. Dlaczego w case’ach 1-4 masz coś takiego “cin>>Wynik;”. Czemu to ma służyć?

  6. Dlaczego w case 0 i w default nie masz brake?

  7. Ogólnie nie rozumiem koncepcji tworzenia jakichś lokalnych zmiennych w case’ach. Po co to? W tym programie wystarczą 4 zmienne zadeklarowane na początku main, do których dane będą pobierane i wyliczane w odpowiednich case’ach.

  8. Fajnie, że wpadłeś na pomysł zrobienia oddzielnej funkcji do pobierania liczb od użytkownika. Ale jeśli chcesz, aby funkcja zwróciła kilka zmiennych, to najlepiej przekazać je do niej w argumentach jako wskaźniki. Wtedy Twoja funkcja pobierająca będzie mogła pobrać liczby od użytkownika i zapisać je w zmiennych będących w funkcji main.

Teraz wreszcie zrozumiałem temat. Ty nie chcesz skompilować kodu. Ty chcesz sobie wszystko niepotrzebnie skomplikować :stuck_out_tongue:

  1. Nie nie słyszałem co to formatowanie kodu . A co ? Dev C++ jest zły ?

  2. Sorry , nie wiedziałem że w kodzie programy trzeba ortografii przestrzegać.

  3. W tak krótkim programie to chyba się nikt nie zgubi .

  4. Nie wiedziałem że w switch nie trzeba cin

5.Mówię DOPIERO SIĘ UCZĘ

6.Pkt.5

7.Powiedz mi jakie to 4 zmienne .

somekind , wiem że nie rozumiesz ale DOPIERO SIĘ UCZĘ (W regulaminie było o dużych literach i to co tam pisało to właśnie o to mi chodzi ).

Pioter233, ten ostatni kod który wrzuciłeś jasno pokazuje, że nie znasz C++ zbyt dobrze. Ok, rozumiem że dopiero się uczysz, szanuję to, ale ta funkcja liczba1 i to co prawdopodobnie chciałeś uzyskać może tylko bawić kogoś znającego C++. Zalecam więcej nauki, zdecydowanie.

Również uczulam na formatowanie kodu, czyli wszelkie zabiegi czyniące go bardziej czytelnym, przede wszystkim zwracaj uwagę na odstępy i wcięcia. I muszę zgodzić się z somekind, że temat wątku świetnie pasuje do tego co robisz z tym kodem. Zobacz jak ten kod mógłby wyglądać:

#include 

#include 


int main()

{

    int opcja;

    std::cout << "Wybierz dzialanie : \n 1.Dodawanie \n 2.Odejmowanie\n 3.Mnożenie \n 4.Dzielenie \n 0.Wyjdz\nTwój wybór: ";

    std::cin >> opcja; // zauważ - spacje między operatorami zwiększają czytelność


    if(0 == opcja)

    	return 0;


    double result = NAN;

   	double larg, rarg;


   	std::cout << "Podaj lewy argument: ";

   	std::cin >> larg;

   	std::cout << "Podaj prawy argument: ";

   	std::cin >> rarg;


   	if(4 == opcja && 0 == rarg)

   	{

   		std::cout << "Błąd: Dzielenie przez zero!\n";

   		return 1;

   	}


    switch(opcja) // zwróć uwagę na wcięcia robione Tabem - bardzo polepszają czytelność kodu

    {

    	case 1:

    		result = larg + rarg;

    		break;

    	case 2:

    		result = larg - rarg;

    		break;

    	case 3:

    		result = larg * rarg;

    		break;

    	case 4:

    		result = larg / rarg;

    		break;

    	default:

    		std::cout << "Nieznana opcja\n";		

	}


	std::cout << "Wynik to: " << result << "\n";


	return 0;

}

Jest do bani, by nie powiedzieć inaczej. Chociażby właśnie dlatego, że formatuje kod w losowy, nieprzewidywalny i najbardziej nieczytelny z możliwych sposób.

Jeśli potrzebujesz lekkiego i wygodnego IDE, to polecam CodeBlocks.

To nie ortografia, tylko konwencje. Taki jest dobry, programistyczny obyczaj. Wówczas ktoś patrząc na Twój kod łatwiej go zrozumie. Powiesz, że teraz to nie ma znaczenia - otóż ma. Jeśli nabierzesz złych nawyków teraz, będziesz miał problem z ich zmianą w przyszłości.

Tobie najwyraźniej się to udało. Gdyby tak nie było, to nie prosiłbyś o pomoc tutaj, prawda?

Więc skąd wziąłeś pomysł, że trzeba? Czytałeś jakiś kurs, książkę o C++?

Jedna do przechowywania opcji wybranej przez użytkownika, dwie to przechowywania argumentów działania i jedna na wynik. Razem cztery - tyle jest w kodzie nr47.

Rozumiem, że się uczysz. Dlatego w poprzednim przedstawiłem Ci kilka spraw/problemów, abyś je sobie przemyślał i ewentualnie dopytał.

Dlatego też nie rzuciłem Ci gotowca, ale skoro nr47 , to przynajmniej masz szansę zobaczyć bardzo dobrze napisany kod.

  1. Tu się zgodzić muszę.

  2. Ale tu już nie. Konwencja nazewnictwa to już sprawa indywidualna, przynajmniej na tym poziomie, później sprawa zespołu. Ja wszystko nazywam wielką literą, tylko że przed zmienną daję typy (np. iCalkowita, fZmiennoprzecinkowa, piPointerCałkowitej), więc dla mnie Twoje nazewnictwo też nie dostarcza wystarczającej ilości informacji.

  3. Mały błąd, początkujący nie musi tego wszystkiego kojarzyć. Problem z tym powinien się ograniczyć do ostrzeżenia kompilatora.

  4. Bo zapomniał?

  5. Trochę na pointer jeszcze za wcześnie…

Chłopak dopiero się uczy, zamiast go zniechęcać i pokazywać jaki jesteś dobry, mógłbyś pomóc…

somekind , Masz racje , ale w kodzie nr47 , rozumiem max 2\3 kodu .

cmath , double result itp nie są dla mnie do końca zrozumiałe .

Uczę się na " Od zera do gier kodera " który jest trochę przestarzały ale zrozumiały .

jak zna ktoś lepszy niech da link , chętnie skorzystam

#include oraz double result to tylko dwie linijki, a to na pewno jest jest 1/3 kodu :stuck_out_tongue: cmath to nagłówek z funkcjami matematycznymi, użyłem go tylko dla wartości NAN liczb zmiennoprzecinkowych. A double to typ, tak samo jak int. int jest dla liczby całkowitych (jak ang. integer - całkowity), a double jest dla liczb zmiennoprzecinkowych (tu nieco mniej oczywisty mnemonik - and. double - podwójny od liczby zmiennoprzecinkowej podwójnej precyzji)

Jeżeli chodzi o naukę to wg mnie nie ma sensu marnować czasu na jakieś kursy internetowe, wydajniejszym rozwiązaniem wydaje się być zakup dobrej książki. Jeżeli naprawdę zależy Ci na nauczeniu się C++ i ogólnie na nauce programowania to radzę kupić Ci dobrą książkę. Jaką? Było bardzo dużo wątków “Jaka książka do nauki X” - wystarczy poszukać na tym forum/Google.

Spróbuj to powiedzieć komuś kto się nie zna na c++ .

tu nie chodzi o C++, tu chodzi o podstawową znajomość działania komputera

Piszesz o notacji węgierskiej, od której raczej się odchodzi, bo np:

  1. dodatkowe zaciemnianie kodu przedrostkami zmniejsza jego czytelność;

  2. nie ma potrzeby redundancji informacji o typie zmiennej, kompilator przecież i tak to wie;

  3. w nowoczesnych IDE wystarczy najechać na nazwę zmiennej w dowolnym miejscu kodu, aby zobaczyć jaki ma typ;

  4. gdy w pewnym momencie zmieniasz typ zmiennej, musisz zmienić też jej nazwę.

Przeciwnikami tej notacji są np. Bjarne Stroustrup (on się chyba trochę zna na C++ ^^) i Linus Torvalds (myślę, że on też “coś” napisać umie).

To tyle o naszych bratankach znad Balatonu. Ale jakby nie patrzeć ważne jest, żeby:

  1. jakąś konwencję mieć - a nie raz tak, raz siak;

  2. nazwy zmiennych i funkcji jednak coś mówiły, a nie brzmiały “adfadas”, bo później patrząc w kod po miesiącu nie załapie się o co chodziło w trakcie jego pisania.

I o to trzeba dbać już od samego początku zabawy w programowanie, bo jak nie, to później będzie źle.

Dlatego mu zwróciłem na to uwagę. “Małe błedy”, ale są.

Nie chciałem nikogo zniechęcać (zresztą wątpię, aby to nastąpiło), tylko zwrócić uwagę na parę rzeczy. I nie jestem wcale dobry, raczej upierdliwy :stuck_out_tongue:

Jeśli masz jeszcze problemy z podstawową składnią, instrukcjami i typami zmiennych, to może zacznij od tego: http://pl.wikibooks.org/wiki/C#Spis_tre.C5.9Bci. To C, a nie C++, ale zasady te same, na pewno nie zaszkodzi.

Natomiast, podobnie jak nr47 uważam, że lepszym wyjściem są książki. Np. “Symfonia C++ Standard”.