2016-07-02 7 views
1

ich in diesem Code lautete:Pointers in C: Änderungen in einer Funktion

#include <stdio.h> 

void foo(int* p1, int* p2) 
{ 
    p1 = p2; 
    *p1 = *p2 + 1; 
} 

void bar(int** p1, int** p2) 
{ 
    p1 = p2; 
    *p1 = *p2 + 1; 
    **p1 = **p2 + 2; 
} 

void main (void) 
{ 
    int n[] = {1,2,3}; 
    int m[] = {4,5,6}; 
    int *p1 = n; 
    int *p2 = m; 

    foo(p1,p2); 
    bar(&p1,&p2); 
    printf("%d %d\n",*p1,*p2); 
} 

Ich dachte, der Ausgang [1,5] sein wird, während es [1,7]. Kann jemand den Grund erklären?

Vielen Dank

+1

Bitte den Code als Text in den Fragetext eingeben als ein Link. – SurvivalMachine

+0

'void main (void)' hat ein undefiniertes Verhalten im C-Standard, es sei denn, es handelt sich um eine implementierungsdefinierte Art des Prototyping von 'main'. Siehe auch http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c –

+0

Ich habe den Code aktualisiert. meine Frage war über das Verhalten des Zeigers. –

Antwort

3

Zunächst müssen Sie p1 und p2 innerhalb Haupt- und p1, p2 innerhalb der Funktionen unterscheiden, die nicht gleich sind. Also werde ich die Parameter foo und bar in fp1, fp2, bp1, fp2 umbenennen, um klarer unterscheiden zu können. Dies wird nichts an Verhalten ändern.

So erste Hauptanrufe . fp1 und fp2 sind dann Kopien der Zeiger p1 und p2. Innerhalb von foo:

  1. fp1 = fp2; fp2 ist fp1 zugeordnet. So halten sowohl fp1 als auch fp2 die Adresse des Arrays, dem p2 zugewiesen wurde (d. H. m innerhalb von main).
  2. *p1 = *p2 + 1; da sowohl p1 als auch p2 die Adresse von m haben (oder m [0], was für Arrays gleich ist), wird m [0] inkrementiert (war 4, ist jetzt 5).

Rufen Sie dann bar(&p1, &p2);. So bp1 und bp2 halten nun die Adressen der beiden Zeiger p1 und p2 innerhalb des Haupt (dh Sie können p1 ändern und P2 sich von innen bar!), Die dann geschehen wird, auch:

  1. bp1 = bp2; wieder beide Zeiger haben dieselbe Adresse, die die von p2 innerhalb von main ist (immer noch mit der Adresse von m [0]).
  2. *bp1 = *bp2 + 1; da sowohl bp1 als auch bp2 auf den gleichen Zeiger zeigen, führt dies zu einer Inkrementierung dieses Zeigers, so dass p2 effektiv inkrementiert wird und jetzt auf m [1] zeigt.
  3. **bp1 = **bp2 + 2; bp1 und bp2 zeigen beide auf p2, was auf m [1] zeigt. Also wird m [1] um 2 inkrementiert (m [1] war 5, jetzt ist 7!).

Abschließend die Werte drucken. Denken Sie daran, p2 selbst wurde innerhalb von bar geändert und zeigt jetzt auf m [1], was wiederum zu 7 geändert wurde. Das Ergebnis wurde also nicht erwartet ...

+0

großartig, vielen Dank –