www.mikrocontroller.net

Forum: Compiler & IDEs unverständliches Kauderwelsch


Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich hab hier grad ein Listing mit ner Zeile dich ich nicht kapiere.

#define MAX 8
int add(int i)
{
 return (i+1) == MAX ? 0 : i+1;
}

Versteh nur Bahnhof und hab noch keine Lösung gefunden

thx
dennis

Autor: wayne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define MAX 8

-> Definiert eine Konstante MAX mit Wert 8

int add(int i)
{
 return (i+1) == MAX ? 0 : i+1;
}

ist, glaube ich , so zu verstehen:

int add(int i)
{
  if (i+1) = MAX then return 0
  else return i+1
}

aber meine C-Kenntnisse sind eher grottig.

Autor: Marius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
das gleiche mit einer if:

#define MAX 8
int add(int i)
{
 if (i+1 == MAX)
   return 0;
 else
   return i+1;
}

Hoffe das dir das hilft

Autor: Irgwer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich schreibs mal mit anderen Worten auf:

falls der Aufrufparameter der Funktion 'add' schon 8 ist, dann gib 0
zurück, andernfalls den um eins erhöhten Aufrufparameter.

Vermute mal dieser Code (im Wahrsten Sinne des Wortes) stammt aus einem
Programm welches sich mit Ringspeichern beschäftigt.

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>aber meine C-Kenntnisse sind eher grottig.
Wie sind dann meine wenn du das schon entziffern kannst

>Hoffe das dir das hilft
Sicher hilft mir das.

Danke an Euch beide
dennis

Autor: Ewald Kantner (ebtschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, ich erlaub mir mal, das Ganze in etwas leichter lesbaren, aber
equivalenten Code zu "übsersetzen":

#define MAX 8
int add(int i)
{
 if(i+1==MAX)
  return 0;
 else
  return i+1;
}

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ergibt das nachher dann eigentlich identischen Code oder gibts da dann
noch Unterschiede in der Codegröße oder Ausführungsgeschwindigeit?

Autor: Ewald Kantner (ebtschi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puh, gute Frage. Ich glaube (Achtung: glauben != wissen), dass da
identischer Maschinencode erzeugt wird. Kann aber u. A.
compilerabhängig sein.

Am besten probierst du beide Varianten aus, und siehst dir danach das
Assembler-Listing an. Das Ergebnis würde mich auch interessieren.

Autor: Mario Schrenk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mal 'ne andere Frage: Würde

 return ((i+1) % MAX);

also eine Operation Modulo MAX nicht das gleiche bewirken (außer bei
Aufrufen mir Werten > MAX)? Auch hier wäre dann die Frage nach
Codegröße und Ausführungsgeschwindigkeit. Oder hat der Programmierer
des obigen Codes nur seine Unkündbarkeit im Sinn ;-)

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder hat der Programmierer
>des obigen Codes nur seine Unkündbarkeit im Sinn ;-)

Gute Frage, nächste Frage. Is aber ne gute Idee. Muß ich mal testen

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jetzt wäre es interessant ob da der Compiler das gleiche macht....:
return ((i+1) % MAX);

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm die Modulo Variante dauert aber länger, da hier eine division gemacht
wird. Bei MAX = 8 würde ich zwar sagen dass er statt einer Division
shifts macht, aber wenn MAX was anderes als 8 ist, dann muss die
Divisions Routine her (Abziehen, inkrementieren.. Rest)

Autor: Feadi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define MAX 8
int add(int i)
{
 return (i+1) == MAX ? 0 : i+1;
}

Ich sags mal so:
add(0) ergibt 1
add(1) ergibt 2
...
add(5) ergibt 6
add(6) ergibt 7
add(7) ergibt 0
add(8) ergibt 9
add(9) ergibt 10

--------------------

Das "return ((i+1) % MAX)" sieht aber so aus:
add(0) ergibt 1
...
add(6) ergibt 7
add(7) ergibt 0
add(8) ergibt 1
add(9) ergibt 2


Feadi

Autor: Christian Spahn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich gerade mal (AVR) Compiler spiele, würde ich aus "(i+1) % MAX"
(mit MAX = 8) folgende zwei Befehle machen:

inc r16
andi r16, 0x07

Fertig. Eine Division braucht man da nicht! Die andere Lösung mit
Vergleich und Sprung wird mindestens doppelt so lang.

