Ändern der im Zeiger enthaltenen Adresse mithilfe der Funktion
Lesezeit: 4 Minuten
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
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
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;
}
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
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