Ändern der im Zeiger enthaltenen Adresse mithilfe der Funktion

Lesezeit: 4 Minuten

Benutzeravatar von pranphy
Pranphy

Wenn ich einen Zeiger deklariert habe p wie int *p; Im Hauptmodul kann ich die darin enthaltene Adresse ändern p durch Zuweisung p = &a; wo a ist eine andere bereits deklarierte Integer-Variable. Ich möchte jetzt die Adresse ändern, indem ich eine Funktion wie folgt verwende:

void change_adrs(int*q)
{
    int *newad;
    q = newad;
}

Wenn ich diese Funktion vom Hauptmodul aus aufrufe

int main()
{
    int *p;
    int a = 0;
    p = &a; // this changes the address contained by pointer p
    printf("The address is %u\n", p);
    change_adrs(p);
    printf("The address is %u\n", p); // but this doesn't change the address
    return 0;
}

der Adressinhalt bleibt unverändert. Was ist falsch daran, eine Funktion für dieselbe Aufgabe zu verwenden?

  • Sie übergeben den Zeiger als Wert. Wenn Sie den Zeiger innerhalb der Funktion ändern müssen, übergeben Sie ihn als Referenz … Doppelzeiger.

    – Alok Speichern

    17. November 2012 um 13:43 Uhr


Benutzeravatar von mathematician1975
Mathematiker1975

In C werden Funktionsargumente als Wert übergeben. Daher wird eine Kopie Ihres Arguments erstellt und die Änderung an dieser Kopie vorgenommen, nicht an dem tatsächlichen Zeigerobjekt, von dem Sie erwarten, dass es geändert wird. Sie müssen Ihre Funktion ändern, um ein Zeiger-zu-Zeiger-Argument zu akzeptieren, und die Änderung am dereferenzierten Argument vornehmen, wenn Sie dies tun möchten. Zum Beispiel

 void foo(int** p) {
      *p = NULL;  /* set pointer to null */
 }
 void foo2(int* p) {
      p = NULL;  /* makes copy of p and copy is set to null*/
 }

 int main() {
     int* k;
     foo2(k);   /* k unchanged */
     foo(&k);   /* NOW k == NULL */
 }

Wenn Sie den Luxus haben, C++ zu verwenden, besteht eine alternative Möglichkeit darin, die Funktion so zu ändern, dass sie einen Verweis auf einen Zeiger akzeptiert.

  • Ich möchte nur darauf hinweisen, dass der C-Standard nicht garantiert, dass die Zuweisung von p zu 0 null macht.

    – JKRT

    17. November 2017 um 20:28 Uhr


  • Wenn ich müsste *arr = malloc() ein neues Array in der aufgerufenen Funktion und dem Punkt **p dazu, ist es *p = &arr?

    – mlSchüler33

    6. Juli 2020 um 5:45 Uhr

  • @JKRT: 6.2.3.2 in der C-Spezifikation sagt: “Ein ganzzahliger konstanter Ausdruck mit dem Wert 0 oder ein solcher Ausdruck, der in den Typ void * umgewandelt wird, wird als Nullzeigerkonstante bezeichnet.” — Wenn Sie also ein Literal 0 zuweisen, wird es null. Das „oder“ in diesem Satz bedeutet, dass keine Umwandlung erforderlich ist.

    – Chris Dodd

    16. November 2020 um 22:51 Uhr


In C werden Variablen als Wert übergeben – eine Kopie des Zeigers wird an die Funktion übergeben. Verwenden Sie stattdessen einen anderen Zeiger auf den Zeiger:

void change(int **p, int *someOtherAddress)
{
    *p = someOtherAddress;
}

int a = 1, b = 2;
int *p = &a;

printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);

Das druckt

*p = 1
*p = 2

  • Stimmen Sie nur zu, weil diese Antwort den Ausdruck “Doppelzeiger” vermeidet

    – William Pursel

    5. August 2020 um 22:49 Uhr

Benutzeravatar von snr
snr

Wenn Sie den Inhalt einer Variablen in einer Funktion in C ändern möchten, ist der Zeiger auch eine Art Variable, Sie müssen ihn übergeben Zeiger oder indirekte Referenz indem Sie immer verwenden & Adresse u * Dereferenzierungsoperatoren. Ich meine * Der Operator wird immer verwendet und vorangestellt, wenn der Wert einer Variablen geändert wird.

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


void changeIntVal(int *x) {
    *x = 5;
}

void changePointerAddr(int **q) {
    int *newad;
    *q = newad;
}

void changePPAddr(int ***q) {
    int **dummy;
    *q = dummy;
}

int main() {
    int *p;
    int **pp;
    int *tempForPP;
    int a = 0;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);


    p = &a;
    pp = &tempForPP;
    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    changeIntVal(&a);        // ----
                             //    |---
    changePointerAddr(&p);   // ----  |---->  parts of what I mean
                             //    |---
    changePPAddr(&pp);       // ----

    printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);

    return 0;

}

Für einen primitiven Datentyp wie z int, die Doppelzeiger sind nicht erforderlich. Sie können direkt in die Adresse schreiben, wo die int wird gespeichert und behandelt seine Adresse als Zeiger in der aufgerufenen Funktion. Dies ist anders als a char array (“string”), wobei die Größe dessen, worauf gezeigt wird, variabel ist und Sie daher eine andere Indirektionsebene verwenden müssen, wenn Sie sie innerhalb einer aufgerufenen Funktion ändern. Versuche dies:

void foo(int *oldVal)
{
    int newVal = 99;    // or whatever you want
    *oldVal = newVal;
}

int main(int argc, char *argv[])
{
    int someVal = 0;
    foo(&someVal);      // we send its address to foo()

    printf("someVal is now %d.\n", someVal);

    return EXIT_SUCCESS;
}

Benutzeravatar von Omkant
Omkant

Dies ändert nichts am tatsächlichen Wert von p weil die q in der Funktion ist lokal dazu und Änderungen in dieser Funktion werden sich nicht darin widerspiegeln main so übergeben Sie die Adresse von p statt vorbei p nach Wert

Verwenden Sie diese Syntax unten

void change_adrs(int **q)
{
    int * otheraddess;
    *q = otheraddress; 
}

und so anrufen change_adrs(&p);

Oder Sie haben einen anderen Weg: Ändern Sie den Rückgabetyp der Funktion und fangen Sie die zurückgegebene Adresse ab.

int* change_adrs(int *q)
{
    int * otheraddess;
    q = otheraddress;
    return q; 
}


int main()
{
    p = change_adrs(p);
    return 0;
}

1413540cookie-checkÄndern der im Zeiger enthaltenen Adresse mithilfe der Funktion

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy