Frage: Pointer-Deklaration

Gast #1359457
Hallo,

kurze Frage aus der Pfalz:

im Header-file zum LPC2294 wird die Adresse des CANMOD-Registers wie 
folgt definiert:

#define C1MOD (*((volatile unsigned long*)))  0xE0044000



Später im einer anderen Routine wird einem Pointer diese Adresse wie 
folgt zugewiesen:


unsigned long *pBase

pBase = (unsigned long*) &C1MOD;


Warum wird hier noch einmal der Typ angegeben? Das ist doch 
normalerweise ein Typecast, ist dieser hier wirklich nötig?
Und wofür das Doppel* in der Definition des Registers?

Kann mir jemand bei diesen Fragen helfen?

Danke,
Bernd
#1359498
Bernd Bubble schrieb:

> Warum wird hier noch einmal der Typ angegeben? Das ist doch
> normalerweise ein Typecast, ist dieser hier wirklich nötig?

Ohne den Cast würde es eine "discards qualifiers"-Warnung geben.

> Und wofür das Doppel* in der Definition des Registers?

Das erste '*' ist Bestandteil des Cast, um aus dem Hex-Wert einen 
Pointer zu machen, das zweite '*' ist zur Dereferenzierung dieses 
Pointers.

Edit: Oder umgekehrt, je nach dem, von welcher Seite man anfängt zu 
zählen. ;-)
#1359527
Dass sieht seltsam aus.

Bist du sicher, dass du das richtig hier ins Forum kopiert hast.

IMHO sollte das eigentlich lauten
1
#define C1MOD (*((volatile unsigned long*)0xE0044000))

so ergibt das Sinn, aber deine Variante ist ... zumindest seltsam
Gast #1359566
Karl Heinz,

du hattest recht:

#define C1MOD          (*((volatile unsigned long *) 0xE0044000))

aber kannst du mir in wenigen verständlichen Worten die Deklaration 
erklären.

Mir ist klar, dass man dem Register einen Adresswert zuweisen will, und 
dass im Programm die Adresse an Pointer vom Typ unsigned long übergeben 
werden soll...ich hätte gesagt, dass der erste * zur Dereferenzierung 
verwendet wird???
#1359599
Bernd Bubble schrieb:
> Karl Heinz,
>
> du hattest recht:
>
> #define C1MOD          (*((volatile unsigned long *) 0xE0044000))
>
> aber kannst du mir in wenigen verständlichen Worten die Deklaration
> erklären.
>
> Mir ist klar, dass man dem Register einen Adresswert zuweisen will, und
> dass im Programm die Adresse an Pointer vom Typ unsigned long übergeben
> werden soll...ich hätte gesagt, dass der erste * zur Dereferenzierung
> verwendet wird???

Yep.

Aber gehe es doch einfach von innen nach aussen, beginnend beim Wert 
durch

  0xE0044000
               ist eine bestimmte Zahl

  (volatile unsigned long *) 0xE0044000
               diese Zahl wird zu einem Pointer gecastet

  *Pointer
               gibt den Inhalt an der Adresse die im Pointer steht

  Also

  * (volatile unsigned long *) 0xE0044000

      ergibt den Inhalt, der sich an dem unsigned long Pointer,
      dessen Wert 0xE0044000 beträgt. (Das volatile besagt lediglich,
      dass jedesmal nachgesehen werden muss, wenn mit dem Inhalt etwas
      passiert. Cachen ist nicht erlaubt)

Und dann noch eine Klammer rundherum, wie es bei Makros generell ratsam 
ist.
#1359602
Erstmal ist das keine Zuweisung, sondern nur ein #define.
Es wird also in Zukunft C1MOD erstzt durch das, was hier dahinter steht.

Das ist dann wiederum so zu interpretieren:
a) 0xE0044000 ist eine ganze Zahl
b) (volatile unsigned long *) 0xE0044000 ist eben diese Zahl, aber
  interpretiert als Zeiger auf unsigned long.
  Gemeint ist damit die Adresse einer unsigned long an der Stelle
  0xE0044000 im Speicher.
c) *((volatile unsigned long *) 0xE0044000) ist dann das, was an
  besagter Stelle im Speicher steht, also die unsigned long an
  der Stelle 0xE0044000
d) die Klammern drumrum sollen Ärger verhindern, der durch
  die unglückliche Auswertungsreihenfolge der Operatoren
  bei der jeweiligen Verwendung vorkommen kann.
  Man gewöhnt sich einfach an, solche Ersetzungen zu klammern.

Tip: In jedem besseren C-Buch die Operatoren anschauen und
dabei die Prioritäten und Auswertungsreihenfolge beachten
(Zusammenfassung von links oder von rechts).

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 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.