Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

program działa, pyt o czytelność kodu

Ostatnio zmodyfikowano 2016-12-31 14:47
Autor Wiadomość
mikewazowski
Temat założony przez niniejszego użytkownika
program działa, pyt o czytelność kodu
» 2016-12-30 23:39:06
zaczynam naukę c++, nie chcę utrwalać złych praktyk, stąd moje pytanie - czy mój kod jest czytelny, czy są w nim jakieś rażące błędy?
( jest to kalkulator temperatur z zabezpieczeniem przed przeliczaniem zera bezwzglednego )

C/C++
#include <iostream>
using namespace std;
// *** przeliczanie temperatur
float cel_na_fahr( float x )
{
    return( x *( 9.0 / 5.0 ) ) + 32;
}
float fahr_na_cel( float x )
{
    return( 5.0 / 9.0 ) *( x - 32 );
}
float cel_na_kel( float x )
{
    return x + 273.15;
}
float kel_na_cel( float x )
{
    return x - 273.15;
}
float kel_na_fah( float x )
{
    int przeliczone, wynik;
    przeliczone = kel_na_cel( x );
    wynik = cel_na_fahr( przeliczone );
    return wynik;
}
float fah_na_kel( float x )
{
    int przeliczone, wynik;
    przeliczone = fahr_na_cel( x );
    wynik = cel_na_kel( przeliczone );
    return wynik;
}
// *** funkcja z menu i zabezpieczeniami przed zerem bezwględnym
void menu()
{
    int wybor;
    float wartosc, wynik;
    do
    {
        cout << "menu" << endl;
        cout << "1-kelwiny na cel\n2-cel na kel\n3-fahr na cel\n4-cel na fah\n5-kel na fah\n6-fah na kel\ntwoj wybor: ";
        cin >> wybor;
        switch( wybor )
        {
        case 1:
            cout << "kel na cel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <= 0 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            wynik = kel_na_cel( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        case 2:
            cout << "cel na kel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <- 270 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            wynik = cel_na_kel( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        case 3:
            cout << "fah na cel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            wynik = fahr_na_cel( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        case 4:
            cout << "cel na fah" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <- 270 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            wynik = cel_na_fahr( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        case 5:
            cout << "kel na fah" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
           
            while( wartosc <= 0 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
           
            wynik = kel_na_fah( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        case 6:
            cout << "fah na kel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            wynik = fah_na_kel( wartosc );
            cout << "w przeliczeniu: " << wynik << endl;
            break;
        }
    }
    while( wybor != 7 );
   
}
int main()
{
    menu();
    return 0;
}
P-155719
mokrowski
» 2016-12-31 00:45:33
Wzorów i obliczeń nie sprawdzałem. Ogólnie dobra robota :-) Małe uwagi umieściłem w kodzie. Jak będziesz bardziej zaawansowany, zapiszesz ten program inaczej :-)
C/C++
#include <iostream>
#include <cstdlib> // XXX: Wytłumaczenie pod koniec main()

using namespace std;

// *** przeliczanie temperatur
float cel_na_fahr( float x )
{
    return( x *( 9.0 / 5.0 ) ) + 32;
}

float fahr_na_cel( float x )
{
    return( 5.0 / 9.0 ) *( x - 32 );
}

float cel_na_kel( float x )
{
    return x + 273.15;
}

float kel_na_cel( float x )
{
    return x - 273.15;
}

float kel_na_fah( float x )
{
    // XXX: Jeśli zmiennej wynik (tu usuniętej) używasz tylko raz, warto skrócić zwrócenie wartości.
    // Dodatkowo, to nie jest dobra praktyka deklarować kilka zmiennych z użyciem przecinka.
    // Problem może pojawić się przy okazji wskaźnika. To zły pomysł.
    int przeliczone;
    przeliczone = kel_na_cel( x );
    return cel_na_fahr( przeliczone );
}

float fah_na_kel( float x )
{
    // XXX: To samo co wyżej.
    int przeliczone;
    przeliczone = fahr_na_cel( x );
    return cel_na_kel( przeliczone );
}

// *** funkcja z menu i zabezpieczeniami przed zerem bezwględnym
void menu()
{
    // XXX: Czy planujesz wartości ujemne? Jeśli nie, zmień na unsigned
    unsigned wybor;
    // XXX: Podobnie jak wyżej. Jeśli zmienna wynik (usunięta), użyta 1 raz, wpisuj bezpośrednio.
    float wartosc;
    do
    {
        cout << "menu" << endl;
        // XXX: Warto poinformować że "7-koniec programu"
        // Warto łamać linie tak aby mieściły się w 80 znakach.. taka "świecka tradycja" :-)
        cout << "1-kelwiny na cel\n2-cel na kel\n3-fahr na cel\n4-cel na fah\n5-kel na fah"
        "\n6-fah na kel\n7-koniec programu\ntwoj wybor: ";
        cin >> wybor;
        switch( wybor )
        {
        case 1:
            cout << "kel na cel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <= 0 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            cout << "w przeliczeniu: " << kel_na_cel( wartosc ) << endl;
            break;
        case 2:
            cout << "cel na kel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <- 270 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            cout << "w przeliczeniu: " << cel_na_kel( wartosc ) << endl;
            break;
        case 3:
            cout << "fah na cel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            cout << "w przeliczeniu: " << fahr_na_cel( wartosc ) << endl;
            break;
        case 4:
            cout << "cel na fah" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            while( wartosc <- 270 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
            cout << "w przeliczeniu: " << cel_na_fahr( wartosc ) << endl;
            break;
        case 5:
            cout << "kel na fah" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
           
            while( wartosc <= 0 )
            {
                cout << "podaj wartosc wieksza niz zero bezwzgledne: ";
                cin >> wartosc;
            }
           
            cout << "w przeliczeniu: " << kel_na_fah( wartosc ) << endl;
            break;
        case 6:
            cout << "fah na kel" << endl;
            cout << "podaj wartosc do przeliczenia: " << endl;
            cin >> wartosc;
            cout << "w przeliczeniu: " << fah_na_kel( wartosc ) << endl;
            break;
            // XXX: Dodaj default jako nieprawidłowy wybór oraz 7-koniec programu
            // Jest to miłe dla uruchamiającego program.
        case 7:
            cout << "koniec programu\n";
            break;
        default:
            cout << "to nie jest prawidlowy wybor\n";
            break;
        }
    }
    while( wybor != 7 );
   
}
int main()
{
    menu();
    // XXX: Nie zwracaj "magicznych zer" czy innych wartości. Po pierwsze akurat w main() możesz
    // nie zwracać w C++ nic (ale w C to nie jest prawda) i kompilator sam dopisze Ci zero, ale poprawniej
    // jest zwrócić wartość z cstdlib (dodałem na początku #include ) EXIT_SUCCESS
    return EXIT_SUCCESS;
}

Jeszcze uwaga co do użycia std::endl, std::flush, "\n". Doczytaj jakie są różnice, przemyśl i będzie po sprawie :-)
P-155721
michal11
» 2016-12-31 02:06:39
Jest dobrze, ale mogłoby być lepiej. W casach naruszasz DRY, można to na pewno jakoś inaczej, sprytniej zapisać. 

@mokrowski

Jeżeli chodzi o zmienne w funkcjach, oczywiscie zgadzam się ale to co napisał mikewazowski i tak zostanie zoptymalizowane a czasami łatwiej się debuguje jak są zmienne w kodzie.
P-155724
mokrowski
» 2016-12-31 13:30:02
Oczywiście że da się to zapisać ładniej ale po ilości postów kolegi (~8) wnioskuję że kontener lambd lub inne rozwiązania z wydzielonymi funkcjami (może np. mapa) były by zbyt zaawansowane. Jeśli kolega będzie chciał to poprosi o napisanie nieco nowocześniej :-)

