web-dev-qa-db-de.com

Ändern der im Zeiger enthaltenen Adresse mit der Funktion

Wenn ich einen Zeiger p als int *p Deklariert habe; Im Hauptmodul kann ich die in p enthaltene Adresse durch Zuweisen von p=&a; ändern, wobei a eine andere bereits deklarierte Ganzzahlvariable ist. Ich möchte jetzt die Adresse ändern, indem ich eine Funktion benutze wie:

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("\n The address is %u ",p);
    change_adrs(p);
    printf("\n the address is %u ",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?

31
pranphy

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

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

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

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

37

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);

Dies wird gedruckt

*p = 1
*p = 2
12
user529758

Wenn Sie den Inhalt einer Variablen in einer Funktion in C ändern möchten, ist der Zeiger ebenfalls eine Art Variable. Sie müssen ihn mit Zeiger oder indirekte Referenz übergeben immer & Adresse und * Dereferenzierungsoperatoren. Ich meine * -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;

}
2
snr

Für einen primitiven Datentyp wie int sind die doppelten Zeiger nicht erforderlich. Sie können direkt in die Adresse schreiben, unter der int gespeichert ist, und die Adresse als Zeiger in der aufgerufenen Funktion behandeln. Dies ist anders als bei einem char -Array ("string"), bei dem die Größe des Verweises variabel ist und Sie daher eine andere Indirektionsebene verwenden müssen, wenn Sie es aus einer aufgerufenen Funktion heraus ä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;
}

Hierdurch wird der tatsächliche Wert von p nicht geändert, da die Funktion q für diese Funktion lokal ist und Änderungen in dieser Funktion nicht für main gelten. Übergeben Sie daher die Adresse von p anstatt p als Wert zu übergeben

Verwenden Sie diese Syntax unten

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

und wie folgt aufrufen change_adrs(&p);

Oder Sie haben eine andere Möglichkeit: Ändern Sie den Rückgabetyp und erfassen Sie die zurückgegebene Adresse.

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


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