Entwickler-Ecke

Basistechnologien - Problem mit Array als Objekt


Lord-Maricek - Sa 21.08.10 18:56
Titel: Problem mit Array als Objekt
Hi,

ich bin dabei ein Programm zu schreiben. Dafür schreibe ich gerade eine Klasse, die unterschiedlich oft als Objekt definiert werden muss.
Program

C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vektor_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            object[] vectors = new object[1000000];
            int i = 0;
            bool weiter = true;
            while(weiter){
                Console.WriteLine("Geben Sie x1,y1,x2,y1 ein:");
                double x1 = Convert.ToDouble(Console.ReadLine());
                double y1 = Convert.ToDouble(Console.ReadLine());
                double x2 = Convert.ToDouble(Console.ReadLine());
                double y2 = Convert.ToDouble(Console.ReadLine());
                vectors[i] = new vector(x1,y1,x2,y2);
                Console.Write("Wollen Sie noch einen Punkt eingeben? y/n  ");
                if (Console.ReadLine() == "y")
                {
                    i++;
                }
                else
                {
                    weiter = false;
                }
            }
            Console.WriteLine("{0}", vectors[0].entfernung);
            Console.ReadLine();
        }
    }
}

Klasse:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vektor_Console
{
    class vector
    {
        public double entfernung;
        public vector(double x1, double y1, double x2, double y2)
        {
            this.entfernung = Math.Sqrt(Math.Pow((x2 - x1), 2) + Math.Pow((y2 - y1), 2));
        }
    }
}


Das Problem ist, wenn ich aus dem Array mit dem Index 0 oder anderen Zahlen versuche, auf die Public Variable "entfernung" zu zugreifen, funtzt dass nicht. Habt ihr da vielleicht eine Idee warum das nicht geht?

MfG
Philipp


Trashkid2000 - Sa 21.08.10 21:37

Hallo,

das kommt daher, dass vectors ein object[] ist. Und object kann einfach mal ALLES sein. Also müsstest Du per Cast erst einmal sagen, was denn das Objekt an einen bestimmten Index repräsentiert.
Also wäre es besser, die Objekte in eine typsicheren Struktur zu packen!!

ABER:
An dieser Stelle ein Array zu benutzen, ist nicht gerade toll! Du gibst eine definierte Größe an, bei Dir 1.000.000.
Der Speicher wird für 1 Mio Objekte reserviert! Da Du nie weisst, wie oft denn die Schleife ausgeführt wird (mal wird zu viel Speicher reserviert, oder nach 1 Mio Durchläufen dann OutOfRange, also Absturz ), sollte man hier eine

C#-Quelltext
1:
List<vector>                    
oder ähnliches verwenden. Halt irgendeine Collection. Dann kannst Du die Vektorobjekte bei jedem Durchlauf hinzufügen.

Noch 3 Anmerkungen: Auf jeden Fall noch Fehlerbehandlung (Du weisst nie, was der Nutzer eingibt), Namenskonventionen einhalten, und sowas wie

C#-Quelltext
1:
public double entfernung;                    
schnell vergessen! Dafür entweder Getter/Setter-Methoden oder Propertys verwenden.
Nicht böse gemeint!

LG, Marko


Lord-Maricek - Sa 21.08.10 21:53

Ok, danke,
ich probiere das mal mit List.
Es wird später selbstverständlich noch Fehlerbehandlung dazu kommen, aber das ist erstmal nur ein kleiner Teil, einer größeren Software. Ich schreibe mir die Software immer in einzelnen Elementen, und wenn die alle funktionieren, setzte ich alles zusammen.

MfG
Philipp


Trashkid2000 - Sa 21.08.10 22:11

Ups, muss mal noch was richtig stelen.
Bei einem Array wird nicht Speicher für die Objekte darin reserviert, sondern nur für die Zeiger auf die Objekte. Was aber nichts daran ändert, dass bei Deinem Beispiel bei 1 Mio Schluss wäre.

LG, Marko


Lord-Maricek - So 22.08.10 09:10

Hi,

mit List kenne ich mich noch nicht aus, ich habe ein bisschen bei Google geguckt, aber so ganz klar wird mir das auch nicht. Kann es sein, dass man, wenn man etwas in die Liste hinzugefügt hat, nicht auf die einzelnen Elemente zugreifen kann wie bei Arrays?
Es wird am ende auch so laufen, dass ich eine Textdatei einlesen werde, und je nach ihrer Länge wird dann die Array Länge festgelegt.
Ich habe ein bisschen weiter programmiert, aber jetzt bekomme ich immer NullReferenceExeption an mehreren Stellen.
Programm:

