2010-12-26 13 views
2

Die Funktion:Zeiger in C mit einer #define

#define ASSOC(port) (*(volatile bit_field *) (&port)) 

Der Funktionsaufruf:

#define SCLK ASSOC(PORTC).bit0 

bit_field als Struktur definiert wie folgt aus:

typedef struct { 
unsigned char bit0 :1, bit1 :1, bit2 :1, bit3 :1, bit4 :1, bit5 :1, 
    bit6 :1, bit7 :1; 
} bit_field; 

ich nicht tun wissen, wo & Port definiert ist.

Kann mir bitte jemand erklären, wie die Funktion gelesen wird und wie es funktioniert? Ich bin nicht sehr gut mit Zeigern und dieses Beispiel insbesondere ist sehr verwirrend mit "*" in der Front und am Ende und der "&" mit dem Port.

Danke

Antwort

4

port ist nicht definiert. Es ist das Argument zu ASSOC wie Sie hier sehen können:

#define ASSOC(port) /* etc. */ 

Auch ich nehme an, es soll ein char sein, weil die bit_field 8 Bits hat. Die & in &port dient einfach dazu, ihre Adresse im Speicher zu bekommen.

ASSOC seinerseits wandelt &port in eine volatile bit_field * um, und dann gibt es die extra * am Anfang, um direkt auf den Inhalt des resultierenden Zeigers zu zeigen.

Wenn Sie also ASSOC (Port) aufrufen, können Sie es als Struktur vom Typ bit_field verwenden. Zum Beispiel gibt das SCLK Makro das erste Bit PORTC.

+0

Das brauchte eine Weile um zu verstehen, aber ich verstehe es jetzt. Der verwirrendste Teil für mich war, warum er Bit_field als Zeigervariable definierte (mit dem *). Dies liegt daran, dass er den gesamten Inhalt des typedef-Bitfelds, das er erstellt hat, erhält. Dann referenziert er das Ganze [(* (volatile bit_field *) (& port))] mit der Außenseite *, denn wenn er dies nicht tut, wird er die Adresse dessen, was er gerade übermittelt (PORTC), zurückgeben. Also rät er die ganze Sache so, dass der Inhalt zurückgegeben wird und nicht die Adresse .... Ich verstehe endlich besser Zeiger :) – milan

1

ASSOC nimmt, was ich nehme an ein charPORTC genannt und gibt in PORTC eine bit_field mit den gleichen Werten wie jedes einzelne Bit zurück.

SCLK gibt eines der Bits im Bitfeld zurück.

Sie nehmen PORTC und übergibt es als Parameter an ASSOC.

2

Das ASSOC Makro, das Sie definieren, ist ein In-Place-Cast.

  1. Sie übergeben in einem Wert port (in diesem Fall, es kommt von den anderen Makro SCLK)
  2. ASSOC nimmt die Adresse port mit dem & Operator
  3. ASSOC wirft port ‚s-Adresse zu einem (volatile bit_field *)
  4. ASSOCdereferences (* s) die Adresse des bit_field

Das Ergebnis sind die gleichen Bits wie Sie begonnen haben, aber als bit_field struct.

+0

Das hat mich eine Weile gebraucht, um zu verstehen, aber ich verstehe es jetzt. Der verwirrendste Teil für mich war, warum er Bit_field als Zeigervariable definierte (mit dem *). Dies liegt daran, dass er den gesamten Inhalt des typedef-Bitfelds, das er erstellt hat, erhält. Dann referenziert er das Ganze [(* (volatile bit_field *) (& port))] mit der Außenseite *, denn wenn er dies nicht tut, wird er die Adresse dessen, was er gerade übermittelt (PORTC), zurückgeben. Also referenziert er das Ganze so, dass die Inhalte zurückgegeben werden und nicht die Adresse .... Ich verstehe endlich besser Zeigern :) – milan