Erklärung eines kleinen Codebeispiels...



  • Also ich habe hier ein kleines Programm und komme da aber nicht so 100% dahinter warum weshalb wieso.
    Währe schön wenn mir das einer mal kurz erläutern könnte...

    void up( int* f)
    {
    
    	int i;
    	int Feld2[10] = {11,12,13,14,15};
    
    	f = Feld2;
    
    	for (i=0;i<5;i++) printf ("\n %d", f[i]);
    
    }
    
    int main()
    {
    	int Feld1[12] = {0,1,2,3,4,5,6,7,8,9,10};
    	int i;
    
    	*(Feld1+6)=100; 
    	up(Feld1);
    
    	printf("\n----------------------------------\n\n");
    
    	for (i = 0; i < 12; i++) printf("\n %d", Feld1[i]);
    
    	return 1;
    
    }
    

    Und zwar geht es in meinen Kopf einfach nicht rein, wenn ich in der Funktion main die Funktion up aufrufe übergebe ich ja eigentlich einen Pointer (?), Feld1 ( was ein Array ist ).
    Durch die Funktion up gibt dann mein übergebener Parameter den Inhalt des Array's Feld2 aus.
    Eine Zeile später in der Funktion main hat aber das Array Feld1 immer noch seine Werte obwohl ich doch ihm in der Funktion up das Array Feld2 zugewiesen habe????

    mfg rendner



  • Du hast dem Pointer f, der lokal in der Funktion ist (also nachher verschwindet und v.a. keine irgendwie geartete Beziehung zu Feld1 aus main hat) die Adresse von Feld2 zugewiesen.



  • Aber f ist doch nicht lokal in der Funktion ( zumindest nach meinen bedürftigen C-Kenntnissen )es ist doch nur als definition des Parameters genutzt, und ich übergebe doch Feld1 als Parameter somit ist der Parameter f ja Feld1 und diesem wird die Adresse von Feld2 zugewiesen.

    Oder habe ich dich jetzt falsch verstanden?
    Kann das eventuell einer etwas idiotensicher erklären?

    mfg rendner



  • f ist ein Pointer. Vor der Zuweisung zeigt er auf Feld1. Nach der Zuweisung zeigt er auf Feld2. Am Ende der Funktion wird er zerstört. An Feld1 oder Feld2 ändert sich dadurch gar nichts.



  • Ah ich glaube es dämmert etwas...
    Liegt es vielleicht daran, das ein Array ja zu den komplexen Datentypen gehört und ich quasi nur ne Referenz der Funktion übergebe aber nicht das Array selber?

    Und in der Funktion bekommt dann der pointer f eine Referenz auf Feld2.

    Habe ich das einigermassen richtig interpretiert?
    Vielen Dank schonmal, alleine hätte ich da bestimmt noch ne Woche gerätselt warum das so ist wie es ist.

    mfg rendner



  • Ja, ich glaube das dämmert dir richtig 😉

    EDIT: Ob das Array nun etwas komplexes ist oder nicht, ist eigentlich egal. Wichtig ist, dass hier ein Pointer zugewiesen wird, weil f einfach ein Pointer ist. Arrays kopieren kannst du nie mit einer einfachen Zuweisung.



  • Dann bedanke ich mich für deine Hilfe und wünsche dir noch nen schönen Abend... 🙂

    mfg rendner



  • Was muss ich denn machen, um den Inhalt des Übergeben Arrays zu ändern?

    Ich will eine Getter-Methode für eine Klasse schreiben, welche ein Feld zurückliefert:

    class MeineKlasse
      private:
        int einFeld[3];
      public:
        int* getFeld(){return einFeld;};
    end;
    

    wenn ich dann aber sowas mache kommt ein Fehler:

    aIntFeld = Instanz.getFeld();

    ich habs auch schon damit veruscht:
    aIntFeld = ( (int[])Instanz.getFeld() );
    Das is wohl laut ANSI standard vrboten.

    Wie liefere ich den Inhalt eines Feldes zurück?



  • DerAnfänger2005 schrieb:

    Wie liefere ich den Inhalt eines Feldes zurück?

    Am besten so (Deklaration deiner Methode):

    getFeld(int * p_Feld);
    

    Du musst dann nur noch den Inhalt deiner Eigenschaft einFeld nach p_Feld kopieren.

    Da du aber hier C++ verwendest (mal davon abgesehen, dass du dazu im falschen Forum bist), warum verwendest du dann nicht die Standard-Container-Klassen von C++? Wie z. B. vector<>.



  • hmmm... Das hatte ich auch schon probiert. Gab auch was zurück...nur halt nicht das richtige...

    Wie muss ich den in der Funktion die Parameter an den Pointer übergeben? Vielleicht ist da mein Fehler.

    Ich hab bisher immer sowas gemacht:

    getFeld(int * p_Feld)
    {
      p_Feld = einFeld;
    }
    

    Ist das richtig so?

    PS: Ich will mit OpenGL arbeiten. Dafür brauch ich Arrays.



  • Nein so ist es nicht richtig, denn damit weißt du ja nur die Adresse von einFeld auf den lokalen Pointer p_Feld zu.

    Du musst wie gesagt, den Inhalt von einFeld an die Adresse, auf die p_Feld zeigt, kopieren:

    //zum Beispiel mit memcpy()
    memcpy(p_Feld, einFeld, sizeof(int) * 3); //sizeof(int) * 3 ist die Speichergröße in Byte, die dein Array einFeld belegt
    


  • 😮 So krass!?

    Geht das nur in ANSI C so kompliziert, oder ist das in C++ noch genauso?

    Also, ich sag mal ein Feld zurückliefern ist doch so grundlegend, dass es ohne externen Funktionsaufruf (memcpy) gehen muss.... 🙄



  • Du könntest bei deiner Variante natürlich auch casten:

    class MeineKlasse
      private:
        int einFeld[3];
      public:
        const int * getFeld() const {return (const int *)einFeld;};
    end;
    

    Das Casten ist aber immer mit Vorsicht zu genießen. Da sollte man schon wissen was man tut.

    Btw hab ich deinen Rückgabewert auch noch Konstant gemacht.

    Für dein eigentliches Problem könnte man auch noch anders vorgehen:
    Speichere deine Daten z. B. in einem vector<> und setze diesen um in ein Array, kurz bevor du die OpenGL-Funktion(en) nutzt, die das Array brauchen.

    Aber das hängt ganz davon ab wieviel du in deinem Code mit den Arrays machst und wie oft du OpenGL-Funktionen aufrufst, die das Array brauchen. Wenn es viele Aufrufe mit dem Array gibt, dann lass es so wie es ist.



  • Hmmm...soganz geht das auch net:

    class MeineKlasse
      private:
        int einFeld[3];
      public:
        int * getFeld() {return (int *)einFeld;};
    end;
    

    Irgendwann später:

    int color[3];
    
    color = ( (int[])EineInstanz->getFeld() ); //Hier Fehler!
    

    Und zwar sagt er:
    -error: ISO C++ forbids casting to an array type 'int[]'
    -error: incompatible types in assignement of 'int*' to 'int[3]'

    Das Leben ist so ungerecht....Es könnte alles soooo einfach sein 😞



  • Mir persönlich gefällt die gecastete Methode besser...nur wie gesagt gehts so net... Habt dz/ihr noch Ideen?



  • DerAnfänger2005 schrieb:

    Mir persönlich gefällt die gecastete Methode besser...nur wie gesagt gehts so net... Habt dz/ihr noch Ideen?

    Ja, so gehts nicht. Die Deklaration und Definition deiner Methode ist richtig, aber deine Verwendung und Zuweisung nicht.

    DerAnfänger2005 schrieb:

    Irgendwann später:

    int color[3];
    
    color = ( (int[])EineInstanz->getFeld() ); //Hier Fehler!
    

    Und zwar sagt er:
    -error: ISO C++ forbids casting to an array type 'int[]'
    -error: incompatible types in assignement of 'int*' to 'int[3]'

    Da meckert er natürlich rum!
    Wenn du deine Werte in das Array color[] kopieren willst, dann musst du meine erste Variante mit dem Parameter (ohne cast) verwenden. Wenn du es mit Zeiger und cast machen willst, dann muss das ganze so aussehen:

    int * color;
    ...
    color = EineInstanz->getFeld();
    

    DerAnfänger2005 schrieb:

    Das Leben ist so ungerecht....Es könnte alles soooo einfach sein 😞

    Du sagst es... (manchmal ist es aber auch einfacher als man denkt ;))



  • Wenn du deine Werte in das Array color[] kopieren willst, dann musst du meine erste Variante mit dem Parameter (ohne cast) verwenden.

    Also die memcpy() Sache... hmmm

    Wenns denn unbedingt sein muss... (In Delphi geht sowas irgendwie...flüssiger 😉 )



  • Du kannst es aber auch mit int * color probieren. Wäre auf jeden Fall weniger Speicherintensiv (wobei das bei 3 Elementen noch relativ egal ist).



  • Ich sollte vielleicht noch erwähnen, dass das Color beschaffen relativ zeitkritisch ist.

    Wenn ich 100 OpenGL Objekte habe und für jedes die Farbe hohlen muss, wärs schon schön, wenns flott ginge. Wie schnell ist den memcpy in dieser Hinsicht?



  • AJ schrieb:

    Du kannst es aber auch mit int * color probieren. Wäre auf jeden Fall weniger Speicherintensiv (wobei das bei 3 Elementen noch relativ egal ist).

    Hmmm...eigentlich könnte das funktionieren... Man kann halt nur nicht so konfortabel auf die Elemente zugreifen...



  • DerAnfänger2005 schrieb:

    AJ schrieb:

    Du kannst es aber auch mit int * color probieren. Wäre auf jeden Fall weniger Speicherintensiv (wobei das bei 3 Elementen noch relativ egal ist).

    Hmmm...eigentlich könnte das funktionieren... Man kann halt nur nicht so konfortabel auf die Elemente zugreifen...

    Sicher? 😃

    Probiers hald mal aus:

    ...
    int arr[3] = { 1, 3, 5 };
    int * ptr = arr;
    
    printf("%i = %i", arr[1], ptr[1]); // oder cout << arr[1] << " = " << ptr[1];
    ...
    

    DerAnfänger2005 schrieb:

    Ich sollte vielleicht noch erwähnen, dass das Color beschaffen relativ zeitkritisch ist.

    Wenn ich 100 OpenGL Objekte habe und für jedes die Farbe hohlen muss, wärs schon schön, wenns flott ginge. Wie schnell ist den memcpy in dieser Hinsicht?

    Wenn es zeitkritisch ist, dann solltest du so wenig wie möglich kopieren. memcpy() dürfte eine der schnellsten Varianten sein etwas von einem Speicherbereich zum anderen zu kopieren.


Anmelden zum Antworten