C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vektor_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            vector[] vectors = new vector[100000000];
            int i = 0;
            bool weiter = true;
            while(weiter){
                Console.WriteLine("Geben Sie x1,y1,x2,y1 ein:");
                double x1 = Convert.ToDouble(Console.ReadLine());
                double y1 = Convert.ToDouble(Console.ReadLine());
                double x2 = Convert.ToDouble(Console.ReadLine());
                double y2 = Convert.ToDouble(Console.ReadLine());
                vectors[i] = new vector(x1,y1,x2,y2);
                Console.Write("Wollen Sie noch einen Punkt eingeben? y/n  ");
                if (Console.ReadLine() == "y")
                {
                    i++;
                }
                else
                {
                    weiter = false;
                }
            }
            for (int e = 0; e <= i; e++)
            {
                Console.WriteLine("Entfernung für Eingabe {0}: {1}\nAnzahl der Punkte ist: {2}\nFaktor: {3}\n Punkte:", e, vectors[e].entfernung, vectors[e].punkte, vectors[e].factor);   //NullReferenceExeption
                for (i = 0; i < vectors[e].punkte; i++)
                {
                    Console.WriteLine("X: {0}, Y: {1}", vectors[e].points[0][i], vectors[e].points[1][i]);    //NullReferenceExeption
                }
            }
            Console.ReadLine();
        }
    }
}


Klasse:

C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Vektor_Console
{
    class vector
    {
        public double entfernung,factor, punkte;
        public double[][] points = new double[2][];
        public vector(double x1, double y1, double x2, double y2)
        {
            this.entfernung = Math.Sqrt(Math.Pow((x2 - x1), 2) + Math.Pow((y2 - y1), 2));
            this.punkte = this.entfernung * 100.0;
            this.factor = 1.0 / this.punkte;
            double a_factor = this.factor;
            int i=0;
            while (a_factor <= 1.0)
            {
                this.points[0][i] = x1 + a_factor * (x2 - x1);      //NullReferenceExeption
                this.points[1][i] = y1 + a_factor * (y2 - y1);      //NullReferenceExeption
                a_factor += this.factor;
                i++;
            }
        }
    }
}


Ich habe schon raus gefunden, dass ich in der Klasse Programm noch irgendwas mit dem Array Double machen muss, aber ich weiß nicht was.

Könnt ihr mir bitte nochmal helfen?

MfG
Philipp


Th69 - So 22.08.10 10:15

Doch auch bei einer List<> kann man ganz normal mittels [] auf einzelnen Element zugreifen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
List<int> list = new List<int>();

for(int i=0; i<10; i++)
  list.Add(i);

for(int i=0; i<list.Count; i++)
{
  int value = list[i]; // Indexzugriff wie beim Array
}

// oder alternativ mittels foreach
foreach(int i in list)
{
  int value = i;
}


Du verwendest jedoch bei dir auch mehrdimensionale Arrays (double[][] points), und diesen mußt du erst einzeln Speicher zuweisen (daher die NullreferenceException).
Verwende auch hier am besten eine generische Liste (List<double>) bzw. zwei (je eines für x und y).


Lord-Maricek - So 22.08.10 13:27

Ok, danke jetzt läuft fast alles.
Ich versuche jetzt die Koordinaten zu errechnen, dazu errechne ich mit den Faktor "t" (so steht er zumindest in meinem Mathebuch, für Vektorrechnung).
Nachdem ein Punkt errechnet wird, wird der Faktor nochmal zum Aktuellen Faktor dazu gerechnet, aber das funtzt nicht.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
double a_factor = this.factor;
            for(int i=0;i<this.punkte;i++)
            {
                //this.points[0][i] = x1 + a_factor * (x2 - x1);      //NullReferenceExeption
                //this.points[1][i] = y1 + a_factor * (y2 - y1);      //NullReferenceExeption
                this.x_axis.Add(x1 + a_factor * (x2 - x1));
                this.y_axis.Add(y1 + a_factor * (y2 - y1));
                this.factor_.Add(a_factor);
                a_factor += this.factor;
            }

a_factor ist der Aktuelle Faktor, für den nächsten Durchlauf.

Das hier ist ein Auszug, aus der Ausgabe:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
I: 271  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 272  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 273  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 274  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 275  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 276  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 277  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 278  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 279  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 280  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 281  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364
I: 282  X: 0,00706713780918728, Y: 0,00706713780918728
 Factor: 0,00353356890459364


Da kann man sehen, dass sich der Faktor nicht erhöht, das müsste er aber machen.

MfG
Philipp


Kha - So 22.08.10 14:20

Bist du schon einmal mit dem Debugger durchgesteppt? Da kann ja eigentlich nicht viel schiefgehen, ich würde den Fehler an anderer Stelle vermuten.