Moim zdaniem kod jest _dla_ludzi_ a nie dla debugera. Ale tu wkraczamy w obszar "kto co uważa" więc nie będę brnął :-) Dość że ma się czytać dobrze dla człowieka. Jak będzie konieczność debugowania i tak będzie walka. Im krótszy kod (powyżej wyraźnej granicy dla C++ ~ 10-15 linii) tym mniej błędów :-)

Na marginesie... 
Im więcej praktyki tym częściej się testuje nie debuguje. Testem jest szybciej :-)

P-155733
mikewazowski
Temat założony przez niniejszego użytkownika
» 2016-12-31 13:48:56
dziękuje za wskazówki :) uściślając nie jestem kolegą tylko koleżanką, tylko dwa pytania - czym jest DRY które naruszam w casach? (nie spotkałam się z tym sformułowaniem wcześniej)i dlaczego poprawniej jest używać
return EXIT_SUCCESS;
 zamiast
return 0;
 lub nie pisać return?
P-155734
carlosmay
» 2016-12-31 14:06:20
DRY - don't repeat yourself
W skrócie. Pisanie kodu tak, aby się nie powtarzał.
Jeśli jakiś fragment powtarza się kilka razy, należy ująć dany fragment w funkcję i to ją wywoływać
w tych miejscach.

@mikewazowski - Hmm? Wszystko wskazuje na male;
P-155735
mokrowski
» 2016-12-31 14:23:33
No to wybacz że nie domyśliłem się płci :-)
Jeszcze to jest istotne https://pl.wikipedia.org/wiki​/KISS_(regu%C5%82a)  Wraz z DRY jest częścią ZEN programowania :-)
P-155737
mikewazowski
Temat założony przez niniejszego użytkownika
» 2016-12-31 14:47:45
ok, dziekuje jeszcze raz za pomoc :D zamykam
P-155741
« 1 »
  Strona 1 z 1