www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik *(byMessage + i) identisch byMessage[i]


Autor: Bergie B. (bergie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*(byMessage + i) 
byMessage[i]


sind diese beiden zugriffe auf die Variablen Identisch oder gibt es 
unterschiede?

Wann soll ich welchen davon benutzen ?
Ist es nur eine sache des aussehen, oder gibt es echte vor/nachteile?

LG

Autor: Thomas Pircher (tpircher) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bergie B. schrieb:
>
> *(byMessage + i)
> byMessage[i]
> 

Ja. Der Standard sagt:
The definition of the subscript operator [] is that E1[E2] is identical 
to (*((E1)+(E2))).

Deshalb koenntest du sogar schreiben:
i[byMessage]

> Wann soll ich welchen davon benutzen?

Meine Regel ist:

Wenn byMessage ein Array ist (als Array defiiert oder als pointer 
definiert, der aber auf mehere Elemente zeigt), dann nehme ich die 
byMessage[] Schreibweise.

Wenn der Pointer auf ein Element zeigt (Zeiger auf eine einzelne 
Variable oder Zeiger auf ein beliebiges Element in einem Array), dann 
mehme ich die Pointer-Schreibweise. (nota: in diesem Fall ist i immer 0)

Andere moegen das anders handhaben. Die einzige generelle Regel ist, 
dass man den Code so schreiben soll, dass er verstaendlich ist und am 
wenigsten falsche Interpretationen zulaesst.

Autor: Gasstt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eher die []-Schreibweise. Bei der *()-Schreibweise besteht die Gefahr 
fehlerhafter Rechnungen bei unpassenden Datentypen. Weiter wird der 
Compiler eine Warnung ausspucken, da zwischen Zahlenwerten und Pointern 
'unseriös' gecastet wird.

Aber wer C programmiert, der weiss ja, dass solche Stunts dazugehören - 
aber man muss im Detail wissen, was man tut.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bei der *()-Schreibweise besteht die Gefahr
> fehlerhafter Rechnungen bei unpassenden Datentypen. Weiter wird der
> Compiler eine Warnung ausspucken, da zwischen Zahlenwerten und Pointern
> 'unseriös' gecastet wird.

Kannst du das präzisieren?

Autor: Gasstt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Häufig ist x ein Pointer und i ein Integer. x[i] wird vom Compiler 
problemlos akzeptiert, *(x + i) ist jedoch eine Addition von Integer und 
Pointer, also werden unterschiedliche Datentypen verrechnet, was der 
Compiler eventuell mit einer Warnung quittiert.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
?

"Bitte einen längeren Text eingeben."
ok: ?????????

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unseriös fände ich, für i eine double zu nehmen.
Das ist aber in keiner der beiden Varianten zulässig.

Mit int sind dagegen beide Versionen vollkommen ok.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Häufig ist x ein Pointer und i ein Integer. x[i] wird vom Compiler
> problemlos akzeptiert, *(x + i) ist jedoch eine Addition von Integer und
> Pointer, also werden unterschiedliche Datentypen verrechnet, was der
> Compiler eventuell mit einer Warnung quittiert.

Das würde mich wundern, den solche Zeigerarithmetik ist was ganz 
normales. Ich habe wegen sowas auch noch nie eine Warnung gesehen.

Übrigens weiß ich auch nicht so recht, was:

> Eher die []-Schreibweise. Bei der *()-Schreibweise besteht die Gefahr
> fehlerhafter Rechnungen bei unpassenden Datentypen

bedeuten soll. Wie schon geschrieben wurde, sind beide Schreibweisen 
äquivalent. Wenn etwas in der einen fehlerhaft ist, ist es das auch in 
der anderen.

Autor: Captain Subtext (captainsubtext)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Übrigens weiß ich auch nicht so recht, was:
>
>> Eher die []-Schreibweise. Bei der *()-Schreibweise besteht die Gefahr
>> fehlerhafter Rechnungen bei unpassenden Datentypen
>
> bedeuten soll. Wie schon geschrieben wurde, sind beide Schreibweisen
> äquivalent. Wenn etwas in der einen fehlerhaft ist, ist es das auch in
> der anderen.

Ich glaube, ich hatte dieselben Gedanken wie Gassst und verstehe es 
ehrlich gesagt immer noch nicht!

Ein Beispiel:
char i;
int wert[5] = {1,2,3,4,5};
i = 4;

angenommen, wert[] startet jetzt  bei "Adresse 100". (mir fehlt gerade 
eine treffendere Bezeichnung)
wert[0] belegt die Adressen 100 und 101
wert[1] belegt 102 und 103
...
wert[i] = *(108) = 5
*(wert + i) = *(104) = 3
wert[i] != *(wert + i)

Wo liegt denn jetzt da mein Denkfehler?

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Captain Subtext schrieb:

> Wo liegt denn jetzt da mein Denkfehler?

Der Compiler ist klug und addiert nicht platt i, sondern i * sizeof( 
int).

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und das steht in jedem C-Buch.

Es macht Sinn, da mal reinzusehen, bevor man hier postet.
Notfalls wird Peter Stegemann bestimmt auch gerne die
relevante Seite aus dem K&R einscannen und hier reinstellen,
dann brauchen die anderen kein Buch in die Hand zu nehmen :-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gehört zu den Grundlagen der Zeigerarithmetik. Wenn ich einen Zeiger auf 
z.B den Anfang eines Arrays irgendeines beliebigen Typs habe und zu 
diesem i dazuaddiere, zeigt er i Elemente weiter, nicht i Bytes.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> ... und das steht in jedem C-Buch.
>
> Es macht Sinn, da mal reinzusehen, bevor man hier postet.

Das koennen wir in die FAQ schreiben, die keiner liest ;^/

> Notfalls wird Peter Stegemann bestimmt auch gerne die
> relevante Seite aus dem K&R einscannen und hier reinstellen,
> dann brauchen die anderen kein Buch in die Hand zu nehmen :-)

