Forum: Mikrocontroller und Digitale Elektronik Prüfen ob Wert zwischen zwei Werten liegt


von Mike (Gast)


Lesenswert?

Gibt es in Ceine einfache Möglichkeit zu überprüfen ob ein Wert zwischen 
zwei Werte liegt?

Ich dachte  da an
1
if (x < wert < y)

Aber so funzt das leider nicht.

Danke euch schonmal

von Oliver R. (orb)


Lesenswert?

if ((wert > x) & (wert < y))

von cc (Gast)


Lesenswert?

Oliver R. schrieb:
> if ((wert > x) & (wert < y))
oder (wenn man logisch rangeht)
if ((wert > x) && (wert < y))

von Mike (Gast)


Lesenswert?

genau das wollte ich vermeiden da ich mehrere werte zu überprüfen habe 
und die if somit kilometerlang wird :-/
aber wenn das die einzige möglichkeit ist bleibt mir nichts anderes.
Dankeschön.

von cc (Gast)


Lesenswert?

Mike schrieb:
> genau das wollte ich vermeiden da ich mehrere werte zu überprüfen
> habe
> und die if somit kilometerlang wird :-/
> aber wenn das die einzige möglichkeit ist bleibt mir nichts anderes.
> Dankeschön.

Dann mach doch eine Funktion, der du "wert" als Variable übergibst. In 
der Funktion prüfst du dann auf die Grenzwerte und gibst "true" oder 
"false" zurück. Je nachdem, ob "wert" innerhalb oder außerhalb der 
Grenzen liegt.

von Wolfgang A. (Gast)


Lesenswert?

Mike schrieb:
> genau das wollte ich vermeiden da ich mehrere werte zu überprüfen habe
> und die if somit kilometerlang wird :-/

Wie wäre es, wenn du deine zu überprüfenden Daten in ein Array packst 
und den Vergleich in einer Schleife ausführst. Dann muss der Prozessor 
allenfalls stundenlang in der Programmschleife durch das Array toben.

von Possetitjel (Gast)


Lesenswert?

Mike schrieb:

> genau das wollte ich vermeiden da ich mehrere werte
> zu überprüfen habe und die if somit kilometerlang
> wird :-/

Nicht unbedingt.

Wahrheitswert explizit in Variable speichern. In Schleife
Wert und Intervall aus Tabelle/Array lesen, neuen Wahrheitswert
bestimmen, mit altem Wahrheitswert passend verknüpfen.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Schon mal das Wort Rekursion gehört oder den Begriff Funktion?
Alternativ Subroutine?


Packe deinen Algorythmus in eine Funktion / Subroutine

zum beispiel


include stbool.h



void main()

.
.
.


for (i=1,i<imax;i++),
{
print fensterdiskriminator (Xdat[i];Zmax[i];Ymin[i]);
}
.
.
.

loop;




bool fensterdiskriminator (dat, max,min)

{
    if(dat <= max || min<= dat)
    return false;
    else return true;
    endif;
};

von B. S. (bestucki)


Lesenswert?

Mike schrieb:
> genau das wollte ich vermeiden da ich mehrere werte zu überprüfen habe
> und die if somit kilometerlang wird :-/

Spielt doch keine Rolle. Mit entsprechender Formatierung ist das 
trotzdem lesbar:
1
if(
2
  (Wert        > x) && (Wert        < y) &&
3
  (AndererWert > x) && (AndererWert < y) &&
4
  (Nochwas     > x) && (Nochwas     < y) &&
5
  /* usw. */
6
){
7
  /* tu was */
8
}

Wie die genaue Formatierung aussieht, ist Geschmackssache. Die 
Überprüfung kann man alternativ auch in eine eigene Funktion packen, 
damit der restliche Code besser zu lesen ist. Am besten in das gleiche 
Sourcefile und als static definieren, dann wird das der Compiler 
wahrscheinlich inlinen.

von Mike (Gast)


Lesenswert?

Auf die Idee mit der Funktion könnte ich auch selber kommen.... :-D
Ok, danke euch.

von #define (Gast)


Lesenswert?

Die Kür ist aber ein Makro. Weil schneller, weil es den Sinn besser 
wieder gibt, weil es gut lesbar ist.

