Übergeben von Zeigern an Funktionen

Dieses Thema im Forum "C/C++" wurde erstellt von NaRF, 11.04.2005.

  1. NaRF

    NaRF Hatifschnacke

    Dabei seit:
    15.05.2003
    Beiträge:
    105
    Zustimmungen:
    0
    Ort:
    Friedberg (Hessen)
    hi,
    ich starre schon ewigkeiten auf ein paar programmzeilen aus dem informatikunterricht, was mich bis jetzt aber noch nicht dazu befähigt hat, sie zu verstehen :).
    das programm erstellt einen binärbaum. daten werden eingelesen und dann alphabetisch in eine baumstruktur geschrieben. jedes baum struct enthält einen "infocontainer" (speichert ein char) und 2 zeiger auf die zweige rechts und links von ihm.

    ein baum mit dem inhalt unixboard sieht dann z.b. so aus:

    Code:
           |---> x
     |---> u
                       |---> r
                 |---> o
           |---> n
                 |---> i
                             |---> d
                       |---> b
                             |---> a

    hier erstmal das programm:
    Code:
    # include <iostream>
    	//# include <conio.h>
    	# include <string>
    	
    	using namespace std;
    
    	struct BaumTyp {char info; BaumTyp *re, *li;};
    
    // --------------------------------------------
    	[B]void einfuegen (BaumTyp* &Baum, char Daten)[/B]
    // --------------------------------------------
     {
    	if (Baum == NULL)
    	  {
            Baum = new BaumTyp;
    	    Baum->info = Daten;
       	    Baum->li = NULL;
            Baum->re = NULL;
    	  }
    	else einfuegen (Daten < Baum->info ? Baum->li : Baum->re, Daten);
     }
    
    // ---------------------------------- 
    	void zeige (BaumTyp *Baum, int h)
    // ----------------------------------
     {
    	int i;
    
    	if (Baum != NULL)
    	  {
    	    zeige (Baum->re, h+1);
    	    for (i=1; i<=h; i++) cout << "      ";
    	    cout << " |---> " << Baum->info << endl;
    	    zeige (Baum->li, h+1);
    	  }
     }
    
    // -----------------------------------
    	void LWR_Durchlauf (BaumTyp *Baum)
    // -----------------------------------
     {
    	if (Baum != NULL)
    	  {
    	    LWR_Durchlauf (Baum->li);
    	    cout << Baum->info << " ";
       	    LWR_Durchlauf (Baum->re);
    	  }
     }
    
    // -----------------------------------------------------
    	void rechtsaussen_anhaengen (BaumTyp *a, BaumTyp *z)
    // -----------------------------------------------------
     {
    	if (a->re == NULL) a->re = z;
    	else rechtsaussen_anhaengen (a->re, z);
     }
    
    // ----------------------------
    	void loeschen (BaumTyp* &z)
    // ----------------------------
     {
    	static BaumTyp *h;
    
    	h = z;
    	if (z != NULL)
    	  {
    	    if (z->li == NULL) z = z->re;
    	    else
    	      {
    	        rechtsaussen_anhaengen (z->li, z->re);
    		    z = z->li;
    	      }
            delete h;
    	  }
     }
    
    // -----------------------------------------------
    	void suchen_und_loeschen (BaumTyp* &a, char x)
    // -----------------------------------------------
     {
    	if (a != NULL) if (a->info == x) loeschen (a);
    		           else if (a->info > x) suchen_und_loeschen (a->li, x);
    				        else suchen_und_loeschen (a->re, x);
     }
    
    // ------------
        int main ()
    // ------------
     {
    	[B]BaumTyp *Baum;[/B]
    	char Eingabe[20], Zeichen;
    	int k, L;
    
    	Baum = NULL;
    	cout << "Gib eine Zeichenkette ein: ";
    	cin >> Eingabe;
    	L = strlen (Eingabe);
    	for (k=0; k<L; k++) einfuegen (Baum, Eingabe[k]);
    	cout << endl;
    	zeige (Baum, 0);
    	cout << endl;
    	LWR_Durchlauf (Baum);
    	cout << "\n\nWelches zeichen soll geloescht werden: ";
    	cin >> Zeichen;
    	suchen_und_loeschen (Baum, Zeichen);
    	cout << endl;
    	zeige (Baum, 0);
    	cout << endl;
    	LWR_Durchlauf (Baum);
    	
    	getchar();
    	return 0;
     }
    verständnisprobleme habe ich in der oberen fettgedruckten zeile. ich übergebe der funktion doch einen zeiger auf eine variable des typs BaumTyp (siehe untere fettgedruckte zeile). was hat dann das "&" in der oberen zeile, das mir afaik die adresse vom zeiger liefert, dort verloren? warum kann ich den zeiger nicht einfach wie in der funktion "zeige" übergeben?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Lord Kefir, 11.04.2005
    Zuletzt bearbeitet: 11.04.2005
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Weil's ein Referenzparameter ist.

    [edit]
    C++ im Schulunterricht?! Hach, da wird man glatt neidisch...
    [/edit]

    Mfg, Lord Kefir
     
  4. cremi

    cremi Dude

    Dabei seit:
    15.02.2004
    Beiträge:
    329
    Zustimmungen:
    0
    Ort:
    AUT/Ktn
    ich hab mir den source jetzt zwar nicht richtig angeschaut aber der unterschied zur funktion zeige ist folgendes:
    bei zeige() wird der baum nicht verändert dort wird er nur ausgegeben deshalb wird hier der zeiger auf den baum übergeben.
    bei einfügern() veränderst du den inhalt des Baumes - deshalb musst du eine referenz (&) übergeben.

    ist hier unter kapitel 5.2 glaub ich ganz gut und ausführlich erklärt:
    http://www.highscore.de/cpp/einfuehrung/funktionen.html#section2
     
  5. #4 NaRF, 11.04.2005
    Zuletzt bearbeitet: 11.04.2005
    NaRF

    NaRF Hatifschnacke

    Dabei seit:
    15.05.2003
    Beiträge:
    105
    Zustimmungen:
    0
    Ort:
    Friedberg (Hessen)
    vielen danke euch beiden :)

    wenn ich das richtig verstanden habe führt "&" also ein doppelleben und dient:
    1)um die adresse einer variable/eines pointers im speicher zu erfahren:
    int x=5;
    cout << &x;

    2)als referenz, die zwar, ähnlich wie ein pointer, die adresse einer variable speichert, beim aufruf aber einen direkten zugriff auf die variable erlaubt und nicht wie der pointer auf deren adresse:
    int y=5;
    int &x=y;
    cout << x; //gibt 5 aus

    das ganze müsste sich aber doch auch so realisieren lassen:
    int y=5;
    int *x=&y;
    *x=7
    cout << y; //gibt 7 aus


    ich muss aber dazu sagen, dass ich cremis text jetzt erstmal nur überflogen habe. ich werde mir den jetzt nochmal nen bisschen genauer zu gemüte führen :hilfe2:
     
  6. cremi

    cremi Dude

    Dabei seit:
    15.02.2004
    Beiträge:
    329
    Zustimmungen:
    0
    Ort:
    AUT/Ktn
    die sache sieht so aus:

    wenn du den pointer übergiebst wird der inahlt übergeben, dh. es wird eine kopie von dem inhalt fürs unterprogramm erstellt. wenn du nun etwas veränderst veränderst du die kopie. der speicherplatz dieser kopie wird aber bei verlassen des unterprogrammes wieder frei gegen und außerdem zeigt der pointer sowieso aufs "orginal" welches nat. genau wie vor dem funktiosaufruf aussieht.

    wenn du eine referenz übergibst, übergiebst du die adresse von dem speicher auf den der zeiger zeigt, wenn du nun was veränderst, wird das "orginal" verändert. und das ist ja das was du bei einer einfügen() funktion machen willst. bei der zeigen() funktion werden die daten ja nur gelesen und deswegen wird dort der pointer übergeben.
     
  7. #6 NaRF, 11.04.2005
    Zuletzt bearbeitet: 11.04.2005
    NaRF

    NaRF Hatifschnacke

    Dabei seit:
    15.05.2003
    Beiträge:
    105
    Zustimmungen:
    0
    Ort:
    Friedberg (Hessen)
    Code:
    #include <iostream>
    
    using namespace std;
    
    void test(int *p)
    {
    cout << "\nFunktion: Inhalt Zeiger: " << p << endl;
    cout << "Adresse Zeiger: " << &p << endl;
    
    
    *p=8;
    }
    
    int main()
    {
    int y=5;
    int *x=&y;
    cout << "\nMain: Inhalt Zeiger: " << x;
    cout << "\nAdresse Zeiger: " << &x << endl;
    test(x);
    cout << "y=" << y << endl;
    }
    
    ausgabe:
    Code:
    Main: Inhalt Zeiger: 0xbffff8c4
    Adresse Zeiger: 0xbffff8c0
    Funktion: Inhalt Zeiger: 0xbffff8c4
    Adresse Zeiger: 0xbffff8b0
    y=8
    laut der ausgabe greife ich in diesem beispiel aber doch direkt auf y zu obwohl ich einen zeiger auf y an die funktion übergeben habe.
    vielleicht habe ich dich falsch verstanden aber ich habe deinen beitrag jetzt so gedeutet, dass ich wenn ich einen zeiger übergebe eine kopie des zeigers übergebe, der zwar auf den gleichen wert zeigt (nicht auf die gleiche variable), den aber in einen andren speicherbereich schreibt. laut meinem beispiel wird zwar tatsächlich eine kopie des zeigers angelegt (siehe adresse zeiger). der zeiger zeigt aber immer noch auf den selben speicherbereicht (siehe inhalt zeiger). deshalb kann ich auch in der unterfunktion mit hilfe des dereferenzierungsoperators * direkt auf y zugreifen.
     
  8. #7 Lord Kefir, 11.04.2005
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Mal so aus Interesse: hast Du eigentlich vor C++ mal C programmiert?! Finde ich bezogen auf Speicherverwaltung etc. ziemlich nützlich. Hat mir jedenfalls ziemlich geholfen, den ganzen Kram irgendwie in meine Birne zu kriegen ;)

    Mfg, Lord Kefir
     
  9. NaRF

    NaRF Hatifschnacke

    Dabei seit:
    15.05.2003
    Beiträge:
    105
    Zustimmungen:
    0
    Ort:
    Friedberg (Hessen)
    bei uns im infounterricht waren die übergänge zwischen c und c++ eher fließend :)

    speicherverwaltung haben wir vor dem thema "structs, pointer&co" noch gar nicht gemacht. bis jetzt haben wir z.b. diverse sortier/verschlüsselungsalgorhythmen (die einfachen ;) ) implentiert, grafikprogrammierung mit ner uralten borland library :oldman gemacht (z.b. erstellen von graphen, eine populationsentwicklung simuliert, mandelbrotmenge etc.) und ein programm zum knacken der vignere-verschlüsselung (anhand der buchstabenhäufigkeit) geschrieben.

    zeiger und speicherverwaltung sind also totales neuland für mich und die (meisten) andren aber langsam blick ich durch :D (hoffe ich)

    btw: ich hab meinen letzten beitrag nochmal editiert, das programm erweitert und dabei noch was wichtiges endtdeckt ;)
     
  10. #9 cremi, 11.04.2005
    Zuletzt bearbeitet: 11.04.2005
    cremi

    cremi Dude

    Dabei seit:
    15.02.2004
    Beiträge:
    329
    Zustimmungen:
    0
    Ort:
    AUT/Ktn
    du übergiebst nicht den zeiger sondern eine referenz - also die adresse der daten - deswegen funkts

    ist ja identisch mit:
    Code:
    int main()
    {
    int y=5;
    
    cout << endl << y;
    test(&y);
    cout << y << endl;
    }
    
     
  11. #10 MrFenix, 11.04.2005
    MrFenix

    MrFenix Executor

    Dabei seit:
    16.10.2004
    Beiträge:
    480
    Zustimmungen:
    0
    Ort:
    Siegen, NRW
    [Offtopic]
    Was habt ihr denn für nen genialen Info Unterricht???
    Wir sind schon seit bald nem Monat damit beschäftigt mit Delphi (würg) Rechtecke über den Bildschirm zu schieben *langsam am rad dreh*
    [/Offtopic]
     
  12. #11 Lord Kefir, 11.04.2005
    Zuletzt bearbeitet: 11.04.2005
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Ich glaube ich liege richtig wenn ich behaupte, dass Speicherverwaltung, Zeiger etc. eigentlich immer für die größte Verwirrung sorgen... :) vor allem wenn man dann in C anfängt Zeiger auf Zeiger zu programmieren, die vielleicht auch noch auf Zeiger zeigen...
    Selbst programmiere ich jetzt auch noch nicht soooo lange mit C und habe erst vor kurzem mit C++ angefangen. Mir ist jedenfalls dabei aufgefallen, dass ein bischen Erfahrung in C echt nicht schaden kann. Wollte ich halt mal so als Tipp am Rande erwähnen :D

    C++ in der Schule... haut mich immer noch vom Hocker. Wir quälen uns mit Turbo Pascal 3 herum. Nichts gegen Pascal - aber unsere Version ist noch von 1987 oder so... :(

    Mfg, Lord Kefir
     
  13. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  14. #12 h2owasser, 14.04.2005
    Zuletzt bearbeitet: 14.04.2005
    h2owasser

    h2owasser Sxe Power User

    Dabei seit:
    07.12.2002
    Beiträge:
    491
    Zustimmungen:
    0
    Moment, hier ist *p der Wert, der übergeben wird. D.h. der Inhalt des Wertes wird kopiert (hier: 0xbffff8c4) und nicht der Wert, auf den p zeigt (hier *p bzw. 5).

    Alternativ lässt sich dein Code von oben auch (etwas unschön) umschreiben zu:

    Code:
    
    // --------------------------------------------
            void einfuegen (BaumTyp** Baum, char Daten)
    // --------------------------------------------
     {
            if (*Baum == NULL)
              {
            *Baum = new BaumTyp;
                (*Baum)->info = Daten;
                (*Baum)->li = NULL;
            (*Baum)->re = NULL;
              }
            else einfuegen (Daten < (*Baum)->info ? &((*Baum)->li) : &((*Baum)->re), Daten);
     }
    // Aufruf nun: einfuegen (&Baum, Eingabe[k]);
    
    
    
     
  15. cremi

    cremi Dude

    Dabei seit:
    15.02.2004
    Beiträge:
    329
    Zustimmungen:
    0
    Ort:
    AUT/Ktn
    IMHO würd ich sagen, so ist es sogar "sauberer"
     
Thema:

Übergeben von Zeigern an Funktionen

Die Seite wird geladen...

Übergeben von Zeigern an Funktionen - Ähnliche Themen

  1. sed suchen und ersetzen mit Variable übergeben?

    sed suchen und ersetzen mit Variable übergeben?: hallo, ich habe folgenden sed-Befehl, der schon super ist und auch alles tut, was er tun soll, nur eben natürlich das $i einfach hinschreibt...
  2. usernamen als argument übergeben

    usernamen als argument übergeben: Hi ich bin anfänger auf dem gebiet und möchte ein einfaches backup script schreiben. #!/bin/bash #Bei Ausführung des Scripts werden alle Datein...
  3. Zeichenkette per Skript an shell übergeben

    Zeichenkette per Skript an shell übergeben: [gelöst]Zeichenkette per Skript an shell übergeben Hallo Leute, sitze momentan etwas ratlos vor einem Shell-Skript (Bin kompletter Anfänger...
  4. grep Ausgabe an ls übergeben

    grep Ausgabe an ls übergeben: Kann ich die Ausgabe von grep (es sind dateinamen des lokalen verzeichnisses) irgendwie gleich weiterpipen zu ls? Also so das ich zu den...
  5. Vergleich bei unterschiedlicher Schreibweise eines übergebenen Parameters

    Vergleich bei unterschiedlicher Schreibweise eines übergebenen Parameters: Hallo, ich bin unerfahren in der Script-Erstellung und suche für folgendes Problem eine Lösung: Als Aufrufparameter erwartet mein Script...