Forum: PC-Programmierung Variable begrenzen in C


von Freak (Gast)


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

von Rolf M. (rmagnus)


Lesenswert?

Nein.

von Thomas E. (thomase)


Lesenswert?

int nA;

if (nA < 10000) nA++;

oder

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

oder

nA++;
nA = nA % 10001;


mfg.

von Jürgen (Gast)


Lesenswert?

Schreib einfach:
1
   ink(a);  // Anstelle von a++;
2
[c]
3
4
und verwende folgende Funktion:
5
6
[c]
7
int ink(int a)
8
{
9
  return (++a > 10000) ? 10000 : a; 
10
}

von Klaus W. (mfgkw)


Lesenswert?

Jürgen schrieb:
> ink(a);  // Anstelle von a++;

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

von Schorsch (Gast)


Lesenswert?

1
template<int maximum> class limited_int {
2
public:
3
...
4
  limited_int<maximum> operator++...
5
...
6
private:
7
  unsigned int value;
8
}
oder so...

von Klaus W. (mfgkw)


Lesenswert?

genau, vor allem in C.

von Freak (Gast)


Lesenswert?

danke für die vielen Möglichkeiten, die

if anweisung ist perfekt für mich!

von sebastians (Gast)


Lesenswert?

> Kann man das irgendwie am Anfang deklarieren?
nein.

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

von D. I. (Gast)


Lesenswert?

Jürgen schrieb:
> Schreib einfach:
>
1
>    ink(a);  // Anstelle von a++;
2
> [c]
3
> 
4
> und verwende folgende Funktion:
5
> 
6
> [c]
7
> int ink(int a)
8
> {
9
>   return (++a > 10000) ? 10000 : a;
10
> }
11
>

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

von Klaus W. (mfgkw)


Lesenswert?

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

von Sam .. (sam1994)


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

von Sequence Point (Gast)


Lesenswert?

Samuel K. schrieb:
1
> 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)?

von Freak (Gast)


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

von chris (Gast)


Lesenswert?

wie wär's damit?

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

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

von Karl H. (kbuchegg)


Lesenswert?

Sequence Point schrieb:
> Samuel K. schrieb:
>
1
>> return (a++ > maximum - 1) ? maximum : a;
2
>
>
> 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.

von W.aldo (Gast)


Lesenswert?

a = (a>=maximum ? maximum : a+1);

von chris (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

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

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

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

von Klaus W. (mfgkw)


Lesenswert?

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

von Klaus W. (mfgkw)


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):
1
#include <stdio.h>
2
3
#define meineVariableA  (*aGetAddress())
4
int *aGetAddress()
5
{
6
  static int a = 0;
7
  if( a>10000 )
8
  {
9
    a = 10000;
10
  }
11
  return &a;
12
}
13
14
15
int main( int nargs, char **args )
16
{
17
  meineVariableA = 5;
18
  printf( "meineVariableA = %d\n", meineVariableA );
19
20
  meineVariableA = 9999;
21
  printf( "meineVariableA = %d\n", meineVariableA );
22
23
  meineVariableA++;
24
  printf( "meineVariableA = %d\n", meineVariableA );
25
26
  meineVariableA++;
27
  printf( "meineVariableA = %d\n", meineVariableA );
28
29
  meineVariableA++;
30
  printf( "meineVariableA = %d\n", meineVariableA );
31
32
  meineVariableA++;
33
  printf( "meineVariableA = %d\n", meineVariableA );
34
35
  printf( "meineVariableA = %d\n", meineVariableA++ );
36
  printf( "meineVariableA = %d\n", meineVariableA++ );
37
  printf( "meineVariableA = %d\n", meineVariableA++ );
38
39
  printf( "meineVariableA = %d\n", ++meineVariableA );
40
  printf( "meineVariableA = %d\n", ++meineVariableA );
41
  printf( "meineVariableA = %d\n", ++meineVariableA );
42
43
  return 0;
44
}

Das funktioniert weitgehend.
Zu beachten ist nur, daß ++meineVariableA einen Wert liefert,
der ggf. 1 über dem Maximum liegt:
1
meineVariableA = 5
2
meineVariableA = 9999
3
meineVariableA = 10000
4
meineVariableA = 10000
5
meineVariableA = 10000
6
meineVariableA = 10000
7
meineVariableA = 10000
8
meineVariableA = 10000
9
meineVariableA = 10000
10
meineVariableA = 10001
11
meineVariableA = 10001
12
meineVariableA = 10001

von chris (Gast)


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

von Klaus W. (mfgkw)


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

von Klaus W. (mfgkw)


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

von Rolf M. (rmagnus)


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:
1
a<maximum && ++a;

oder noch besser:
1
a += a < maximum;

von Klaus W. (mfgkw)


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

von Rolf M. (rmagnus)


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:
1
a < maximum && (++a, 1);

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

von chris (Gast)


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.

von chris (Gast)


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?

von Klaus W. (mfgkw)


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.

von Klaus W. (mfgkw)


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.

von W.aldo (Gast)


Lesenswert?

Hallo,

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

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

von Klaus W. (mfgkw)


Lesenswert?

W.aldo schrieb:
> Kostet doch nur Zeit!

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

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.