2015-04-15 5 views
7

Ich übergebe einen Zeiger eine Funktion, die es aktualisiert. Wenn die Funktion jedoch den Zeiger zurückgibt, kehrt sie zu dem Wert zurück, den sie vor dem Funktionsaufruf hatte.Aktualisieren von Zeigern in einer Funktion

Hier ist mein Code:

#include <stdio.h> 
#include <stdlib.h> 

static void func(char *pSrc) { 
    int x; 
    for (x = 0; x < 10; x++) { 
     *pSrc++; 
    } 

    printf("Pointer Within Function: %p\n", pSrc ); 
} 

int main(void) { 

    char *pSrc = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."; 

    printf("Pointer Value Before Function: %p\n", pSrc ); 

    func(pSrc); 

    printf("Pointer Value After Function: %p\n", pSrc ); 

    return EXIT_SUCCESS; 
} 

Hier ist die Ausgabe

Pointer Value Before Function: 0x100403050 
Pointer Within Function: 0x10040305a 
Pointer Value After Function: 0x100403050 

Was ich erwartet hatte der Wert nach der Funktion war es, die man passend innerhalb der Funktion.

Ich habe versucht, auf char **pSrc zu wechseln, aber das hatte nicht die gewünschte Wirkung.

Ich bin sicher, die Antwort ist ziemlich einfach, aber ich bin ein Hardware-Ingenieur erholt und kann nicht scheinen, um es herauszufinden :-)

+0

Sie müssen die * -Adresse * Ihres 'char * pSrc' übergeben, damit Sie ändern können, worauf' pSrc' zeigt (behalten Sie 'char * pSrc' bei, übergeben Sie es als' & pSrc', und nehmen Sie die Funktion '' char ** '. – crashmstr

Antwort

7

Der Zeiger innerhalb der Funktion eine Kopie des übergebenen Zeigers ist.

Sie beide halten die gleiche Adresse, aber haben unterschiedliche Adressen, so ändert die Änderung der Adresse von einem von ihnen nicht die anderen.

Wenn Sie den Mauszeiger innerhalb der Funktion zu erhöhen, wollen passieren ist es Adresse statt, wie dies

static void func(char **pSrc) { 
    int x; 
    for (x = 0; x < 10; x++) { 
     (*pSrc)++; 
    }  
    printf("Pointer Within Function: %p\n", pSrc ); 
} 

und

func(&pSrc); 

Auch nicht vorsichtig sein, um den Inhalt zu ändern, weil der Zeiger Punkte in ein String-Literal und String-Literale können nicht geändert werden.

2

C verwendet Pass-by-Wert für Funktions Parameter. Der Wert von pSrc ist nur eine Kopie der pSrc in main(), nicht die gleiche Einheit als pSrc von main(). Aus diesem Grund werden Änderungen an pSrc innerhalb der Funktion func() nicht in main() (Anruferfunktion) wiedergegeben.

Allerdings werden alle Änderungen an *pSrc beibehalten.

Lösung: Um die pSrc von main() von func() zu ändern, müssen Sie einen Zeiger auf pSrc (Zeiger auf einen Zeiger), um von main() und die Datentypen entsprechend anpassen. Auch in diesem Fall, bitte beachten Sie, dass die pSrc modifizierbar sein sollte (vorhanden im Schreib-Lese-Speicher). Wie es derzeit geschrieben ist, ist die pSrc in main() nicht änderbar.

+0

C verwendet auch Pass-by-Referenz, nicht wahr? – ryyker

+0

@ryyker ist es so? Wie, bitte? Atleast, ich mein Wissen, tut es nicht. –

+0

Die richtige Aussage, die ich glaube, wäre _With Ausnahme von Arrays und Funktionen, C übergibt Argumente immer nach Wert_. (*** [von hier] (http://www.maths.cam.ac.uk/undergrad/catam/ccatsl/manual/node50.html) ***, zum Beispiel) Ich verstehe den Punkt Ihrer Antwort, und habe kein echtes Problem damit, nur diesen einen Punkt :) – ryyker

2

Wenn Sie einen Zeiger auf eine Funktion geben, haben Sie eine Kopie des Referenzwerts, den Sie ursprünglich hatten.

Dann, wenn Sie Ihren Zeiger ändern, Sie Modifizieren einer Kopie.

Wenn Sie das Original aktualisieren möchten, müssen Sie es mit einem Doppelzeiger ** übergeben, mit dem Sie den ursprünglichen Zeiger ändern und einen "Verweis auf einen Verweis" (Doppelzeiger) übergeben können.

1

C übergibt Parameter nach Wert, also erstellt es eine Kopie von pSrc innerhalb Ihrer Funktion, und alle Änderungen, die Sie vorgenommen haben, werden auf eine Kopie von pSrc angewendet. Wenn Sie den Wert von pSrc ändern möchten, dann sollten Sie einen Zeiger auf pSrc, wie dies passieren:

static void func(char **pSrc){ // pointer to char* 
    int x; 
    for (x = 0; x < 10; x++) 
     (*pSrc)++ 
} 
1

rufen Sie func von pSrc vorbei. Sie denken, Sie übergeben die gleiche Variable - Das ist func wird auf dem gleichen Speicherort betrieben, wenn es pSrc ändert. Das ist falsch.

func erhält eine Kopie von pSrc. Der Stack-Frame mit dem Aufruf func wird seine eigene pSrc haben. Was geändert wird, ist seine Version nicht die aufrufende Funktion.

Um func auf die tatsächliche Variable in Haupt bearbeiten zu können, müssen Sie die Adresse pSrc - &pSrc übergeben.

Relevante Konzepte - Pass by Value und Pass by Reference.