von Sebastian (Gast)


Lesenswert?

#define schrieb:
> Die Kür ist aber ein Makro.

Mit dem Nachteil dass Seiteneffekte im Parameter, der mehrfach 
auftaucht, auch mehrfach passieren.

von Sebastian (Gast)


Lesenswert?

cc schrieb:
> if ((wert > x) && (wert < y))

Umsortiert sieht es dem Original etwas ähnlicher:
1
if ( x <      wert      < y)
2
if ((x < wert) && (wert < y))

von #define (Gast)


Lesenswert?

Sebastian schrieb:
> #define schrieb:
> Die Kür ist aber ein Makro.
>
> Mit dem Nachteil dass Seiteneffekte im Parameter, der mehrfach
> auftaucht, auch mehrfach passieren.

??? Kann er das näher erläutern?

von avr (Gast)


Lesenswert?

#define schrieb:
> Sebastian schrieb:
>> #define schrieb:
>> Die Kür ist aber ein Makro.
>>
>> Mit dem Nachteil dass Seiteneffekte im Parameter, der mehrfach
>> auftaucht, auch mehrfach passieren.

Und mit dem Vorteil, dass es nicht typgebunden ist - also die Funktion 
eines templates in c++ erfüllen kann.

> ??? Kann er das näher erläutern?

Wenn man Makros z.B. mit Zuweisungen aufruft. MAKRO(i++) könnte i 
mehrfach erhöhen, da es nur eine Textersetzung ist.

von B. S. (bestucki)


Lesenswert?

#define schrieb:
> Die Kür ist aber ein Makro. Weil schneller, weil es den Sinn besser
> wieder gibt, weil es gut lesbar ist.
Das wurde hier schon einige Male diskutiert:
Beitrag ""C" Makro vs. Funktion"
Beitrag "Unterschied #define und Funktion?"
http://www.mikrocontroller.net/articles/Makro

#define schrieb:
> ??? Kann er das näher erläutern?
http://www.mikrocontroller.net/articles/C-Pr%C3%A4prozessor#m.C3.B6gliche_Probleme_beim_Einsatz_des_Pr.C3.A4prozessors

avr schrieb:
> Und mit dem Vorteil, dass es nicht typgebunden ist - also die Funktion
> eines templates in c++ erfüllen kann.
Was früher oder später durch Unachtsamkeit zu folgender Warnung führen 
wird (jedoch nur, wenn man sie auch einschaltet):
1
[Warning] comparison between signed and unsigned integer expressions [-Wsign-compare]

von Makro (Gast)


Lesenswert?

#define schrieb:
> Sebastian schrieb:
>> #define schrieb:
>> Die Kür ist aber ein Makro.
>>
>> Mit dem Nachteil dass Seiteneffekte im Parameter, der mehrfach
>> auftaucht, auch mehrfach passieren.
>
> ??? Kann er das näher erläutern?

Wenn "wert" z.B. der Rückgabewert von einem Funktionsaufruf ist, wird 
bei
1
if ((wert() > x) && (wert() < y))
die Funktion mehrfach aufgerufen. In einen Makro verpackt, sieht man das 
dann an der aufrufenden Stelle im Programmcode nicht mehr 
offensichtlich. Wenn in der Funktion wert() dann noch andere Dinge 
passieren, werden diese doppelt angestoßen.

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


Lesenswert?

Mike schrieb:
> genau das wollte ich vermeiden da ich mehrere werte zu überprüfen habe
> und die if somit kilometerlang wird :-/
Hast du mehrere vollkonmmen unabhängige Werte zu vergleichen (1), oder 
soll nur ein fester Wert irgendwo eingeordnet werden (2)?
So also (1):
1
  if (  10  < temperatur  && temperatur < 20 
2
     && 100 < druck       && druck      < 200 
3
     && 40  < wasser      && wasser     < 60 
4
     && 78  < oel         && oel        < 87
5
     ) ...

Oder so (2):
1
   if      ( 10 <= temperatur  && temperatur < 20 ) ...
2
   else if ( 21 <= temperatur  && temperatur < 30 ) ...
3
   else if ( 31 <= temperatur  && temperatur < 40 ) ...

