Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Addieren 2er Complexer Zahlen in C# » Antwort erstellen » Hallo Gast [Anmelden|Registrieren]

Antwort erstellen
Benutzername: (du bist nicht eingeloggt!)
Thema:
Nachricht:

HTML ist nicht erlaubt
BBCode ist erlaubt
Smilies sind erlaubt
Bilder sind erlaubt

Smilies: 21 von 33
smileWinkDaumen hoch
verwirrtAugenzwinkerngeschockt
Mit ZungeGottunglücklich
Forum Kloppebösegroßes Grinsen
TanzentraurigProst
TeufelSpamWillkommen
LehrerLOL HammerZunge raus
Hilfe 
aktuellen Tag schließen
alle Tags schließen
fettgedruckter Textkursiver Textunterstrichener Text zentrierter Text Hyperlink einfügenE-Mail-Adresse einfügenBild einfügen Zitat einfügenListe erstellen CODE einfügenPHP CODE farbig hervorheben
Spamschutz:
Text aus Bild eingeben
Spamschutz

Die letzten 10 Beiträge
eulerscheZahl

Über den Stil lässt sich natürlich streiten, mein Programmierbuch rät auch dazu, this immer zu verwenden, Microsoft selbst verzichtet darauf.
Wenn ich aber so darüber nachdenke, gebe ich dir Recht mit der besseren Lesbarkeit, werde mich künftig daran halten.
Airblader

Zitat:
Außerdem ist genau das der Grund, überhaupt this zu schreiben: um das an die Funktion übergebene "re" von dem in der Klasse unterscheiden zu können.


Da möchte ich nicht ganz zustimmen. Ich halte ein "this" immer für sinnvoll, auch wenn es nicht um diese Unterscheidung geht. Und zwar ganz einfach darum, dass man einer Variable sofort ansieht ob sie zur Klasse gehört oder nicht. Die einzige Ausnahme bilden Konstanten, die sich schon dadurch kennzeichnen, dass sie (jedenfalls typischerweise) versal geschrieben sind.

Einige IDEs heben Klassenvariablen natürlich farblich sowieso hervor. Aber Lesbarkeit sollte nicht von der IDE-Einstellung abhängen. Und mal ein "this" zu setzen und mal nicht finde ich auch schlicht inkosistent.
eulerscheZahl

Zitat:
wenn ich [...] c1.Add3(c2); aufrufe,
wird quasi mein c2 für die Zeit der Methodendurchführung einfach nur "ctmp" genannt? es ist also exakt das selbe... (also nicht Kopie, sondern nur "namensänderung")?????
und deswegen ändere ich auch mein c2 (was ja eigentlich nicht soll)

Genau. Es wird nicht wirklich die Variable übergeben, sondern nur die Information, wo im Arbeitsspeicher die Variable zu finden ist.
Das gilt übrigens nicht nur für Klassen, sondern auch für Arrays.
Bei einer struct wird der komplette Inhalt kopiert, wie du es von int, double, ... kennst.
Der Vorteil: bei großen Datensammlungen in einer Klasse würde das Kopieren des Speicherinhalts recht lange dauern.
Mit ref kann erzwungen werden, dass z.B. auch bei int die Adresse übergeben wird, nicht der Inhalt.

Zitat:
Wenn ich sowas habe wie:
c1=c1.Add3(c2.Add3(c3));
Dann führt der das doch von rechts nach links aus oder?
Also al erstes macht er c2.Add3(c3)????

Ja, bzw. von innen nach außen.


Edit: habe mir dein Programm mal näher angesehen, das Init() ist so nicht sauber (mal abgesehen davon, dass unnötig, wie schon erwähnt wurde):
Dein Code
code:
1:
2:
3:
4:
5:
        public void Init(float wert1, float wert2)
        {
            this.re = wert1;
            this.im = wert2;
        }

besser:
code:
1:
2:
3:
4:
5:
        public void Init(float re, float im)
        {
            this.re = re;
            this.im = im;
        }

Vorteil: wenn du die Methode aufrufen willst, zeigt dir z.B. Visual Studio als Hilfe die zu übergebenden Parameter an (siehe Bild), hier ist wert1 nicht wirklich aussagekräftig.
Außerdem ist genau das der Grund, überhaupt this zu schreiben: um das an die Funktion übergebene "re" von dem in der Klasse unterscheiden zu können.

eulerscheZahl hat dieses Bild (verkleinerte Version) angehängt:
IntelliSense.png

Matze84

Hallo ihr beiden... heute schaffe ich es mal wieder mich damit zu beschäftigen unglücklich

@Karlito:
nochmal zum Verständnis:

wenn ich also

public Complex Add3(Complex ctmp){}

habe und dann als Bsp.

c1.Add3(c2); aufrufe,
wird quasi mein c2 für die Zeit der Methodendurchführung einfach nur "ctmp" genannt? es ist also exakt das selbe... (also nicht Kopie, sondern nur "namensänderung")?????
und deswegen ändere ich auch mein c2 (was ja eigentlich nicht soll)
ok.


Wegen dem Init.... ja das ist leider so vorgegeben, würde das auch lieber mit

Complex c1 = new Complex(1,2) oder so lösen....
müsste man sich halt nur den Konstruktor schreiben, was aber nicht das Problem sein sollte...

