Skocz do zawartości

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

nyac55

C# - Program Kalkulator w obiektowym z Odwróconą Notacją Polska?

Polecane posty

Spróbuj sobie jeszcze raz prześledzić pierwsze 3 linijki w pierwszym if'ie w metodzie Add.

Tak w ogóle to próbujesz analizować ten kod, czy dopisujesz parę zmian, sprawdzasz czy działa i zadajesz kolejne pytanie na forum?

Bo te błędy są na tyle proste, że bez wielce skomplikowanej analizy da się je wyłapać.

Link do komentarza
Udostępnij na innych stronach

Tak w ogóle to próbujesz analizować ten kod, czy dopisujesz parę zmian, sprawdzasz czy działa i zadajesz kolejne pytanie na forum?

Po zrobieniu kilku zmian zastanawiam się co dalej zrobić, żeby program działał poprawnie. Jeśli nic sensownego nie uda mi się wymyślić piszę na forum.

_+_+_


double dana = _stos.Pop();
//
char znak =Convert.ToChar(Convert.ToString(dana));

Wydaje mi się, że błąd znajduje się w tym lub tym fragmencie tekstu.


case ('+'):
_stos.Push(_stos.Pop() + _stos.Pop()); // po ściągnięciu tych wartości nie ma ich już na stosie czy są?
_stos.Peek();
break;

Według mnie w 2 fragmencie wkładamy na stos wartość, która jest sumą wartości ściągniętej z szczytu stosu z wartością kolejną. Następnie zwracamy wynik z szczytu stosu, który jest tam wrzucany po zakończonej operacji np. dodawania.

-=-=-=-

Natomiast w 1 fragmencie, myślę, że może być jakiś problem z ściągnięciem wartości (bo jest to znak, a ja konwertuję to na double do zmiennej dana)?

Link do komentarza
Udostępnij na innych stronach

Na stosie znajdują się jedynie obiekty typu double, więc nie ma możliwości, żeby się tam znalazł jakiś znak.