Denn im ersten Fall gibt es kaum Abhilfe, den zweiten Fall könnte man 
aber evtl. durch eine Formel abbilden:
1
   tempbereich = temperatur/10;
2
   if      ( tempbereich == 1 ) ...
3
   else if ( tempbereich == 2 ) ...
4
   else if ( tempbereich == 3 ) ...
Oder stufenweise abfragen:
1
   if      ( 10 <= temperatur  && temperatur < 20 ) ...
2
   else if ( temperatur < 30 ) ... // ist hier sowieso mindestens 21
3
   else if ( temperatur < 40 ) ... // ist hier sowieso mindestens 31

: Bearbeitet durch Moderator
von F. F. (foldi)


Lesenswert?

Na da bin ich froh, dass Leute wie Lothar das auch so machen.
Da ich ja noch nicht viel programmiert habe, immer noch lerne, mache ich 
das auch so.
Vielen Dank, das gibt mir wieder etwas Sicherheit.
Für mich ist erstmal wichtig, dass der µC am Ende das tut was ich will. 
Das Programm kann ja eh keiner sehen. ;-)

von PittyJ (Gast)


Lesenswert?

Man könnte auch in C++ den < Operator überladen, dass er einen int statt 
eines bool zurückgibt.
Damit kann man doch bestimmt weiter spielen, so dass der erste Versuch
if (x < wert < y)
auch funktioniert.

von Daniel A. (daniel-a)


Lesenswert?

PittyJ schrieb:
> Man könnte auch in C++ den < Operator überladen, dass er einen int statt
> eines bool zurückgibt.

Nein, das geht nicht, da für das überladen eines globalen operators 
mindestens ein benutzerdefinierter type angegeben werden muss, und somit 
ein operator<(int a,int b){return b-a;} unzulässig ist. Ausserdem 
evaluiert jeder wert ungleich 0, also auch negative werte zu true. Es 
währe also ein benutzerdefinierter type mit überladenem < operator, 
einem einem constructor(const int&) und einem globalen 
operator=(bool&,const type&) nötig.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Der GCC kann beim Switch Bereiche testen:
1
  switch( val ){
2
    case 1 ... 15: blub(); break;
3
    case 30 ... 300: blab(); break;
4
    case 20 ... 27: blib(); break;
5
  }

von Dirk B. (dirkb2)


Lesenswert?

Makro schrieb:
> Wenn "wert" z.B. der Rückgabewert von einem Funktionsaufruf ist, wird
> beiif ((wert() > x) && (wert() < y))
> die Funktion mehrfach aufgerufen. In einen Makro verpackt, sieht man das
> dann an der aufrufenden Stelle im Programmcode nicht mehr
> offensichtlich. Wenn in der Funktion wert() dann noch andere Dinge
> passieren, werden diese doppelt angestoßen.

Nicht unbedingt.
Wenn beim ersten Aufruf das Ergebnis <= x ist, ist das Ergebnis der 
Bedingung schon bekannt² (unwahr) und somit wird auf den Vergleich mit y 
verzichtet.


² beim && müssen beide Operanden wahr sein

von #define (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Der GCC kann beim Switch Bereiche testen:  switch( val ){
>     case 1 ... 15: blub(); break;
>     case 30 ... 300: blab(); break;
>     case 20 ... 27: blib(); break;
>   }

Das ist kein Standard C.

von Peter D. (peda)


Lesenswert?

#define schrieb:
> Das ist kein Standard C.

Niemand zwingt Dich, es zu benutzen.

von F. F. (foldi)


Lesenswert?

Peter Dannegger schrieb:
> Der GCC kann beim Switch Bereiche testen:
>
1
>   switch( val ){
2
>     case 1 ... 15: blub(); break;
3
>     case 30 ... 300: blab(); break;
4
>     case 20 ... 27: blib(); break;
5
>   }
6
>

Hallo Peter,

du hast hier ja schon so einiges beigetragen und deine Kompetenz ist, so 
denke ich, unbestritten. Danke für dieses Beispiel. Das werde ich wohl 
auch mal probieren.

Beitrag #7691781 wurde von einem Moderator gelöscht.
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.