Doppel Pointer / Pointer in Funktion ändernq



  • Hallo ,

    ich habe ein ziemlich schlechtes Programm geschrieben( Entstand zu Übungszwecken), indem eine Liste in ein Array of Struct geschrieben wird.

    Es gibt die Funktion add, die einen Pointer auf das "aktuelle" Element erhält, dieses füllt und dann den Pointer erhöht und zurück gibt.

    Ca so: (DATA ist die STruct als Typedef, enthält Chars, int´s undn double)

    DATA* add(DATA* act_pos, int MAX){
    
    // füllen
    // act_pos++  wäre nach verlassen der Funktion "hinfällig", act_pos nur eine Kopie??
    return ++act_pos // so funktioniert die Rückgabe
    }
    

    Das geht soweit, ziemlich unelegant aber ich hoffe das mein Kommentar stimmt und nicht nur zufall ist.

    Dann gibt es noch die funktion Delete, und da happert es irgendwie:

    void del(DATA teile[10], **act_pos){
    
    // bla bla, abfrage welches teil gelöscht wird usw, 
    for(del_teil=auswahl; del_teil<MAX; del_teil++){
        teile[del_teil]=teile[del_teil+1];
    // ist nicht der Originalcode, nur um das Prinzip darzulegen... Es wird einfach "nachgerückt"
    // für die funktion "show" wird dann wieder die aktuelle position benötigt
    => somit möchte ich hier act_pos um "1" zurücknehmen
    act_pos--   // DAS FUNKTIONIERT ÜBERHAUPT NICHT
    

    Wenn ich einen Doppelpointer übergebe, also einen Zeiger auf einen ZEiger, kann ich doch in der Funktion den Originalzeiger ändern oder sehe ich das Falsch??

    main.c:

    DATA xy[10];
    DATA *sp, *start;
    
    start=sp=xy;
    
    while(irgendwas){
    sp=add(sp, 10)
    }
    
    del(xy, &sp);
    

    Ich kann es schon mit einen einfachen Pointer in del lösen, und "return act_pos" machen. Aber eigentlich will ich mit der Funktion mal return TRUE / FALSE machen.
    Ich dache mit dem Ansatz Doppelpointer wäre ich richtig??

    Ist alles etwas verwirrend, evtl. nimmt sich jmd. mal kurz die Zeit?
    Den Originalcode habe ich leider nicht mehr zur Hand...



  • #include <stdio.h>
    
    void add( int **pos, int value )
    {
    	**pos = value;
    	(*pos)++;
    }
    
    void del( int *data, size_t del_pos, int **pos )
    {
    	for( data += del_pos; data + 1 != *pos; ++data )
    		*data = data[ 1 ];
    
    	(*pos)--;
    }
    
    void show( int *data, int *pos )
    {
    	puts( "show():" );
    	for( ; data != pos; ++data )
    		printf( "%p: %d\n", data, *data );
    }
    
    int main( void )
    {
    	int data[ 10 ] = { 0 };
    	int *pos = data;
    
    	add( &pos, 1 );
    	show( data, pos );
    
    	add( &pos, 2 );
    	add( &pos, 3 );
    	add( &pos, 4 );
    	show( data, pos );
    
    	del( data, 1, &pos );
    	show( data, pos );
    
    	del( data, 2, &pos );
    	show( data, pos );
    }
    

    Daß das Grundsätzlich fürchterlich ist, ist dir eh klar, gell?



  • Daß das Grundsätzlich fürchterlich ist, ist dir eh klar, gell?

    Ja, das ganze stinkt zum Himmel. Das Grundkonzept , dafür ein Array zu nehmen und dann nicht mit INdex zu arbeiten ist Mist.
    Wäre eine einfach verkettete Liste für sowas nicht besser geeignet?

    void del( int *data, size_t del_pos, int **pos )
    {
        for( data += del_pos; data + 1 != *pos; ++data )
            *data = data[ 1 ];
    
        (*pos)--;
    }
    

    ** => Wert des Zeigers
    * => "Originalzeiger" ?
    (*pos)--; Originazeiger bearbeiten, ok // Hatte ich als erstes gemacht, aber die Klammer weggelassen...
    pos-- ; => was macht dann das?



  • Hab den Originalcode nochmal gefunden.

    WAHH.. ich habe (ptr)-- geschrieben. Die sch... Klammerei bei den 2....

    Gibt´s da nicht ne Eselsbrücke oder ne "bessere " Erklärung?



  • db_pointer schrieb:

    Gibt´s da nicht ne Eselsbrücke oder ne "bessere " Erklärung?

    Du willst zuerst ptr dereferenzieren um danach seinen Pointee zu inkrementieren.



  • Danke erstmal, muss mir das besser merken.

    Noch ne frage... was würde ptr-- machen?



  • int foo;
    int * ptr = &foo;
    int ** ptrptr;
    
    ptrptr--; // ptrptr zeigt danach auf einen int* "vor" ptr ...
    

    Der Speicher gehört dir aber nicht.



  • besten Dank, ich glauch so trichter ich es mir ein.

    Wäre eine verkettete Liste ein sinnvolle Lösung für eine solche Aufgabe, oder spricht es aus der Praxis eher für etwas anders?



  • db_pointer schrieb:

    Wäre eine verkettete Liste ein sinnvolle Lösung für eine solche Aufgabe, oder spricht es aus der Praxis eher für etwas anders?

    Die Parxis spricht zu 99% zu einem Array, das wachsen kann. (in C++ std::vector).

    Fast nie zu einer verketten Liste.

    Dann eher noch zu einer Mischform, sagen wir mal 4096-Byte-große Happen werden verkettet, innerhalb der Happen wird wie im Array gewachsen, immer erst wenn ein Happen voll ist, wird eine neuer Happen gemalloct und reinverkettet. (std::deque ider der anderen Sprache halt).



  • Die Parxis spricht zu 99% zu einem Array, das wachsen kann. (in C++ std::vector).

    => Wäre da in C das stichwort dynamisches Array mit malloc / realloc oder?

    Gibt´s überhaupt praktische Anwendungen für verkettete Listen?
    Wie schauts mit den binären Bäumen aus... ??



  • db_pointer schrieb:

    Gibt´s überhaupt praktische Anwendungen für verkettete Listen?

    Hashtables, zum Behandeln von Kollissionen
    Free List bei Memory Management
    FAT Dateisystem besteht aus LLs
    "Arrays", bei denen du mitten drin etwas einfügen oder löschen können willst, ohne die Elemente aufrücken zu lassen


  • Mod

    db_pointer schrieb:

    Wie schauts mit den binären Bäumen aus... ??

    Die (und viele andere baumartige Strukturen) haben haufenweise praxisrelevante Anwendungen.


Anmelden zum Antworten