C Struct Pointer in Funktion "swappen" ?

Gast #4860840
Hallo Community,

ich möchte ganz gerne im Hauptprogramm über eine Funktion zwei Zeiger 
untereinander tauschen. Das gelingt mir nicht. Was habe ich übersehen?
1
...
2
typedef struct
3
{
4
    unsigned char fid;
5
    unsigned char mount;
6
    unsigned char name[8];
7
} MY_device;
8
...
9
...
10
void SwapDevices(MY_device *dev_a, MY_device *dev_b)
11
{
12
  OWI_device *dev_s;
13
  
14
  *dev_s = *dev_a;
15
  *dev_a = *dev_b;
16
  *dev_b = *dev_s;  
17
}
18
...
19
...
20
int main (void) {
21
    MY_device *dvo, *dvi;
22
...
23
...
24
...
25
    SwapDevices(dvo, dvi);
26
}


Vor dem Aufruf von "SwapDevice" stimmen die Adressen von dvi und dvo 
nach dem Aufruf sind sie leider nicht getauscht.

Ich bitte Euch hiermit um Hilfe.
AVRli
Du musst Pointer auf Pointer übergeben, damit die Funktion Deine Pointer 
swappen kann:
1
void SwapDevices(MY_device **dev_a, MY_device **dev_b)
2
{
3
...
4
}
5

6
int main (void) {
7
    MY_device *dvo, *dvi;
8
...
9
...
10
...
11
    SwapDevices(&dvo, &dvi);
12
}

Gruß, Stefan
Der normale Parameterübergabemechanismus in C ist "call by value", d.h. 
so wie du das machst, übergibst du Kopien deiner Zeiger, die lokal 
vertauscht werden, ausserhalb der Funktion jedoch ( eben weil es Kopien 
sind ) unverändert sind. Wenn du "call by reference" haben willst, dann 
musst Zeiger auf die Originale übergeben, also Zeiger auf Zeiger:
[/c]
void SwapDevices(MY_device **dev_a, MY_device **dev_b)
{
  OWI_device *dev_s;

  dev_s = *dev_a;
  *dev_a = *dev_b;
  *dev_b = dev_s;
}
...
...
int main (void) {
    MY_device *dvo, *dvi;
...
...
...
    SwapDevices(&dvo, &dvi);
}
Gast
Bei genauerer Überlegung ist es wahrscheinlich doch so wie Rainer es 
geschrieben hat. Denn bei call by reference wird eine adresse übergeben, 
deren Inhalt dann geändert werden kann.

Bei:
1
void SwapDevices(MY_device *dev_a, MY_device *dev_b)
2
{
3
}

wird zwar eine Adresse übergeben, aber es soll nicht der Inhalt auf 
dieser Adresse sonder die Adresse selbst geändert werden. Also ist wohl 
doch ein Zeiger auf einem Zeigern notwendig:
1
void SwapDevices(MY_device **dev_a, MY_device **dev_b)
2
{
3
}
Gast
@all
Danke für Eure Antworten!

Rainer B. schrieb:
> Wenn du "call by reference" haben willst, dann
> musst Zeiger auf die Originale übergeben, also Zeiger auf Zeiger:

Danke Rainer! That's is! :-D
Zeiger auf Zeiger - da wäre ich im Leben nicht drauf gekommen!

Und die Swap Funktion habe ich auch übernommen, ich hab echt eine 
"Zeiger-Blockade" ob ich die noch ablegen kann. :-/
Gast
Decius schrieb:
> wird zwar eine Adresse übergeben, aber es soll nicht der Inhalt auf
> dieser Adresse sonder die Adresse selbst geändert werden. Also ist wohl
> doch ein Zeiger auf einem Zeigern notwendig:

Ja, man braucht eben immer mindestens eine Indirektion mehr, wenn man 
den Wert selbst verändern will und nicht bloß seine Kopie: Wert -> 
Zeiger, Zeiger ("Adresswert") -> Zeiger auf Zeiger, Zeiger auf Zeiger -> 
Zeiger auf Zeiger auf Zeiger, ...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.