Forum: Compiler & IDEs unverständliches Kauderwelsch


von dennis (Gast)


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

von wayne (Gast)


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.

von Marius (Gast)


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

von Irgwer (Gast)


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.

von dennis (Gast)


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

von Ewald K. (ebtschi)


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;
}

von dennis (Gast)


Lesenswert?

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

von Ewald K. (ebtschi)


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.

von Mario Schrenk (Gast)


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

von dennis (Gast)


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

von Ulrich (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


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)

von Feadi (Gast)


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

von Christian Spahn (Gast)


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.

von Simon Küppers (ohne Login) (Gast)


Lesenswert?

@ Christian:
ABER nur dann, wenn MAX = 8 ist !

von Ulrich (Gast)


Lesenswert?

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

von ,,,, (Gast)


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.

von dennis (Gast)


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

von The Daz (Gast)


Lesenswert?

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

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

...oder den C-Code erst durch das Makefile erzeugen lassen ;-)

von Marco S (Gast)


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
-

von ---- (Gast)


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

von dennis (Gast)


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"

von Marco S (Gast)


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
-

von ---- (Gast)


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

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


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?
1
if (((a == 3) && (b == 5)) || ((x < (5 + (3 * CONST))))) {
2
...
3
}

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

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:
1
#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.

von ---- (Gast)


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

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


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.

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.