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


von Bergie B. (bergie)


Lesenswert?

1
*(byMessage + i) 
2
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

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

Bergie B. schrieb:
>
1
> *(byMessage + i)
2
> byMessage[i]
3
>

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

Deshalb koenntest du sogar schreiben:
1
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.

von Gasstt (Gast)


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.

von der mechatroniker (Gast)


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?

von Gasstt (Gast)


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.

von Klaus W. (mfgkw)


Lesenswert?

?

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

von Klaus W. (mfgkw)


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.

von Rolf Magnus (Gast)


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.

von Captain S. (captainsubtext)


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:
1
char i;
2
int wert[5] = {1,2,3,4,5};
3
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
...
1
wert[i] = *(108) = 5
2
*(wert + i) = *(104) = 3
3
wert[i] != *(wert + i)

Wo liegt denn jetzt da mein Denkfehler?

von P. S. (Gast)


Lesenswert?

Captain Subtext schrieb:

> Wo liegt denn jetzt da mein Denkfehler?

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

von Klaus W. (mfgkw)


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 :-)

von Rolf Magnus (Gast)


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.

von P. S. (Gast)


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-Reference/dp/3446154973

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

von Thomas P. (tpircher) Benutzerseite


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas P. (tpircher) Benutzerseite


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.

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.