Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Bruchrechnen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
07.11.2004, 13:00 Uhr
rejo



Also ich hab nen kleinen ansatz gemacht und mir kommen einige (16) Fehler... naja zuerst waren es 90 aber die konnt ich irgendwie wegbekommen

hier die quellcodes:

die Datei um die Klasse zu testen

C++:
#include <iostream>
#include "Bruch.h"

void main()
{
    Bruch one;
    std::cout << "Bitte geben Sie den Bruch ein: ";
    std::cin >> one;
    std::cout << std::endl;
    std::cout << one;
}




die Implementierung

C++:
#include "Bruch.h"
#include <iostream>

Bruch::Bruch()
{
    z = 0;
    n = 1;
}

Bruch::Bruch(int a, int b)
{
    z = a;
    n = b;
}

Bruch::Bruch(int a)
{
    z = a;
    n = 1;
}

Bruch::Bruch(Bruch &a)
{
    z = a.z;
    n = a.n;
}

void Bruch::setBruch()
{
    Bruch h;

    cin >> h;

}

void Bruch::outBruch(void)
{
    Bruch h = *this;
    cout << h;
}

Bruch::~Bruch()
{
}

double Bruch::todouble(void)
{
    return (double)z / n;
}

Bruch Bruch::operator +(Bruch &a)
{
    Bruch h;

    h.z = (z * a.n) + (n * a.z);
    h.n = (n * a.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator +(Bruch &a, Bruch &b)
{
    Bruch h;

    h.z = (a.z * b.n) + (a.n * b.z);
    h.n = (a.n * b.n);
    
    h.kuerzen();
    
    return h;
}

Bruch Bruch::operator -(Bruch &a)
{
    Bruch h;

    h.z = (z * a.n) - (n * a.z);
    h.n = (n * a.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator -(Bruch &a, Bruch &b)
{
    Bruch h;

    h.z = (a.z * b.n) - (a.n * b.z);
    h.n = (a.n * b.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator *(Bruch &a)
{
    Bruch h;

    h.z = (z * a.n) * (n * a.z);
    h.n = (n * a.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator *(Bruch &a, Bruch &b)
{
    Bruch h;

    h.z = (a.z * b.n) * (a.n * b.z);
    h.n = (a.n * b.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator /(Bruch &a)
{
    Bruch h;

    h.z = (z * a.n) / (n * a.z);
    h.n = (n * a.n);

    h.kuerzen();

    return h;
}

Bruch Bruch::operator /(Bruch &a, Bruch &b)
{
    Bruch h;

    h.z = (a.z * b.n) / (a.n * b.z);
    h.n = (a.n * b.n);

    h.kuerzen();

    return h;
}

ostream & Bruch::operator <<(ostream &o, Bruch &b)
{
    o << b.z << " / " << b.n << std::endl;
    return o;
}

istream & Bruch::operator >>(istream &i, Bruch &b)
{
    char in[129];
    int ok = 0;
    
    i >> in;

    ok = sscanf(in,"%d / %d", &(b.z), &(b.n));

    if(ok == 1)
    {
        b.n = 1;
    }
    
    if(ok == 2)
    {
        ok = (b.n != 0);
    }

    if(ok)
    {
        b.kuerzen();
    }

    else
    {
        b.z = 0;
        b.n = 1;
    }
    
    return i;
}

void Bruch::kuerzen(void)
{
    int hz = z;
    unsigned hn = n;

    do
    {
        while(hz < hn)
        {
            hn = hn - hz;
        }

        while(hn < hz)
        {
            hz = hz - hn;
        }
    
    }while(hz != hn);

    z = z / hz;
    n = n / hn;
}



die klasse

C++:
#ifndef _BRUCH_
#define _BRUCH_
#include <iostream>
using namespace std;

class Bruch
{
    private:
        int z;
        unsigned int n;
        void kuerzen();

    public:
        Bruch();
        Bruch(int,int);
        Bruch(int);
        Bruch(Bruch &);
        static void setBruch();
        void outBruch() const;
        ~Bruch();
        double todouble();
        Bruch operator+(Bruch &);
        Bruch operator+(Bruch &,Bruch &);
        Bruch operator-(Bruch &);
        Bruch operator-(Bruch &,Bruch &);
        Bruch operator*(Bruch &);
        Bruch operator*(Bruch &,Bruch &);
        Bruch operator/(Bruch &);
        Bruch operator/(Bruch &,Bruch &);
        ostream & operator<<(ostream &o, Bruch &b);
        istream & operator>>(istream &i, Bruch &b);
};

#endif

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
07.11.2004, 13:39 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hi und welche fehler kommen denn, mein "in-kopf-embedded-compiler" ist grad in reparatur
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
07.11.2004, 15:08 Uhr
0xdeadbeef
Gott
(Operator)


Auf den ersten Blick fällt mir auf, dass da

C++:
void main()


steht, was natürlich falsch ist. Mach

C++:
int main()


draus.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.11.2004, 15:23 Uhr
Spacelord
Hoffnungsloser Fall


Auf Anhieb frage ich mich was du mit deiner statischen Methode setBruch()
vorhast?

C++:
void Bruch::setBruch()
{
    Bruch h;

    cin >> h;

}


Du liest das lokale Objekt h ein.Und was passiert wenn setBruch zurückkehrt?

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
07.11.2004, 15:35 Uhr
0xdeadbeef
Gott
(Operator)


OK, ich hab mal ein bisschen Zeit drauf verschwendet und das ganze so umgeschrieben, dass es läuft. Die Fehler waren im Wesentlichen Verletzung der const-correctness und das Scoping der Operatoren - Member-Operatoren haben this implizit als erstes Argument, deswegen ist ein Bruch::operator+(Bruch&, Bruch& ziemlicher Schwachfug. Ansonsten hab ich den operator>> so umgeschrieben, dass er auch sinnvoll aus Dateien lesen kann.

C++:
// bruch.hh

#ifndef INCLUDED_BRUCH_HH
#define INCLUDED_BRUCH_HH

#include <iostream>

class Bruch
{
private:
  int z;
  unsigned int n;
  void kuerzen();

public:
  Bruch();
  Bruch(int,int);
  Bruch(int);

  ~Bruch();

  void outBruch() const;
  double todouble() const;

  int getNumerator() const;
  int getDenominator() const;

  Bruch operator+(Bruch const &) const;
  Bruch operator-(Bruch const &) const;
  Bruch operator*(Bruch const &) const;
  Bruch operator/(Bruch const &) const;

  friend std::istream &operator>>(std::istream &i, Bruch &b);
};

std::ostream &operator<<(std::ostream &o, Bruch const &b);
std::istream &operator>>(std::istream &i, Bruch &b);

#endif



C++:
// bruch.cc

#include "bruch.hh"

#include <iostream>
#include <string>
#include <cstdio>

using namespace std;

Bruch::Bruch()             : z(0), n(1) { }
Bruch::Bruch(int a, int b) : z(a), n(b) { }
Bruch::Bruch(int a)        : z(a), n(1) { }

void Bruch::outBruch(void) const { cout << *this; }

Bruch::~Bruch() { }

double Bruch::todouble() const { return (double)z / n; }

int Bruch::getNumerator  () const { return z; }
int Bruch::getDenominator() const { return n; }

Bruch Bruch::operator +(Bruch const &a) const {
  Bruch h;

  h.z = (z * a.n) + (n * a.z);
  h.n = (n * a.n);

  h.kuerzen();

  return h;
}

Bruch Bruch::operator -(Bruch const &a) const {
  Bruch h;

  h.z = (z * a.n) - (n * a.z);
  h.n = (n * a.n);

  h.kuerzen();

  return h;
}

Bruch Bruch::operator *(Bruch const &a) const {
  Bruch h;

  h.z = (z * a.n) * (n * a.z);
  h.n = (n * a.n);

  h.kuerzen();

  return h;
}

Bruch Bruch::operator /(Bruch const &a) const {
  Bruch h;

  h.z = (z * a.n) / (n * a.z);
  h.n = (n * a.n);

  h.kuerzen();

  return h;
}

ostream &operator <<(ostream &o, Bruch const &b) {
  o << b.getNumerator() << " / " << b.getDenominator() << std::endl;
  return o;
}

istream &operator >>(istream &i, Bruch &b) {
  char c;

  i >> b.z;
  if(i) {
    while((c = i.get()) == ' ');
    if(c == '/')
      i >> b.n;
    else
      b.n = 1;
  } else
    b.n = 1;

  b.kuerzen();

  return i;
}

void Bruch::kuerzen() {
  int hz = z;
  unsigned hn = n;

  do {
    while(hz < hn)
      hn = hn - hz;
    while(hn < hz)
      hz = hz - hn;
  } while(hz != hn);

  z = z / hz;
  n = n / hn;
}



C++:
// main.cc
#include "bruch.hh"

#include <iostream>

int main()
{
    Bruch one;
    std::cout << "Bitte geben Sie den Bruch ein: ";
    std::cin >> one;
    std::cout << std::endl;
    std::cout << one;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
07.11.2004, 17:25 Uhr
rejo



Hey 0xdeadbeef! Danke das du so viel Zeit für mich verschwendest hast!

Kleine Frage was machst du da...


C++:
Bruch::Bruch()             : z(0), n(1) { }
Bruch::Bruch(int a, int b) : z(a), n(b) { }
Bruch::Bruch(int a)        : z(a), n(1) { }



Also ich würd gern das wissen was du da machst wenn du ":z(0), n(1) {} machst.
Ich kann mir denken das du z auf Null setzt und n auf 1 aber bin mir halt nicht sicher ^^

Sonst mal ein RIEßEN dankeschön

Frage... wieso kamen da die Fehler... kannst du vielleicht in mein Niveau runtersenken und mir ist halt in meinem Niveau erklären

EDIT: noch ne klitze kleine Frage... wie lang habts ihr eingentlich schon erfahrung... das ihr euch alle so gut auskennt

EDIT 2: Hab } vergessen ^^

Dieser Post wurde am 07.11.2004 um 17:34 Uhr von rejo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
07.11.2004, 21:34 Uhr
typecast
aka loddab
(Operator)


1.) Du hast das richtig verstanden. z wird auf n0 gesetzt und n auf 1

Ich versuch mal den Text von beefy zu erklaeren:


Zitat:

OK, ich hab mal ein bisschen Zeit drauf verschwendet und das ganze so umgeschrieben, dass es läuft. Die Fehler waren im Wesentlichen Verletzung der const-correctness



Was beefy damit sagen will, ist das du rein gar nichts als konstant deklariert hast. Variablen die sich in einer Funktion nicht aendern solltest du als const deklarieren (wobei ich mir nicht sicher bin, ob deswegen Fehler auftreten. Ich habs nicht ausprobiert)


Zitat:

und das Scoping der Operatoren



Das soll heissen, dass du einige Operatoren an der falschen Stelle deklariert hast (bezieht sich hier auf die << und >> operatoren. Die haben im Grunde genommen nichts mit der Klasse zu tun (abgesehen vom >> operator, da dieser ja direkt auf die Daten deiner Klasse zugreifen sollte um diese zu setzen))


Zitat:

- Member-Operatoren haben this implizit als erstes Argument, deswegen ist ein Bruch::operator+(Bruch&, Bruch& ziemlicher Schwachfug. Ansonsten hab ich den operator>> so umgeschrieben, dass er auch sinnvoll aus Dateien lesen kann.



Das hier sollte eigentlich klar sein, aber ich versuchs trotzdem nochmal zu erklaeren:

Du brauchst nicht

C++:
Bruch::operator+(Bruch&, Bruch&);



zu schreiben (im Grunde genommen darfst du das auch nicht), weil dieser Operator Teil der Klasse ist. D.h. das der Linke Operand bei a+b automatisch die Klasse ist, von der der Operator aufgerufen wird.
Du kannst darauf ueber die Variable this zugreifen.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
08.11.2004, 07:55 Uhr
rejo



aha.... verstehe! DANKESCHÖN!!!

noch ne kleine Frage:

Was wen der Benutzer zum Beispiel: 1+ einen Bruchwert rechnet

Ich mein wir haben ja vorhin nur über Bruchwert+Bruchwert geredet was wenn man eine der Summanden auf 1 setzt?

Dieser Post wurde am 08.11.2004 um 08:15 Uhr von rejo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
08.11.2004, 08:52 Uhr
(un)wissender
Niveauwart


Als eigenständige Funktion hinzufügen:


C++:
const Bruch operator+(int value, const Bruch &bruch)
{
    return Bruch(bruch.getNumerator() + value * bruch.getDenominator(),
                     bruch.getDenominator());
}


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 08.11.2004 um 08:57 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
08.11.2004, 10:36 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von 0xdeadbeef:


C++:
istream &operator >>(istream &i, Bruch &b) {
  char c;

  i >> b.z;
  if(i) {
    while((c = i.get()) == ' ');
    if(c == '/')
      i >> b.n;
    else
      b.n = 1;
  } else
    b.n = 1;

  b.kuerzen();

  return i;
}




Das ist IMHO eine Routine mit einer Nach-Mir-Die-Sintflut-Semantik (was ist zB bei einer Eingabe der Form "1+"? - Das + Zeichen würde verschluckt!). Ich würde es eher so machen:

C++:
istream &operator >>(istream &i, Bruch &b) {
  int z, n;
  i >> z; // Besser lokale variablen benutzen, sonst wird b verändert auch wenn Einlesen schiefgeht.
  if(i) {
    char c = i.get();
    // Folgende Anweisung würde ich nicht machen, weil das Überspringen
    // von Leerzeichen per default sowieso gemacht wird; wenn der Benutzer
    // es nicht will, wird er den stream enstprechend einrichten und gute Gründe
    // dafür haben.
    // while((c = i.get()) == ' ');
    if(c != '/') {
       i.unget(); // Zeichen war kein '/' - Gehört damit nicht zum Bruch!
       n = 1;
    }
    else
      i >> n;
    b.setzenUndKuerzen(n,z);
  }
  return i;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 08.11.2004 um 10:40 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: