Forum: Compiler & IDEs Verständnisfrage ==


von C-Anfaenger (Gast)


Lesenswert?

Hallo,

ich bin noch Anfänger und hab ein Verständnisproblem bei der if() 
Funktion mit ==

Ich nutzer den Cosmic Compiler für Freescale HCS12 Mikrocontroller.

Folgende if()-Abfrage funktioniert:
1
if( ( A & B ) == 0x00)
2
{
3
   mach_was();
4
}

Wenn ich aber schreibe:
1
if( A & B == 0x00)
2
{
3
   mach_was();
4
}

Wird nie zu "mach_was();" gegangen, es sieht sogar so aus als ob das 
weg-compiliert wird, ich kann da nicht mal einen Breakpunkt setzen in 
der 2. Variante, in der 1. Variante kann ich einen Breakpunkt setzen.

Ich lese zum lernen im Kernighan/Ritchie und da steht auf Seite 41 
eigentlich:

"Vergleiche haben geringeren Vorrang als arithmetische Operatoren. ..."

Ich verstehe das sicher falsch, aber es liest sich so, als wenn 
eigentlich beide Varianten der if()... das gleiche Ergebnis bringen 
sollten.

von Martin N. (emsen)


Lesenswert?

Klammern beachten!
Im ersten Beispiel: wenn A UND B den Wert 0 ergibt ...
Im zweiten Beispiel: wenn A=1 ist UND B=0 ist ...

von Peter II (Gast)


Lesenswert?

Martin N. schrieb:
> Klammern beachten!
> Im ersten Beispiel: wenn A UND B den Wert 0 ergibt ...
> Im zweiten Beispiel: wenn A=1 ist UND B=0 ist ...

wenn es wirklihc stimmt das

> "Vergleiche haben geringeren Vorrang als arithmetische Operatoren. ..."

dann hätte ich dieses verhalten aucn nicht erwartet.

von Klaus W. (mfgkw)


Lesenswert?

C-Anfaenger schrieb:
> ... bei der if() Funktion

es gibt keine if-Funktion.

C-Anfaenger schrieb:
> "Vergleiche haben geringeren Vorrang als arithmetische Operatoren. ..."

Eine korrekte Tabelle hilft mehr als Gerüchte:
http://www.wachtler.de/ck/11_Operatoren_Ausdrucke.html#sec:oper-und-ausdr

> Ich verstehe das sicher falsch, aber es liest sich so, als wenn
> eigentlich beide Varianten der if()... das gleiche Ergebnis bringen
> sollten.

Nein, tun sie nicht.
== steht höher als &.

von Micha S. (ernie)


Lesenswert?

C-Anfaenger schrieb:

Moin Moin,

> ich bin noch Anfänger und hab ein Verständnisproblem bei der if()
> Funktion mit ==
>
> Ich nutzer den Cosmic Compiler für Freescale HCS12 Mikrocontroller.
>
> Folgende if()-Abfrage funktioniert:
>
>
1
> if( ( A & B ) == 0x00)
2
> {
3
>    mach_was();
4
> }
5
>
>
> Wenn ich aber schreibe:
>
>
1
> if( A & B == 0x00)
2
> {
3
>    mach_was();
4
> }
5
>
>
> Wird nie zu "mach_was();" gegangen, es sieht sogar so aus als ob das
> weg-compiliert wird, ich kann da nicht mal einen Breakpunkt setzen in
> der 2. Variante, in der 1. Variante kann ich einen Breakpunkt setzen.
>
> Ich lese zum lernen im Kernighan/Ritchie und da steht auf Seite 41
> eigentlich:
>
> "Vergleiche haben geringeren Vorrang als arithmetische Operatoren. ..."
>
> Ich verstehe das sicher falsch, aber es liest sich so, als wenn
> eigentlich beide Varianten der if()... das gleiche Ergebnis bringen
> sollten.

== bindet staerker als &.
Gruesse,

Michael

von Stefan MM (Gast)


Lesenswert?

Liegt an Reihenfolge in der die Operatoren ausgeführt werde.

Oberster Prio haben Klammern. Dann kommen Vergleichsoperatoren, dann 
Bit-Operatoren.

Wenn die Klammern drinn sind wird zuerst A&B ausgeführt, und dann 
geprüft ob das Ergebnis == 0x00.


Lässt du die Klammern weg:
1. B==0x00
2. A & Ergebnis.

Die Auswertung in diesem falls ist also nur wahr wenn: B=0x00 und das 
LSB von a 1 ist.

Schau dir mal eine Präzidenztablle von C an. Da steht die 
auswertreihenfolge drinn.

Beste Grüße,

Stefan

