Forum: Mikrocontroller und Digitale Elektronik C Struct Pointer in Funktion "swappen" ?


von AVRli (Gast)


Lesenswert?

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

von Stefan K. (stefan64)


Lesenswert?

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

von Stefan K. (stefan64)


Lesenswert?


von Rainer B. (katastrophenheinz)


Lesenswert?

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

von Decius (Gast)


Lesenswert?

oder einfach:

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

von Peter II (Gast)


Lesenswert?

Decius schrieb:
> oder einfach:

bestimmt nicht.

von Decius (Gast)


Lesenswert?

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
}

von Decius (Gast)


Lesenswert?

Sorry. War etwas langsamer als PeterII.

von AVRli (Gast)


Lesenswert?

@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. :-/

von Zephyrinus Z. Zeiger (Gast)


Lesenswert?

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, ...

von Nop (Gast)


Lesenswert?

AVRli schrieb:
> Zeiger auf Zeiger - da wäre ich im Leben nicht drauf gekommen!

Dann ist es bis zum Dreisterne-Programmierer ja noch ein weiter Weg. ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.