Aber wenn die Funktion nicht ständig in einer Schleife aufgerufen wird,
macht sich der Geschwindigkeitsunterschied wohl kaum bemerkbar.

Autor: Simon Küppers (ohne Login) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian:
ABER nur dann, wenn MAX = 8 ist !

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon:
Das von Christian passt schon. Das kann man so auch aufrufen wenn man
erst bis 5 gezählt hat....

Autor: ,,,, (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> int add(int i)
> {
> return (i+1) == MAX ? 0 : i+1;
> }

So programmieren nur Angeber, die anderen unbedingt zeigen wollen, dass
sie Ahnung von C haben.

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das würde ich jetzt nicht behaupten. So wie ich das jetzt sehe
nachdem ich ein buch und ein paar Tutorials gelesen hab ist das
durchaus ne reguläre Syntax. Das wäre Angeben

for(;P("\n").R-;P("|"))for(e=3DC;e-;P("_"+(*u++/8)%2))P("|
"+(*u/4)%2);

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder noch schlimmer : Im code 1000 Makros verwenden, die im makefile
definiert werden.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...oder den C-Code erst durch das Makefile erzeugen lassen ;-)

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie dennis sehe ich das auch. Wer mal "angeberischen" C-Code sehen
will, kann unter www.ioccc.org nachsehen. Für den Rest der Welt gehört
der ternäre Operator ?: zu C dazu, wie auch die if-Entscheidung. Ein
Vorteil des return-?:-Konstrukts ist die platzsparende Schreibweise,
welches die lesbarkeit ERHÖHT!

Vergleichen wir das mal mit einem Autofahrer. Dieser nähere sich einem
Stoppschild. "Hui" sagt er, "dass kann ich nicht." und fährt lieber
dreimal mehr rechts und viermal links um an dasselbe Ziel zu kommen. Was
würde wohl ein Beifahrer davon halten?


Gruß
Marco
-

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um mal dein Beispiel aufzugreifen:
Was würde der Beifahrer denken, wenn der Autofahrer erstmal 10min am
Verkehrsschild halten müsste, um zu entziffern, dass es ein Stoppschild
ist...

Der ternäre Operator ? gehört natürlich zu C dazu, so wie alle anderen
Terme in diesem Ausdruck auch. Aber die Kombination macht es
unleserlich. Wir diskutieren hier ja nicht darüber, ob das syntaktisch
korrekt ist oder nicht.

> return (i+1) == MAX ? 0 : i+1;
was bindet dabei mehr? Das "==" oder der "?"-Operator? Eine Klammer
mehr würde da vieles deutlicher machen...

----, (QuadDash).

Autor: dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mal gelesen "C ist wie Geschichte in der Schule. Um es zu
können muß man auswendig lernen".

Wenn man sich die Syntax so anschaut muß ich dem Recht geben. Rein aus
der Syntax kann man nicht wirklich auf die Funktion rückschließen.
Anderen Sprachen sind "sprechender"

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@----

Eben dass meine ich. Wer C gelernt hat, braucht keine 10min für das
Stoppschild. Dass es Prioritäten gibt, sollte man wissen, zur Not auch
nur, wo sie stehen.

In der Tat würde eine Klammer mehr die Lesbarkeit für Anfänger
fördern.

i+1 == MAX ? 0 : i+1  <=> ((i+1) == MAX) ? 0 : (i+1)

Und wenn man bei so einer Sache knobeln muss, ist das meiner Meinung
nach eine der besten Möglichkeiten zu lernen.


Gruß
Marco
-

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Stoppschild ist aber so verschleiert, dass man es erst nach 10min
als solches erkennt, selbst wenn man weiss wie eins aussieht... ;-)

> Und wenn man bei so einer Sache knobeln muss, ist das meiner Meinung
> nach eine der besten Möglichkeiten zu lernen.
Nein, das ist die Garantie, dass Fehler passieren. Der Code ist für den
Menschen geschrieben und muß damit einfach lesbar sein.

80% aller C-Programmierer glauben sie seien überdurchschnittlich gut,
die restlichen 20% denken sie seien weit überdurchschnittlich.

> In der Tat würde eine Klammer mehr die Lesbarkeit für Anfänger
> fördern.
Das klingt leicht überheblich. (Auch wenns wahrscheinlich nicht so
gemeint war).

> Dass es Prioritäten gibt, sollte man wissen, zur Not auch
> nur, wo sie stehen.
Nein, man sollte Unklarheiten vermeiden, dann spart man sich auch das
nachschauen.