Ne, aber den Amazon-Link kann ich spendieren. Den packe ich jetzt doch 
mal auf eine Taste:

http://www.amazon.de/Programmieren-C-ANSI-2-C-Refe...

Ich geb's zu, ich habe nur dieses eine Buch ueber C, aber das reicht 
*<:o)

Autor: Thomas Pircher (tpircher) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im letzten Draft des C99 Standards ist das auch klar definiert und 
halbwegs verstaendlich beschrieben. Das Dokument gibt es gratis im Web, 
z.B. bei http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1336.pdf

6.5.2.1 Array subscripting
2)
A postfix expression followed by an expression in square brackets [] is 
a subscripted designation of an element of an array object. The 
definition of the subscript operator [] is that E1[E2] is identical to 
(*((E1)+(E2))). Because of the conversion rules that apply to the binary 
+ operator, if E1 is an array object (equivalently, a pointer to the 
initial element of an array object) and E2 is an integer, E1[E2] 
designates the E2-th element of E1 (counting from zero).

6.5.6 Additive operators
8)
When an expression that has integer type is added to or subtracted from 
a pointer, the result has the type of the pointer operand. If the 
pointer operand points to an element of an array object, and the array 
is large enough, the result points to an element offset from the 
original element such that the difference of the subscripts of the 
resulting and original array elements equals the integer expression. In 
other words, if the expression P points to the i-th element of an array 
object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N 
has the value n) point to, respectively, the i+n-th and i−n-th elements 
of the array object, provided they exist. Moreover, if the expression P 
points to the last element of an array object, the expression (P)+1 
points one past the last element of the array object, and if the 
expression Q points one past the last element of an array object, the 
expression (Q)-1 points to the last element of the array object. If both 
the pointer operand and the result point to elements of the same array 
object, or one past the last element of the array object, the evaluation 
shall not produce an overflow; otherwise, the behavior is undefined. If 
the result points one past the last element of the array object, it 
shall not be used as the operand of a unary * operator that is 
evaluated.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Pircher schrieb:

> Im letzten Draft des C99 Standards

n1336.pdf ist kein Draft, es ist der verabschiedete Standard, in den
die drei bisher existierenden technical corrigendas (TCs) eingearbeitet
worden sind.  Das Ding sieht nur aus wie ein Draft, weil der formale
Standard halt nur gegen Geld zu haben ist.

Autor: Thomas Pircher (tpircher) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, gut zu wissen; Da im pdf File "Committee Draft — August 11, 2008" 
stand, habe ich angenommen es unterscheide sich in Details vom 
verabschiedeten Standard.

Um zum Thema zurueckzukommen, sei neben dem K&R auch noch "C in a 
Nutshell" von O'Reilly erwaehnt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.