mikrocontroller.net

Forum: PC-Programmierung a=++i; a=i++; a=i+=n C-Syntaxfrage


Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Abwechslung eine theoretische Syntax-Frage:
Gibt es eine Schreibweise ähnlich a=i++, die aber um einen anderen Wert 
als 1 erhöht?
Ich meine nicht a=i+=n, denn das entspricht (für n=1)  ++i und nicht i++ 
(beachte die Position von += und ++).
Es geht mir um den Wert des Ausdruckes i+=n.

Es geht um
a) kompakte Schreibweise    und
b) kürzeste Ausführungszeit und Codegröße.

Beispiele: i=5  n=2
(1)  a=i++  --> a=5  i=6
(2)  a=++i  --> a=6  i=6
(3)  a=i+=n --> a=7  i=7

ich will aber, dass wie in (1)  a=5 ist, aber i um n erhöht wird.

Klar kann ich schreiben
(4) a=i; i+=n;
die Frage ist, ob (und wie) das (mit einem Trick) in einem Befehl geht.

Mein Vorschlag wäre
(5)  a=(+=i+=n);  oder
(6)  a=(i+=n)-n;
(7)  a=++++i;     für n=2

Zeile (6) wäre sogar syntaktisch richtig, aber ob ein Compiler schlau 
genug ist, zu erkennen, was ich meine?
Dass er das richtig optimiert, nämlich dass er _auf die Variable i nur 
einmal lesend zugreifen_ braucht.
(Die hier gegebenen Beispiele sind einfacher Natur, richtig wirkt sich 
das aus, wenn i kompizierte indirekt indizierte Variablen sind).

Ich denke auch an Pointer:
dort gibt es z.B.
b = *feldptr++
Was aber, wenn ich in Zweierschritten durch das Feld springen will?

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

Bewertung
0 lesenswert
nicht lesenswert
Versuche nicht, den Sourcecode auf Kosten der Lesbarkeit zu
,,optimieren''.  Überlass das Optimieren dem Compiler.  Deine
Verrenkungen bringen im besten Falle gar nichts bei einem modernen
Compiler, und im schlimmsten Fall kann kein Schwein mehr das Zeug
in 3 Monaten lesen. ;-)

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eProfi wrote:

> Es geht um
> a) kompakte Schreibweise    und
> b) kürzeste Ausführungszeit und Codegröße.

ad a) Kompakte Schreibweisen sind vielleicht theoretisch interessant, 
aber notorisch inhärent unverständlich für andere -- und alsbald auch 
für dich selbst.

ad b) Dafür gibt es keine Garantie und es ist zudem idR nicht 
spezifiziert, auf welches asm-Konstrukt ein bestimmtes C- oder allgemein 
Hochsprach-Konstrukt abgebildet wird. Das hängt ab von der Quellzeile, 
wesentlich vom Kontext, in dem sie steht, vom Compiler, von seiner 
Beschalterung und von der Plattform.

Ausserdem wird ein aggressiv optimierender Compiler den Code erstmal bis 
auf Hemd und Socken auseinanderpflücken, bei gcc 4.x kann man das zB 
bestaunen, wenn man -fdump-tree-all angibt oder andere fdump-Optionen. 
Mal irgendein Treffer von Tante Gundel:

http://developer.apple.com/documentation/developer...

Autor: bjoerns (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Schreibweise i++ bzw. ++i hat nur einen einzigen Vorteil (man hat 
ein paar Tastaturanschläge weniger), dafür aber sehr viele Nachteile 
(z.B. erschwerte Lesbarkeit), weshalb ich sie nur im Kopf einer 
for-Schleife oder als alleinige Anweisung verwende.

  for( i=1; i<C; i++)
oder
  i++;

Es gibt durch die Verwendung dieser Schreibweisen keinerlei Vorteil in 
der Ablaufgeschwindigkeit, evtl. ist sie sogar nachteilig, da  der 
Ausdruck
a = f( i++ );
möglicherweise wie folgt in Zwischencode übersetzt wird:
I = i;
i = i + 1;
a = f( I );
(wobei I eine vom Compiler eingefügte Hilfsvariable ist.)

Die Verwendug des ++-Operators ist sogar potentiell gefährlich, da die 
Reihenfolge der Auswertung von Teilausdrücken nicht durch ANSI 
standardisiert ist. D.h. der Ausdruck
i = 5;
a = f( i++, i, --i );
kann von verschiedenen Compilern unterschiedlich übersetzt werden und 
kein Compiler macht etwas falsch!
Die Auswertung von links nach rechts berechnet f( 5, 6, 5), die 
Auswertung von rechts nach links hingegen f( 4, 4, 4 ).

Deshalb rate ich von der Verwendung solcher Kurzschreibweisen 
grundsätzlich ab.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eProfi wrote:
> Zur Abwechslung eine theoretische Syntax-Frage:
> Gibt es eine Schreibweise ähnlich a=i++, die aber um einen anderen Wert
> als 1 erhöht?

a = (i += n)-n;

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a=(b=i, i+=n, b);

Sowas hat aber nur selten in Makros einen Sinn,
echte Profis schreiben keine Zuweisungen mitten in Ausdrücke.

Jürgen

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wer hat behauptet dass ich das so schreiben wuerde? Es war die Antwort 
auf die eingehende Frage. Leserlich wuerde man das so schreiben:

a = i;
i += n;

Autor: Jadeclaw Dinosaur (jadeclaw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mal sagen, solche Kurzschreibweisen sind Kandidaten für den 
'Obfuscated C Contest':
http://www.de.ioccc.org/main.html

Ich schreibe lieber leserlich und übersichtlich und überlasse das 
Optimierfummeln dem Compiler, der kann das eh viel besser. Dafür finde 
ich mich selbst nach Monaten in meinem völlig unkommentiertem Code nach 
kurzem Nachdenken noch zurecht. Da stört es mich auch nicht, wenn ich 
dadurch mehr tippen müßte.
Übrigens, gegen schmerzende Fingergelenke hilft eine gute Tastatur. ;-)

Gruß
Jadeclaw.

Autor: Tobias Plüss (hubertus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jadeclaw

> 'Obfuscated C Contest':
> http://www.de.ioccc.org/main.html

WOW! Echt krasser Code, den die Typen da geschrieben haben. Und DAS ist 
compilierbar? Mal Hand aufs Herz: blckst du bei dem Code, den man dort 
online anschauen kann, durch?
;-)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerade noch ausprobiert in meiner Ubuntu VM: 
http://homepages.cwi.nl/~tromp/tetris.html

Autor: Jadeclaw Dinosaur (jadeclaw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Tobias: Durchblicken? Keine Chance. Der Code muß aber lauffähig und 
mittels GCC compilierbar sein.
Aus der FAQ:
Q: What platform should I assume for my entry?
A: Your entry must compile with GCC and run under at least one flavor of 
UNIX (e.g. Linux or Solaris). To improve chances to win, it should work 
under both BSD and SysV style UNIX (think stty cbreak), and should not 
depend on endianness. If it can compile and run on Windows and/or Mac 
(see 2000/thadgavin), even better.

Gruß
Jadeclaw.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tobias Plüss wrote:
> @Jadeclaw
>
>> 'Obfuscated C Contest':
>> http://www.de.ioccc.org/main.html
>
> WOW! Echt krasser Code, den die Typen da geschrieben haben. Und DAS ist
> compilierbar?

Nicht alles und einiges nur unter Schmerzen ;)

Autor: Tobias Plüss (hubertus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jadeclaw

hmm, ich hab nirgends eine Beschreibung gefunden, was die Programme im 
Endeffekt eigentlich tun sollten. Oder bin ich blind?
Also zumindest aus dem Code kann ICHs nicht rauslesen ;-))))