----, (QuadDash).

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

Bewertung
0 lesenswert
nicht lesenswert
>> Dass es Prioritäten gibt, sollte man wissen, zur Not auch nur, wo
>> sie stehen.

> Nein, man sollte Unklarheiten vermeiden, dann spart man sich auch
> das nachschauen.

Naja.  Bedingt.  Was findest du besser lesbar?
if (((a == 3) && (b == 5)) || ((x < (5 + (3 * CONST))))) {
...
}

oder
if ((a == 3 && b == 5) || (x < 5 + 3 * CONST)) {
...
}

Ich finde eindeutig das Zweite besser lesbar.  Dass Punktrechnung vor
Strichrechnung geht, haben wir schon in der Grundschule gelernt, und
alle mir bekannten Programmiersprachen halten sich dran.  Dass C die
Operatorenreihenfolge für logisch verkettete Vergleiche vernünftig auf
die Reihe bekommen hat (anders als Pascal), kann man sich m.E. genau
so gut merken, d.h. a < 5 && b > 3 funktioniert so, wie man sich das
auch vorstellt (die Vergleiche binden stärkere als die logische
Verknüpfung von deren Ergebnissen).  Ob nun && oder || die höhere
Priorität hat, ist dagegen wirklich nicht unbedingt einleuchtend und
leicht zu erinnern (auch wenn es definiert ist), daher sollte man das
wohl wirklich immer klammern.

Gleichermaßen kann man sich m.E. auch ganz gut merken, dass es im
Prinzip (*) nur noch einen Operator gibt, der weniger bindet als ?:,
das ist der Komma-Operator.  Alle Teilausdrücke innerhalb von ?: sind
damit praktisch immer ,,fester'' gebunden, was durchaus auch dem
Sinn
dieses Operators entspricht.

(*) Dazwischen stehen noch die kombinierten Operations- und
Zuweisungsoperatoren, also += usw., die spielen hier eine eher
untergordnete Rolle.

Ein sehr gängiges Beispiel für die Sinnfälligkeit des ?:-Operators
dürfte eine mögliche Implementierung eines MAX-Makros sein:
#define MAX(a, b) ((a) > (b)? (a): (b))

Da es sich hier um einen Makro handelt, sollte man die expandierten
Argumente jedoch immer klammern, da man ja nie weiß, was der Aufrufer
darin schreibt.  Das größte Problem dieses Makros ist übrigens, dass
er seine Argumente zwei Mal bewertet, er hat also einen Seiteneffekt,
daher per Konvention die Großschreibung.

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was findest du besser lesbar?
Geringfügig das Zweite.

Wenn man sich stur an die Klammernschreiberei hält, dann muß man auch
nicht (erneut) nachdenken, wenn man die Zeile mal ändert.

Aber ursprünglich gings ja um den Ausdruck:
return (i+1) == MAX ? 0 : i+1;
Und da isses vorbei mit Grundschul-Punkt-vor-Strich-Wissen. Dieser
Ausdruck an sich ist schon so kompliziert, daß er IMHO aufgeteilt
werden muss!
Mehr Code würde eine Aufteilung übrigens auch nicht produzieren wie
dieser "verdichtete" C-Knäuel.

----, (QuadDash).

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

Bewertung
0 lesenswert
nicht lesenswert
> Wenn man sich stur an die Klammernschreiberei hält, dann muß man
> auch nicht (erneut) nachdenken, wenn man die Zeile mal ändert.

Das könnte man auch gut als Argument gegen überflüssige Klammern
ansehen. ;-)  Wenn jemand bei einer Änderung nicht erneut über das
Problem nachdenkt, begibt er sich auf einen gefährlichen Weg...
Wenn die fehlenden Klammern also wirklich das Nachdenken fördern,
dann sollten sie bitte schön auch weggelassen werden. :-)

> Und da isses vorbei mit Grundschul-Punkt-vor-Strich-Wissen.

Zusammen mit dem Wissen darum, dass ?: praktisch keine Prioriät hat:
überhaupt nicht.

Ich hätte das vermutlich in einen Makro ausgelagert und ihm einen
Namen gegeben, der die Intention vernünftig beschreibt, aber ansonsten
kann das gut die simpelste Lösung für ein bestimmtes Problem sein.
Dass die Modulo-Variante keineswegs gleiche Funktionalität hat, sollte
ja mittlerweile klar geworden sein.

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.