von Michael B. (mb_)


Lesenswert?

Martin N. schrieb:
> Klammern beachten!
> Im ersten Beispiel: wenn A UND B den Wert 0 ergibt ...
> Im zweiten Beispiel: wenn A=1 ist UND B=0 ist ...

Halb richtig. Das zweite Beispiel wird implizit so geklammert:

if( A & (B == 0x00))
{
   mach_was();
}

Der if-Körper wird also ausgeführt, wenn B gleich 0 ist und das erste 
Bit (bit 0) in A gesetzt ist.

von C-Anfaenger (Gast)


Lesenswert?

Aha ... vielen Dank für die tollen Erklärungen ! Ich denke das ich das 
Problem jetzt verstehe. Vielen, vielen Dank.

von Jan M. (mueschel)


Lesenswert?

Noch zur Ergänzung:

> "Vergleiche haben geringeren Vorrang als arithmetische Operatoren. ..."

Dein Buch hat durchaus Recht, allerdings handelt es sich bei & nicht um 
einen arithmetischen Operator sondern um einen logischen.

+ und - haben Vorrang vor ==
und
== hat Vorrang vor & und |

von Yalu X. (yalu) (Moderator)


Lesenswert?

Jan M. schrieb:
> Dein Buch hat durchaus Recht, allerdings handelt es sich bei & nicht um
> einen arithmetischen Operator sondern um einen logischen.

Doch, & und | sind arithmetische Operatoren, denn sie rechnen mit
Zahlenwerten. Die logischen Operatoren in C heißen && und ||.

Die nicht ganz nachvollziehbaren Präzedenzregeln für & und | haben
historische Gründe. Dennis Ritchie beschreibt hier die Zwickmühle, in
der er sich damals befand:

  http://www.lysator.liu.se/c/dmr-on-or.html

von Rolf Magnus (Gast)


Lesenswert?

Yalu X. schrieb:
> Jan M. schrieb:
>> Dein Buch hat durchaus Recht, allerdings handelt es sich bei & nicht um
>> einen arithmetischen Operator sondern um einen logischen.
>
> Doch, & und | sind arithmetische Operatoren, denn sie rechnen mit
> Zahlenwerten.

C spricht hier nicht von arithmetischen, sondern von bitweisen 
Operatoren. Sie arbeiten ja auch nicht mit den Zahlenwerten, sondern nur 
mit den einzelnen Bits.
Ich würde & und | nicht als arithmetische Operatoren betrachten.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf Magnus schrieb:
> Ich würde & und | nicht als arithmetische Operatoren betrachten.

Das ist Geschmackssache. Ich würde die bitweisen Operationen als eine
Teilmenge der arithmetischen betrachten.

Auf jeden Fall sind & und | für mich (und auch für den C-Standard) keine
logischen Operatoren, denn logische Operationen liefern immer "wahr"
order "falsch" (bzw. 1 oder 0), aber niemals eine Zahl wie 27583.

von ernst (Gast)


Lesenswert?

...das es immer noch Leute gibt, welche sich freiwillig diesen 
unübersichtlichen und unvorhersehbare Resultate erzeugenden "C"-Unfug 
antun... Dieser Treppenwitz der EDV-Geschichte sollte doch langsam ins 
Kuriositätenkabinett verbracht werden und zukünftigen Generationen von 
"Compilerbauern" und "Sprachkonstrukteuren" als abschreckendes Beispiel 
dienen, wie man's nicht machen sollte!

(duck und wech ;-)

von Karl H. (kbuchegg)


Lesenswert?

ernst schrieb:
> ...das es immer noch Leute gibt, welche sich freiwillig diesen
> unübersichtlichen und unvorhersehbare Resultate erzeugenden "C"-Unfug
> antun... Dieser Treppenwitz der EDV-Geschichte sollte doch langsam ins
> Kuriositätenkabinett verbracht werden und zukünftigen Generationen von
> "Compilerbauern" und "Sprachkonstrukteuren" als abschreckendes Beispiel
> dienen, wie man's nicht machen sollte!
>
> (duck und wech ;-)

Wird auch gut sein.
Nichts von alledem, was du da dahergebrabbelt hast, ist korrekt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> C-Anfaenger schrieb:
>> ... bei der if() Funktion
> es gibt keine if-Funktion.
Na gut, dann eben bei der if-Schleife... ;-)

von Klaus W. (mfgkw)


Lesenswert?

sowas etwa?
1
#include <stdio.h>
2
3
#define if while
4
5
int main( int nargs, char **args )
6
{
7
  char *p = "Hallo\n";
8
9
  if( *p )
10
  {
11
    putchar( *p++ );
12
  }
13
14
  return 0;
15
}