@Michael
Auch mal wieder hier unterwegs? ;-)
> einiges nur unter Schmerzen ;)
Jau, Augenschmerzen vom Anblick des Codes ;-) (da fällt mir spontan 
www.augenkrebs.de.vu ein.... :p war jetzt ezwas OT, SCNR)

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt zu jedem Progamm eine .hint-Datei mit Hinweisen zum Programm. 
Manchmal steht da drin, was das Programm macht, oder zumindestens wie 
man das Programm übersetzen und ausführen muss, damit man merkt, das es 
macht.

Recht einfach zu verstehen ist das hier:
http://www.de.ioccc.org/years.html#1994_smr
Kategorie "Worst Abuse of the Rules", und gleichzeitig das kürzeste 
jemals eingereichte Programm.

Bei dem hier steht der Zweck nich im hint, aber man findet es schnell 
selbst raus:
http://www.de.ioccc.org/years.html#1988_robison
Berechnet wird die Eulersche Zahl, das Programm nimmt als Parameter die 
gewünschte Stellenzahl und das zu verendende Zahlensystem entgegen.

Und für einige Programme muss man nicht mal C können, weil sie auf dem 
Präprozessor beruhen:
http://www.de.ioccc.org/years.html#1994_westley
Sowas ist dann "Worst Abuse of the C Preprocessor", wenn ein komplettes 
Spiel nur mit dem Präprozessor gemacht wird...

Autor: Tobias Plüss (hubertus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  das kürzeste jemals eingereichte Programm

Sehe ich das richtig dass es sich aus einer einzigen leeren Datei 
zusammensetzt? die Datei ist jedenfalls leer wenn ich sie runterlad'...

Autor: Jorge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir den generierten Assemblercode an- Jörg Wunsch hat Recht.

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

Bewertung
0 lesenswert
nicht lesenswert
Tobias Plüss wrote:

> Sehe ich das richtig dass es sich aus einer einzigen leeren Datei
> zusammensetzt? die Datei ist jedenfalls leer wenn ich sie runterlad'...

Ja, darum ist es ja auch "worst abuse of the rules".  Der Kommentar
der Jury war ja auch, dass es streng genommen kein korrektes C-
Programm sei, aber eben auch kein inkorrektes...

Autor: Colonel Z (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Dass er das richtig optimiert, nämlich dass er _auf die Variable i nur
>einmal lesend zugreifen braucht.

Das muss der Compiler von selbst (unabhängig, wie du das schreibst) 
erkennen. Die meisten tun dies aber nicht. Erstens weil es (heute) nicht 
mehr notwendig ist und bestimmte Speicherzugriffe parallel zur Execution 
Unit (EU) ablaufen und zweitens, weil die Entwickler von 
Hochsprachen-Compilern auf solche "Kleinigkeiten" prinzipiell kein Auge 
werfen. Die Schreibweise (deiner Syntax) ist also egal, der Compiler 
macht es immer gleich schlecht...

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a=i;i+=n;

ist IMHO die Schreibweise, wo der Compiler (zumindest der GCC) den
besten Code generiert, außerdem ist sie auch vom Menschen lesbar. Fast
alle bisherigen Vorschläge sind schlechter lesbar, haben einen längeren
Quellcode (mehr Tipparbeit ;-)) und führen trotzdem zu schlechterem
Maschinencode. Es gibt also nicht einen einzigen Grund, diese
Verrenkungen anzustellen.

Wenn das Ganze - warum auch immer - unbedingt in einer einzelnen
Anweisung geschehen muss:
a=i,i+=n;

Der generierte Code ist gleich wie oben.

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.