www.mikrocontroller.net

Forum: PC-Programmierung Variable begrenzen in C


Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich habe eine Variable int a und möchte, dass diese maximal den Wert 
10000 annimmt, egal wie oft ich a++ rechne. Kann man das irgendwie am 
Anfang deklarieren?

Ich schreibe in C

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein.

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int nA;

if (nA < 10000) nA++;

oder

nA++;
if (nA > 10000) nA = 10000;

oder

nA++;
nA = nA % 10001;


mfg.

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib einfach:
   ink(a);  // Anstelle von a++;
[c]

und verwende folgende Funktion:

[c]
int ink(int a)
{
  return (++a > 10000) ? 10000 : a; 
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen schrieb:
> ink(a);  // Anstelle von a++;

Wenn schon, dann:
a = ink( a );

Autor: Schorsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
template<int maximum> class limited_int {
public:
...
  limited_int<maximum> operator++...
...
private:
  unsigned int value;
}
oder so...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
genau, vor allem in C.

Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für die vielen Möglichkeiten, die

if anweisung ist perfekt für mich!

Autor: sebastians (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann man das irgendwie am Anfang deklarieren?
nein.

> die if anweisung ist perfekt für mich!
Da ist aber nichts am Anfang deklariert.

Autor: D. I. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen schrieb:
> Schreib einfach:
>
>    ink(a);  // Anstelle von a++;
> [c]
> 
> und verwende folgende Funktion:
> 
> [c]
> int ink(int a)
> {
>   return (++a > 10000) ? 10000 : a;
> }
> 

Was wohl passiert wenn a = 2^31-1 ist?! ;) Ich denke man sollte a nicht 
verändern wenn 10000 ereicht wurde.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es konsequent auf 10000 limitiert wird, erscheint mir 2^31-1
eher unwahrscheinlich.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D. I. schrieb:
> Was wohl passiert wenn a = 2^31-1 ist?! ;) Ich denke man sollte a nicht
> verändern wenn 10000 ereicht wurde.

Eher so:

unsigned int ink(unsigned int a, unsigned int maximum)
{
    return (a++ > maximum - 1) ? maximum : a;
}

Autor: Sequence Point (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> return (a++ > maximum - 1) ? maximum : a;

So, und hier die Frage an die C-Standard-Versteher:

Ist der Rückgabewert davon jetzt a oder a+1 (für a < maximum)?

Autor: Freak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Kann man das irgendwie am Anfang deklarieren?
>nein.

>> die if anweisung ist perfekt für mich!
>Da ist aber nichts am Anfang deklariert.


Ja gerade, weil es nicht geht, muss ich wohl mit der if anweisung 
leben...

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie wär's damit?

[c]
...
ink(&a);
....

void ink(int *a){
   if(*a<10000)(*a)++;
}
[\c]

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sequence Point schrieb:
> Samuel K. schrieb:
>
>> return (a++ > maximum - 1) ? maximum : a;
> 
>
> So, und hier die Frage an die C-Standard-Versteher:
>
> Ist der Rückgabewert davon jetzt a oder a+1 (für a < maximum)?

Der Rückgabewert ist entweder maximum oder der bereits erhöhte Wert.
Beim ? ist ein Sequence Point, damit ist dort die ++ Operation 
abgeschlossen.

Autor: W.aldo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a = (a>=maximum ? maximum : a+1);

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a = (a<maximum ? a++ : maximum );

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nö, wenn schon dann
 a = (a<maximum ? ++a : maximum );
oder
 a = (a<maximum ? a+1 : maximum );

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> nö, wenn schon dann
>  a = (a<maximum ? ++a : maximum );

Oder halt einfah:
a<maximum ? ++a : 0;
oder etwas verständlicher:
if (a < maximum)
    ++a;

Man muß nicht auf Teufel komm raus den ?:-Operator verwenden.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich auch nie behauptet; vielmehr nur seine falsche Verwendung 
korrigiert.
Noch mehr Varianten möchte ich diesem Thread nicht antun.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, vielleicht doch noch eine Variante (angelehnt an die
häufige Implementation von errno über ein Makro und eine Funktion,
die einen Zeiger auf die Variable liefert):
#include <stdio.h>

#define meineVariableA  (*aGetAddress())
int *aGetAddress()
{
  static int a = 0;
  if( a>10000 )
  {
    a = 10000;
  }
  return &a;
}


int main( int nargs, char **args )
{
  meineVariableA = 5;
  printf( "meineVariableA = %d\n", meineVariableA );

  meineVariableA = 9999;
  printf( "meineVariableA = %d\n", meineVariableA );

  meineVariableA++;
  printf( "meineVariableA = %d\n", meineVariableA );

  meineVariableA++;
  printf( "meineVariableA = %d\n", meineVariableA );

  meineVariableA++;
  printf( "meineVariableA = %d\n", meineVariableA );

  meineVariableA++;
  printf( "meineVariableA = %d\n", meineVariableA );

  printf( "meineVariableA = %d\n", meineVariableA++ );
  printf( "meineVariableA = %d\n", meineVariableA++ );
  printf( "meineVariableA = %d\n", meineVariableA++ );

  printf( "meineVariableA = %d\n", ++meineVariableA );
  printf( "meineVariableA = %d\n", ++meineVariableA );
  printf( "meineVariableA = %d\n", ++meineVariableA );

  return 0;
}

Das funktioniert weitgehend.
Zu beachten ist nur, daß ++meineVariableA einen Wert liefert,
der ggf. 1 über dem Maximum liegt:
meineVariableA = 5
meineVariableA = 9999
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10000
meineVariableA = 10001
meineVariableA = 10001
meineVariableA = 10001

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>nö, wenn schon dann
> a = (a<maximum ? ++a : maximum );

Irgendwie bin ich gerade blind. Was stoert Dich an meiner Version mit 
dem Postincrement?

a = (a<maximum ? a++ : maximum );

oder dann

if (a<maximum) a++;

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
> Was stoert Dich an meiner Version mit
> dem Postincrement?
>
> a = (a<maximum ? a++ : maximum );

Daß es nicht funktionieren wird (bzw. nicht definiert ist), sonst
ist sie schön.

Das Problem ist die Reihenfolge der Auswertung:
Wenn a noch nicht maximum erreicht hat, geht es in das a++.
Das liefert den alten Wert von a und erhöht anschließend a.
I.d.R. wird dann der alte Wert zugewiesen, damit ist die
Erhöhung für die Katz.
M.W. ist diese Reihenfolge aber nicht sicher, es kann erst
der alte Wert zugewiesen werden und dann die Erhöhung
stattfinden.

chris schrieb:
> oder dann
>
> if (a<maximum) a++;

Das dagegen ist in Ordnung, wenn auch viel zu einfach :-)