von Rolf Magnus (Gast)


Lesenswert?

Yalu X. schrieb:
> Rolf Magnus schrieb:
>> Ich würde & und | nicht als arithmetische Operatoren betrachten.
>
> Das ist Geschmackssache. Ich würde die bitweisen Operationen als eine
> Teilmenge der arithmetischen betrachten.

Viele Assembler-Dokumentationen sehen das anders. Da sind die 
entsprechenden Instruktionen i.d.R. unter den logischen Instruktionen 
einsortiert, oder sie sind - wie beim AVR - zusammen mit den Additionen 
u.s.w. unter einer gemeinsamen Kategorie "arithmetische und logische 
Instruktionen" zu finden.

> Auf jeden Fall sind & und | für mich (und auch für den C-Standard) keine
> logischen Operatoren,

Für C sind sie auch keine arithmetischen.

> denn logische Operationen liefern immer "wahr" order "falsch" (bzw. 1
> oder 0), aber niemals eine Zahl wie 27583.

Die arithmetischen Operationen dagegen interpretieren immer eine 
Kombination mehrerer Bits als eine zusammenhängende Zahl. & und | tun 
das nicht. Sie betrachten jedes Bit einzeln, unabhängig von den anderen. 
Daß man den "bithaufen", der hinten rauskommt, dann wieder als Zahl 
interpretieren kann, ändert daran nichts.

Klaus Wachtler schrieb:
> #define if while

Das ist ja getürkt. So sieht eine richtige if-Schleife aus:
1
#include <stdio.h>
2
3
int main( int nargs, char **args )
4
{
5
  char *p = "Hallo\n";
6
7
Loop:
8
  if( *p )
9
  {
10
    putchar( *p++ );
11
    goto Loop;
12
  } 
13
14
  return 0;
15
}

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:

> Das ist ja getürkt. So sieht eine richtige if-Schleife aus:

Das war eine goto-Schleife. Eine if-Schleife geht so:
1
int f( char *p )
2
{
3
  fputchar( *p++ );
4
  if( *p ) f( p );
5
}
Wenn du nicht glaubst, dass sei eine Schleife, dass zieh es mal durch 
GCC.

von Klaus W. (mfgkw)


Lesenswert?

ja, zumindest mit f( -1 ) geht das echt ab!

von Klaus W. (mfgkw)


Lesenswert?

Außerdem ist die "Schleife" ja eigentlich nicht recht im if drin, nur im 
Block daran.

Wie wäre es damit:
1
   int f( int n )
2
   {
3
      if( !f( --n ) ) return n;
4
      else return 0;
5
   }
?

von (prx) A. K. (prx)


Lesenswert?

Klaus Wachtler schrieb:

> Wie wäre es damit:

Bös Ressourcen fressend. Meine Version ist effizienter. Kommt (via GCC 
-O) exakt der gleiche Code raus wie bei do..while.

von Rolf Magnus (Gast)


Lesenswert?

A. K. schrieb:
> Das war eine goto-Schleife.

Eine if-Schleife mit goto. ;-)

> Wenn du nicht glaubst, dass sei eine Schleife, dass zieh es mal durch
> GCC.

Das ist keine Schleife, sondern Rekursion.

von Peter II (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Das ist keine Schleife, sondern Rekursion.

ich vermute mal das es genau das nicht ist, dann es gibt keine lokalen 
variablen der compiler macht daraus eine entlosschleife ohne calls

von Rolf Magnus (Gast)


Lesenswert?

Es bleibt eine Rekursion, auch wenn es einen Compiler gibt, der das im 
Zuge seiner Optimierung durch eine Schleife ersetzt.

von (prx) A. K. (prx)


Lesenswert?

Peter II schrieb:

> ich vermute mal das es genau das nicht ist, dann es gibt keine lokalen
> variablen der compiler macht daraus eine entlosschleife ohne calls

In Prinzip korrekt, aber dank des if ist es keine Endlosschleife, 
sondern do..while. Der Compiler ersetzt die Endrekursion. In der anderen 
Variante ist es keine Endrekursion und daher ist auch der erzeugte Code 
rekursiv.

von Sam .. (sam1994)


Lesenswert?

Lothar Miller schrieb:
> Klaus Wachtler schrieb:
>> C-Anfaenger schrieb:
>>> ... bei der if() Funktion
>> es gibt keine if-Funktion.
> Na gut, dann eben bei der if-Schleife... ;-)

http://www.if-schleife.de/

von Klaus W. (mfgkw)


Lesenswert?

Danke, man lernt nie aus!
Jetzt weiß Lothar es auch... :-)

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.