Zum Thema schlechter Stil: Der Prof macht das dieses Jahr sowieso merkwürdig, weil er uns ein Beispiel zeigt, und dann erklärt warum das nicht geht (sprich er zeigt quasi als erstes Beispiel, wie es falsch ist unglücklich )
Aber ok da müssen wir durch.

Eine Frage nebenbei noch....

Wenn ich sowas habe wie:
c1=c1.Add3(c2.Add3(c3));
Dann führt der das doch von rechts nach links aus oder?
Also al erstes macht er c2.Add3(c3)????

Lg matze
Airblader

Leider wurde ihm auch das von der Aufgabenstellung vorgegeben. Recht hast du allerdings schon.
Karlito

Hallo,

dein Problem ist, dass Du nicht beachtest, dass von Objekten immer nur Referenzen übergeben werden. D.h. Add3 hat ja einen Parameter vom Typ Complex, wobei als Parameter dann eine Referenz auf ein Objekt vom Typ Complex übergeben wird. D.h. du arbeitest nicht mit einer Kopie sondern mit dem selben Objekt.
Die Lösung besteht darin, für die Rückgabe ein neues Objekt zu erzeugen und dieses zurückzugeben (bzw. dessen Referenz).

Also:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public Complex Add3(Complex ctmp)
{
  Complex result = new Complex();
  result.init(0,0);
  result.re = ctmp.re + this.re;
  result.im = ctmp.im += this.im;
  return result;
}


Btw.: Dass Du den Wert des Objekts erst mit der init-Methode festlegst ist schlechter Stil! Für die initiale Belegung eine Objektes ist der Konstruktor vorgesehen. Das ist übrigens ein oft vorkommendes Verständnisproblem. Viele Anfänger denken, dass der Kontruktor das Objekt konstruiert, dabei handelt es sich eigentlich nur um eine Methode, welche den initialen Zustand (die Belegung der internen Variablen) des Objektes herstellt.

VG,

Karlito
Matze84

Ok soweit so gut... wieder eine Frage smile
Bisher habe ich folgendes geschrieben....
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Complex
    {
        private float re = 0.0F;
        private float im = 0.0F;

        public void Init(float wert1, float wert2)
        {
            this.re = wert1;
            this.im = wert2;
        }
        public void Print()
        {
            Console.WriteLine("({0}--{1})", this.re, this.im);
        }
        public void Add1(Complex ctmp)
        {
            this.re += ctmp.re;
            this.im += ctmp.im;
        }
        public Complex Add2(Complex ctmp)
        {
            this.re += ctmp.re;
            this.im += ctmp.im;
            return this;
        }
        public Complex Add3(Complex ctmp)
        {
            ctmp.re += this.re;
            ctmp.im += this.im;
            return ctmp;
        }
        public Complex Add4(params Complex[] complexestmp)
        { 
            Complex ctmp = new Complex();
            ctmp.re = 0; ctmp.im = 0;
            int count = complexestmp.Length;
            for (int i = 0; i < count; i++)
            {
                ctmp.re += complexestmp[i].re;
                ctmp.im += complexestmp[i].im;
            }
            return ctmp;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Complex c1 = new Complex();
            Complex c2 = new Complex();
            Complex c3 = new Complex();
            c1.Init(1, 2);
            c2.Init(3, 4);
            c3.Init(5, 6);
            c1.Add1(c2);
            c1.Print();
            c1.Init(1, 2);
            c1.Add2(c2).Add2(c3);
            c1.Print();
            c1.Init(1, 2);
            c1 = c1.Add3(c2.Add3(c3));
            c1.Print();
            c1 = c1.Add4(c2, c3, c1, c2);
            c1.Print();
            Console.ReadLine();
        }
    }
}


Ich habe den Fehler erst jetzt bemerkt, aber es geht um meine "Add3" Methode...

In zeile 70 ändert er mir nämlich die Werte von "c3"
das soll er aber (gemäß aufgabenstellung) nicht.
was mache ich da falsch?

JA Add2 und Add3 sind sich gewissermaßen identisch....
Aber mit Add3 kommt das raus, was rauskommen soll... nur durch die Veränderung an "c3" wird mein Ergebnis bei Add4 falsch....

Irgendwas übersehe ich nur weiß ich nicht was.

Wie gesagt die Methoden (und wie ich sie benutzen soll) in der main sind mir vorgegeben.
Matze84

Zitat:
Original von Karlito
Hallo,

kurzer Einwurf: In C# kann man Operatoren überladen. ...........

VG,

Karlito


Das hatten wir gestern in der Vorlesung....
Ist für mich immer erstmal verwirrend, bis ichs dann an einer Übungsaufgabe testen/probieren konnte smile

Weil selber fallen mir immer nicht solche Aufgaben ein, das ich das mal so üben könnte unglücklich
Airblader

Ich finde das Überladen an dieser Stelle auch deutlich schöner. Wie es der Zufall will, schreibe ich derzeit privat eine JavaScript-Bibliothek, bei der es auch um das Addieren (und andere Rechenoperationen) geht. JavaScript kann sowas leider nicht, weshalb mir "nur" das Chaining bleibt.
Karlito

Achso, entschuldigung. Das habe ich nicht gelesen. Als Zusatzinfo sicher trotzdem eine interessante Alternative.

VG,

Karlito
Es sind weitere Beiträge zu diesem Thema vorhanden. Klicken Sie hier, um sich alle Beiträge anzusehen.