Najlepiej się zastanów, skąd wyciągnąć operator (przyjrzenie się pierwszej linijce (z if'em) jest chyba w tym przypadku kluczowe).

I nie ma sensu rzutować string'a na char'a, skoro również z tym pierwszym sobie switch poradzi (chociaż oczywiście trzeba zmienić przy case'ach 'operator' na "operator".

Nie zwróciłem wcześniej na to uwagi, ale jaki sens mają wywołania Peek() ?

Link do komentarza
Udostępnij na innych stronach


public void Accept_button_Click(object sender, EventArgs e)
{
liczba = textBox1.Text;
if (liczba.Equals("-") || liczba.Equals("+") || liczba.Equals("*") || liczba.Equals("/"))
{
znak = textBox1.Text;
_calculator.Add(znak);
}
else
{
_calculator.Add(liczba);
}
textBox1.Text = ""; // czyszczenie text Boxa po zatwierdzeniu liczby
}

Czy w form1 powinno się znaleźć takie coś? czy do odczytywania znaku powinienem stworzyć nową metodę?

Odnośnie Peek() <- miało zwracać obliczony wynik, który znajduje się na szczycie stosu:


_stos.Push(_stos.Pop() - _stos.Pop());
_stos.Peek();

_+_+_

Obecnie program liczy poprawnie, aczkolwiek nie generuje komunikatów o błędzie.

Czy do generowania komunikatów powinienem stworzyć nową metodę, czy zrobić to jakoś inaczej?

Poniżej zamieszczam kod:

https://www.dropbox.com/s/uhxeh3saa4z2qlk/Projekt1_GUI%20v.2.3.rar

Link do komentarza
Udostępnij na innych stronach

Po stronie Form1 wszystko wydawało mi się już poprawne (ale przy okazji znowu mogę wypomnieć pole znak, które mogłoby być zmienną w metodzie, jak również mogłoby nie istnieć wcale, bo dokładnie tę samą wartość przetrzymuje liczba, która zresztą też polem być nie musi, a jej istnienie można co najwyżej wyjaśnić nieco krótszym zapisem warunku if'a i ew. względami wydajnościowymi). Zresztą zauważ, że ta funkcja wykonuje jedynie dwie istotne instrukcje:

- wywołanie metody Add z wartością textBox1.Text

- wyczyszczenie textBox1.Text

a reszta to przypisania do pól, które nigdzie nie są używane.

Sama metoda Peek() zwraca wartość pierwszego elementu na stosie, więc samo jej wywołanie rzeczywiście zwraca wartość, ale też zaraz ją zapomina (i w ogóle nie ma w tym miejscu racji bytu). Właściwie to ta funkcja ma sens jedynie w metodzie wynik (przy okazji powinna zostać wywołana po sprawdzeniu, czy na stosie znajduje się jeden element, a w przeciwnym wypadku zwrócić "error")

Link do komentarza
Udostępnij na innych stronach

Obecnie program działa dość zadowalająco. Podanie 2 argumentów i operatora poprawnie liczy. Podanie więcej np. 3 i znaku powoduje wyświetlenie komunikatu o błędzie. Natomiast jeśli podamy 2 argumenty+operator i obliczymy wynik to np. wynik kasujemy backspace'em i możemy wprowadzić 2 wartość, gdzie 1 wartością będzie obliczony wcześniej wynik, a 2 tą, którą wprowadzimy co oznacza, że po obliczeniu wyniku możemy kontynuować obliczenia na naszym wyniku. Poniżej kod programu:

https://www.dropbox.com/s/ly7nzfgooktpvos/Projekt1_GUI%20v.2.4.rar

Myślę, że to wystarczy w razie co jeszcze będę pisał. Dzięki za pomoc. :)

Link do komentarza
Udostępnij na innych stronach


string wynik2 = Convert.ToString(_stos.Peek());
if (_stos.Count == 1)
{
return wynik2;
}
else if(_stos.Count!=1)
{
string error = "error";
return error;
}
return wynik2;

Ten kod nadal nie jest poprawny (jeżeli po uruchomieniu programu wciśniesz "=", rzuca błędem, bo stos jest pusty, a próbujesz pobrać z niego element). Można zrezygnować z drugiego if'a (sam else wystarczy) i końcowego returna.

A reszta wygląda mi już poprawnie.

Link do komentarza
Udostępnij na innych stronach

Na stos możesz wrzucić w takim wypadku Double.NaN i wtedy w metodzie wynik musiałbyś jeszcze sprawdzić, czy Peek'nięta ze stosu liczba nie spełnia Double.IsNaN(liczba)

Nie bardzo się orientuję o co w ogóle chodzi. Mógłbyś wytłumaczyć mi to jaśniej? Czym jest to Double.NaN i po co to wrzucać na stos? Ja chcę sprawdzić czy 1 wartość nie jest 0. W projekcie wartość ściągniętą ze stosu zapisuję do zmiennej d1. Czy da się to jakoś prościej zrobić?

_+_+_

Na stos możesz wrzucić w takim wypadku Double.NaN

Nie bardzo wiem jak to zapisać. Natomiast próbowałem zapisać Double.IsNaN(liczba) w metodzie wynik, aczkolwiek metoda Add nie chce mi zwrócić wartości zmiennej liczba:


public String wynik()
{
string error = "error";
string wynik2 = Convert.ToString(_stos.Peek());
if (wynik2 != Double.IsNaN(liczba))
{
return error;
}
if (_stos.Count == 1)
{
return wynik2;
}
else //if(_stos.Count!=1)
{
//string error = "error";
return error;
}
//return wynik2;
}

Link do komentarza
Udostępnij na innych stronach

Chyba trochę za szybko ogłosiłem poprawność kodu.

Chyba metoda Add wymaga zwrócenia wartości (bool), która będzie informować, czy wszystko poszło poprawnie.

Na początek wróciłbym przed switch'a. Obecność w tym miejscu wymaga, żeby na stosie znajdowały się przynajmniej dwie liczby. Czyli jeżeli liczność stosu jest mniejsza od 2, możesz zwrócić false (a nawet najpierw wywołać Clear).

Idąc dalej:


if (_stos.Pop() == 0)
{
Clear();
}

Tutaj powinieneś zamiast Pop użyć Peek, bo w warunku chcesz tylko sprawdzić, czy dzielnik jest zerem, ale do obliczeń pobierasz go dopiero później.

Po Clear powinno się pojawić return false, co w sumie będzie sensowniejsze od umieszczania na stosie Nan'a (którego umieszczałoby się wywołując _stos.Push(Double.NaN)).

Na końcu funkcji powinno się jeszcze pojawić return true, które będzie informować, że wszystko jest git.

Zwrócenie wartości przez metodę Add będzie wymagało drobnej zmiany po stronie GUI, np



if (_calculator.Add(liczba))
textBox1.Text = "";
else
textBox1.Text = "error";

Link do komentarza
Udostępnij na innych stronach

Chyba metoda Add wymaga zwrócenia wartości (bool), która będzie informować, czy wszystko poszło poprawnie.

W takim razie metoda ma być typu bool np. public bool Add(string liczba, bool prawda)? Czy jakoś inaczej też da się zwrócić wartość logiczną boola?

Poniżej zamieszczam co udało mi się napisać, w kodzie są jeszcze błędy:

https://www.dropbox.com/s/37i4farel0bbtc0/Projekt1_GUI%20v.2.6.rar

Link do komentarza
Udostępnij na innych stronach

Pop'owanie ze stosu przy dzieleniu było w poprawnym miejscu, obecnie jest umieszczone bez sensu.

Metoda Add nie potrzebuje tego dodatkowego parametru, wartość funkcji zwracasz za pomocą słowa return.

I po co pojawia się pole prawda, używane tylko w jednym miejscu w programie (nie prościej zamiast tamtych dwóch linijek napisać return false?)

Link do komentarza
Udostępnij na innych stronach

Obecnie mam jeszcze kilka błędów:

https://www.dropbox.com/s/ssxyrknh7l7fdya/Projekt1_GUI%20v.2.7.rar

_ _ _ _ _

1>------ Kompilacja rozpoczęta: ProjektProjekt1_Core_dl, KonfiguracjaDebug Any CPU ------

1>C:\Users\Patryk\Downloads\Projekt1_GUI\Projekt1_Core_dl\Class1.cs(64,29,64,35): warning CS0162: Wykryto nieosiągalny kod.

1>C:\Users\Patryk\Downloads\Projekt1_GUI\Projekt1_Core_dl\Class1.cs(15,21,15,24): error CS0161: ?Projekt1_Core_dl.Calculator.Add(string)?: nie dla wszystkich ścieżek kodu jest zwracana wartość.

2>------ Kompilacja rozpoczęta: ProjektProjekt1_GUI, KonfiguracjaDebug Any CPU ------

2>C:\Users\Patryk\Downloads\Projekt1_GUI\Projekt1_GUI\Form1.cs(179,17,179,40): error CS0029: Nie można niejawnie przekonwertować typu ?void? na ?bool?.

========== Kompilacja: 0 zakończono powodzeniem, 2 zakończono niepowodzeniem, 0 zaktualizowano, 0 pominięto ==========

Link do komentarza
Udostępnij na innych stronach

Natomiast tego błędu nie rozumiem:

2>C:\Users\Patryk\Downloads\Projekt1_GUI\Projekt1_GUI\Form1.cs(179,17,179,40): error CS0029: Nie można niejawnie przekonwertować typu ?void? na ?bool?.

Wyświetla się na metodzie Add, która wcześniej była void, a teraz jest bool. Więc co tu konwertować?

Link do komentarza
Udostępnij na innych stronach

To o czym pisałeś webtom się zgadza. Nie wiem co tam jest nie tak, co do 1 błędu to do funkcji Add powrzucałem returny w każdym możliwym miejscu, jednak nadal widzi błędy. Co do 2 błędu widzi błąd i w klasie i w bibliotece, niby wszystko powinno być poprawnie, ale nie działa.

https://www.dropbox.com/s/a7pi8fq8527c8qa/Projekt1_GUI%20v.2.8.rar

Link do komentarza
Udostępnij na innych stronach



  • Kto przegląda   0 użytkowników

    • Brak zalogowanych użytkowników przeglądających tę stronę.

×
×
  • Utwórz nowe...