Noch eine Variante, die wir noch nicht hatten:
  (a<maximum) ? a++ : (a=maximum);

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Ich habe es eben mit dem gcc probiert.
Da kommt bei deiner Version der alte Wert raus und eine Warnung:
t.c:24: warning: operation on ‘a’ may be undefined

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Noch eine Variante, die wir noch nicht hatten:
>   (a<maximum) ? a++ : (a=maximum);

Da hätte ich auch noch mal was ganz anderes:
a<maximum && ++a;

oder noch besser:
a += a < maximum;

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Da hätte ich auch noch mal was ganz anderes:
> a<maximum && ++a;
Auch nett!

Wobei die beiden Fälle dann merkwürdigerweise etwas ganz
unterschiedliches liefern: entweder die 0 vom Vergleich oder
den neuen Wert von a.

Deshalb würde ich den Rückgabewert sicherheitshalber wegwerfen,
auch wenn es vielen dann vielleicht noch merkwürdiger erscheint:
(void)(a<maximum && ++a);

Der zweite ist ja noch besser :-)

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Wobei die beiden Fälle dann merkwürdigerweise etwas ganz
> unterschiedliches liefern: entweder die 0 vom Vergleich oder
> den neuen Wert von a.

Das stimmt. Da könnte man jetzt aber prima den Komma-Operator einsetzen:
a < maximum && (++a, 1);

Dann kommt wie beim Vergleich selber 0 oder 1 raus. ;-)

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>a<maximum && ++a;
Oh, das ist aber haarig, wenn auch ziemlich trickreich. Man verlässt 
sich ja voll auf die Reihenfolge der Ausführung. Ich frage mich, ob da 
nicht ein Optimierer im Compiler was verdrehen könnte.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Deshalb würde ich den Rückgabewert sicherheitshalber wegwerfen

Die Zeile selbst hat ja keinen Rückgabewert. Deshalb müsste man den Wert 
auch nicht wegwerfen, oder?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a<maximum && ++a; hat sehr wohl einen Rückgabewert, nur
verwendet man ihn hoffentlich meistens nicht.
Um eine versehentliche Verwendung zu verhindern (in der
Art: a = a<maximum && ++a) finde ich den cast nach void
angemessen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chris schrieb:
>>a<maximum && ++a;
> Oh, das ist aber haarig, wenn auch ziemlich trickreich. Man verlässt
> sich ja voll auf die Reihenfolge der Ausführung. Ich frage mich, ob da
> nicht ein Optimierer im Compiler was verdrehen könnte.

na und? Das ist vollkommen legal, weil die Reihenfolge beim && und
die short circuit evaluation in C verbindlich sind.
Der Optimierer wird das auch wissen.

Autor: W.aldo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

warum ++a oder a++? Wieso zweimal zuweisen? Kostet doch nur Zeit!

a = (a < maximum ? a+1 : maximum)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.aldo schrieb:
> Kostet doch nur Zeit!

Ja, aber nur beim Übersetzen - der Optimierer wirft es doch eh weg.

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.