Flächeninhalt bestimmen


  • Gesperrt

    Das sollten jetzt alle Fälle sein...

    #include <iostream>
    #include <map>
    #include <string>
    #include <math.h>
    
    using namespace std;
    
    enum Typ_Schenkel_Dreieck
    {
        beliebig,
        gleichschenklig,
        gleichseitig
    };
    
    enum Typ_Winkel_Dreieck
    {
        spitzwinklig,
        stumpfwinklig,
        rechtwinklig
    };
    
    class Dreieck
    {
    private:
    public:
        float a, b, c;
        const float e = 0.1;
        float aw, bw, cw;
        Dreieck(float a, float b, float c) : a{a}, b{b}, c{c}
        {
            float a2 = a * a, b2 = b * b, c2 = c * c;
            aw = acosf((b2 + c2 - a2) / (2 * b * c)) * (180 / 3.14159265358979323846);
            bw = acosf((a2 + c2 - b2) / (2 * a * c)) * (180 / 3.14159265358979323846);
            cw = acosf((a2 + b2 - c2) / (2 * a * b)) * (180 / 3.14159265358979323846);
        };
    
        ~Dreieck()
        {
        }
    
        bool is_equal(float a, float b) const
        {
            return fabs(a - b) - e <= 0;
        }
    
        Typ_Schenkel_Dreieck get_type_schenkel() const
        {
            if (is_equal(a, b) && is_equal(b, c))
                return Typ_Schenkel_Dreieck::gleichseitig;
            if (is_equal(a, b) || is_equal(a, c) || is_equal(b, c))
                return Typ_Schenkel_Dreieck::gleichschenklig;
            return beliebig;
        }
    
        Typ_Winkel_Dreieck get_type_winkel() const
        {
            if (is_equal(aw, 90) || is_equal(bw, 90) || is_equal(cw, 90))
                return Typ_Winkel_Dreieck::rechtwinklig;
            if (aw >= 90 || bw >= 90 || cw >= 90)
                return Typ_Winkel_Dreieck::stumpfwinklig;
            return Typ_Winkel_Dreieck::spitzwinklig;
        }
    };
    
    const char *type_to_string(Typ_Schenkel_Dreieck es, Typ_Winkel_Dreieck ew)
    {
        string s1, s2;
        switch (es)
        {
        case Typ_Schenkel_Dreieck::beliebig:
            s1 = "beliebig, ";
            break;
        case Typ_Schenkel_Dreieck::gleichschenklig:
            s1 = "gleichschenklig, ";
            break;
        case Typ_Schenkel_Dreieck::gleichseitig:
            s1 = "gleichseitig, ";
            break;
        default:
            s1 = "not defined";
            break;
        }
        switch (ew)
        {
        case Typ_Winkel_Dreieck::spitzwinklig:
            s2 = "spitzwinklig";
            break;
        case Typ_Winkel_Dreieck::stumpfwinklig:
            s2 = "stumpfwinklig";
            break;
        case Typ_Winkel_Dreieck::rechtwinklig:
            s2 = "rechtwinklig";
            break;
        default:
            s2 = "not defined";
            break;
        }
        return (s1 + s2).c_str();
    }
    
    ostream &operator<<(ostream &strm, const Dreieck &d)
    {
        return strm << "Dreieck(" << d.a << ", " << d.b << ", " << d.c << ", " << d.aw << ", " << d.bw << ", " << d.cw << ","
                    << endl
                    << type_to_string(d.get_type_schenkel(), d.get_type_winkel()) << ")";
    }
    
    int main(int argc, char **argv)
    {
        cout << Dreieck(15, 20, 25) << endl;
        cout << Dreieck(1.414, 1.414, 2) << endl;
        cout << Dreieck(2, 2, 3) << endl;
        cout << Dreieck(4, 4, 1) << endl;
        return EXIT_SUCCESS;
    }
    


  • @EinNutzer0 Dir ist hoffentlich aufgefallen, dass das Thema unter der Rubrik C eingestellt ist und nicht unter C++?



  • Und wegen

    const char *type_to_string(...)
    {
      // ...
      return (s1 + s2).c_str();
    }
    

    auch noch UB (nimm also string als Rückgabetyp).


  • Gesperrt

    @john-0 sagte in Flächeninhalt bestimmen:

    @EinNutzer0 Dir ist hoffentlich aufgefallen, dass das Thema unter der Rubrik C eingestellt ist und nicht unter C++?

    Naja aber lässt sich ja, wenn er <math.h> inkludiert, einfach nach C übertragen - da muss er eben alles in eine Funktion schreiben.

    @Th69 sagte in Flächeninhalt bestimmen:

    nimm also string als Rückgabetyp

    Danke.



  • @EinNutzer0 sagte in Flächeninhalt bestimmen:

        ~Dreieck()
        {
        }
    

    Why, oh why 😭


  • Gesperrt

    Hier einmal der C-Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    typedef struct Dreieck
    {
        float a, b, c, aw, bw, cw;
    } Dreieck;
    
    Dreieck *get_Dreieck(float a, float b, float c)
    {
        float a2 = a * a, b2 = b * b, c2 = c * c;
        Dreieck *d = (Dreieck *)malloc(sizeof(Dreieck *));
        d->a = a;
        d->b = b;
        d->c = c;
        d->aw = acos((b2 + c2 - a2) / (2 * b * c)) * (180 / 3.14159265358979323846);
        d->bw = acos((a2 + c2 - b2) / (2 * a * c)) * (180 / 3.14159265358979323846);
        d->cw = acos((a2 + b2 - c2) / (2 * a * b)) * (180 / 3.14159265358979323846);
        if (d->aw == 0 || d->bw == 0 || d->cw == 0)
        {
            printf("Unmögliches Dreieck angegeben!!\n");
            free(d);
            return 0;
        }
        return d;
    }
    
    int is_equal(float a, float b)
    {
        return fabs(a - b) - 0.1 <= 0;
    }
    
    void print_Dreieck(Dreieck *d)
    {
        float s, A;
        if (d == 0)
            return;
        printf("Dreieck: %f %f %f %f %f %f\n", d->a, d->b, d->c, d->aw, d->bw, d->cw);
        if (is_equal(d->a, d->b) && is_equal(d->b, d->c))
            printf("Das Dreieck ist gleichseitig\n");
        else if (is_equal(d->a, d->b) || is_equal(d->a, d->c) || is_equal(d->b, d->c))
            printf("Das Dreieck ist gleichschenklig\n");
        else
            printf("Das Dreieck ist beliebig\n");
    
        if (is_equal(d->aw, 90) || is_equal(d->bw, 90) || is_equal(d->cw, 90))
            printf("Das Dreieck ist rechtwinklig\n");
        else if (d->aw >= 90 || d->bw >= 90 || d->cw >= 90)
            printf("Das Dreieck ist stumpfwinklig\n");
        else
            printf("Das Dreieck ist spitzwinklig\n");
    
        s = (d->a + d->b + d->c) * 0.5;
        A = sqrt(s * (s - d->a) * (s - d->b) * (s - d->c));
        printf("Der Flächeninhalt entspricht: %f\n\n", A);
    }
    
    int main()
    {
        print_Dreieck(get_Dreieck(1, 2, 3));
        print_Dreieck(get_Dreieck(2, 2, 3));
        print_Dreieck(get_Dreieck(15, 20, 25));
        print_Dreieck(get_Dreieck(3, 3, 3));
        return 0;
    }
    

    Bitte mit -lm compilieren!!

    $ ./Dreieck.out 
    Unmögliches Dreieck angegeben!!
    Dreieck: 2.000000 2.000000 3.000000 41.409622 41.409622 97.180756
    Das Dreieck ist gleichschenklig
    Das Dreieck ist stumpfwinklig
    Der Flächeninhalt entspricht: 1.984313
    
    Dreieck: 15.000000 20.000000 25.000000 36.869896 53.130100 90.000000
    Das Dreieck ist beliebig
    Das Dreieck ist rechtwinklig
    Der Flächeninhalt entspricht: 150.000000
    
    Dreieck: 3.000000 3.000000 3.000000 60.000000 60.000000 60.000000
    Das Dreieck ist gleichseitig
    Das Dreieck ist spitzwinklig
    Der Flächeninhalt entspricht: 3.897114
    

    Nu hab ich endlich alle Fälle abgefrühstückt,
    daran, dass ein gegebenes Dreieck natürlich auch ungültig sein kann, hab ich erst wieder nicht gedacht!! 😅



  • Du hast ein Speicherleck eingebaut.

    Deine Funktion get_Dreieck erzeugt ein NEUES Dreieck, das aber nie freigegeben wird.

    Und das hier:

    Dreieck *d = (Dreieck *)malloc(sizeof(Dreieck *));

    WTF? Der Cast ist in C nicht nötig und sizeof von einem Pointer?



  • @wob sagte in Flächeninhalt bestimmen:

    Der Cast ist in C nicht nötig

    Ein C/C++-Programmierer ...

    @EinNutzer0 Vielleicht auch mal drüber nachdenken daß man Variablen auch auf den ersten Blick verständliche Namen geben kann ohne groß über die rechte Seite von = nachdenken zu müssen.



  • @Swordfish sagte in Flächeninhalt bestimmen:

    WTF? Der Cast ist in C nicht nötig

    ok, was WTF war mehr auf den hinteren Teil meiner Aussage bezogen. Das malloc(pointerlänge) für ein Dreieck. => Heap-Overflow. Der Cast ist nicht so relevant hier, wenn da so ein Klopper drin ist.


  • Gesperrt

    Ups, ja habt recht, Copy'n'Paste 😅



  • @wob Zitat editiert ^^


  • Gesperrt

    Vielleicht noch von Interesse:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    typedef struct Dreieck
    {
        float a, b, c, aw, bw, cw;
    } Dreieck;
    
    Dreieck *get_Dreieck(float a, float b, float c)
    {
        float a2 = a * a, b2 = b * b, c2 = c * c;
        Dreieck *d = malloc(sizeof(Dreieck));
        d->a = a;
        d->b = b;
        d->c = c;
        d->aw = acos((b2 + c2 - a2) / (2 * b * c)) * (180 / 3.14159265358979323846);
        d->bw = acos((a2 + c2 - b2) / (2 * a * c)) * (180 / 3.14159265358979323846);
        d->cw = acos((a2 + b2 - c2) / (2 * a * b)) * (180 / 3.14159265358979323846);
        if (d->aw == 0 || d->bw == 0 || d->cw == 0)
        {
            printf("Unmögliches Dreieck angegeben!\n\n");
            free(d);
            return 0;
        }
        return d;
    }
    
    int is_equal(float a, float b)
    {
        return fabs(a - b) - 0.1 <= 0;
    }
    
    void print_Dreieck(Dreieck *d)
    {
        float s, A;
        if (d == 0)
            return;
        printf("Dreieck: %f %f %f %f %f %f\n", d->a, d->b, d->c, d->aw, d->bw, d->cw);
        if (is_equal(d->a, d->b) && is_equal(d->b, d->c))
            printf("Das Dreieck ist gleichseitig\n");
        else if (is_equal(d->a, d->b) || is_equal(d->a, d->c) || is_equal(d->b, d->c))
            printf("Das Dreieck ist gleichschenklig\n");
        else
            printf("Das Dreieck ist beliebig\n");
    
        if (is_equal(d->aw, 90) || is_equal(d->bw, 90) || is_equal(d->cw, 90))
            printf("Das Dreieck ist rechtwinklig\n");
        else if (d->aw >= 90 || d->bw >= 90 || d->cw >= 90)
            printf("Das Dreieck ist stumpfwinklig\n");
        else
            printf("Das Dreieck ist spitzwinklig\n");
    
        s = (d->a + d->b + d->c) * 0.5;
        A = sqrt(s * (s - d->a) * (s - d->b) * (s - d->c));
        printf("Der Flächeninhalt entspricht: %f\n\n", A);
    }
    
    void get_and_print_Dreieck(float a, float b, float c)
    {
        Dreieck *d = get_Dreieck(a, b, c);
        if (d)
        {
            print_Dreieck(d);
            free(d);
        }
    }
    
    int main()
    {
        get_and_print_Dreieck(1, 2, 3);
        get_and_print_Dreieck(2, 2, 3);
        get_and_print_Dreieck(15, 20, 25);
        get_and_print_Dreieck(3, 3, 3);
        return 0;
    }
    

    (wieder mit -lm compilieren)

    Jetzt müsste sich der Themenersteller noch einmal melden, ob er noch weitere "Sachen" im Dreieck berechnen möchte - oder, ob das so ok wäre...

    Ich finde es btw nicht so schlimm, wenn die Attribute a,b,c,usw. heißen, denn bei einem Dreieck weiß man doch, dass damit die Seitenlängen gemeint sind.


Anmelden zum Antworten