Hallo Leute,
ich wollte mich mal schlau machen, wie ich eine Variable korrekt
invertieren kann.
Folgende Grundlage habe ich dazu:
ich habe eine Variable namens UD (Up-Down), welche wie folgt deklariert
ist:
1
volatileuint8_tUD;
nun weise ich der Variable je nach Notwendigkeit im Programm entweder
den Wert 1 oder 0 zu in Form von:
1
#define TRUE 1
2
#define FALSE 0
im quellcode sieht dass dann z.b. so aus:
1
UD=TRUE;
wie kann ich dieses UD denn invertieren?
Bei Bits geht das ja mit PORTx ^= _BV(X);
meine sehr spektakuläre Lösung sieht wie folgt aus:
wozu brauchst du denn den goto?
Den braucht kein Mensch.
In
if( bedingung )
statement1;
else
statement2;
wird nur eines der beiden Statements ausgeführt, abhängig davon ob
bedingung zutrifft oder nicht.
D.h. dein von dir eingeführter goto macht nix anderes als das, was
sowieso automatisch passiert, wenn du einen else-Zweig benutzen würdest.
Gerade wenn du Anfänger bist: du brauchst keinen goto! Wenn du versucht
bist einen goto zu verwenden, dann machst du was falsch.
Es gibt zwar Anwendungen, in denen ein goto tatsächlich die einfachste
Lösung darstellt, aber in diese Situation wirst du die nächsten 2 Jahre
nicht kommen und wenn es soweit ist, dann wirst du das wissen. Ich
selbst hab in 28 Jahren C-Programmieren keinen einzigen goto verbaut.
OK.
Also
if( UD )
UD = FALSE;
else
UD = TRUE;
oder in der C-typischen Kurzform, die auf die gleiche Idee rausläuft
UD = UD ? FALSE : TRUE;
Oder
UD = 1 - UD;
Oder
UD = !UD;
Als erstes brauchst Du true und false nicht selber definieren, dafür
gibt es:
1
#include<stdbool.h>
Invertieren geht am einfachsten mit:
1
UD=!UD;
Gewöhn Dir aber lieber gleich an, Variablennamen wie üblich klein zu
schreiben, damit man sie von Defines unterscheiden kann.
Da Du in Deinem Fall anscheinend eine Richtung definieren willst, wäre
es am sinnvollsten, das auch explizit zu tun:
bei UD = !UD;
oder direction = !direction
was passiert denn wenn der wert TRUE ist? wird der dann FALSE? und wenn
er FALSE ist wird er TRUE? bzw in zahlen, wieso wird eine variable mit
einem wert 1 wenn ich sie invertiere 0? oder eben wenn sie 0 ist 1=
Sven Weinmann schrieb:> wieso wird eine variable mit> einem wert 1 wenn ich sie invertiere 0? oder eben wenn sie 0 ist 1=
das muss nicht so sein. Dann True ist definiert als !0 und nicht 1. Es
kann also durchaus sein das aus 0 eine 255 oder eine 65536 wird.
das war mein problem hier!
wobei ich selbst true ja als 1 und false als 0 definiert habe!
aber gerade da stellt sich mir die frage, woher weiß der controller
denn, dass false das gegenteil von true ist?
Es gibt nur 1 oder 0. Wenn nicht 1, dann 0, wenn nicht 0 dann 1
Also ist "NICHT 1" automatisch 0 und "Nicht 0" muss daher 1 sein.
Also ist UD = !UD zu lesen als "neuer wert = nicht alter wert", womit
wir wieder am Anfang wären
Ergänzung, weil ioch zu langsam war:
Sven Weinmann schrieb:> aber gerade da stellt sich mir die frage, woher weiß der controller> denn, dass false das gegenteil von true ist?
egal wie du definierst, ab deiner ersten Zuweisung von UD = true steht
in UD nicht "true" sondern eben die 1, was anderes kann der Controller
ja nicht speichern. Und hier kommt wieder NICHT 1 ist 0, was DU als
false definiert hast (auslesen kannst du ja "false" nicht)
Um das ganze zu klären kann man das auch einfach mal in C einhacken:
1
#include<stdio.h>
2
3
intmain(intargc,char*argv[])
4
{
5
intiint;
6
boolbbool;
7
8
bbool=true;
9
printf("True ist: %.2X\r\n",*(char*)&bbool);
10
11
bbool=false;
12
printf("False ist: %.2X\r\n",*(char*)&bbool);
13
14
bbool=!false;
15
printf("!false ist: %.2X\r\n",*(char*)&bbool);
16
17
bbool=!true;
18
printf("!true ist: %.2X\r\n",*(char*)&bbool);
19
20
bbool=~false;
21
printf("~false ist: %.2X\r\n",*(char*)&bbool);
22
23
bbool=~true;
24
printf("~true ist: %.2X\r\n",*(char*)&bbool);
25
26
if(-1)printf("-1 ist true!\r\n");
27
if(0)printf("0 ist true!\r\n");
28
if(1)printf("1 ist true!\r\n");
29
30
getchar();
31
return0;
32
}
Die Ausgabe dazu:
True ist: 01
False ist: 00
!false ist: 01
!true ist: 00
~false ist: 01
~true ist: 01
-1 ist true!
1 ist true!
Die Konvertierung des Bools über Pointer habe ich gemacht um deutlich zu
machen, dass das Programm den tatsächlichen Speicherinhalt des Bools
anzeigt.
Es gibt zwei NOT-Operationen in C. Das ! ist ein logisches NOT. Das ~
ist ein binäres NOT.
Das beim binären NOT false zu 1 wird ist klar.
Eine Zahl ungleich von null ist immer true (ich hab es jetzt nur mit -1,
0 und 1 probiert).
Das beim binären NOT true zu 1 wird liegt wohl daran, dass ein bool
intern nicht aus einem Bit besteht (je nach Compiler kann es
unterschiedlich lang sein, meist aber 8 bit).
Es werden alle Bits des Bools invertiert und der Boolsche Wert wird
interpretiert. Da beim binären invertieren alle anderen Bits auf 1
kippen wird die Zahl wieder als true interpretiert.
Es ist eigentlich egal, wie true definiert ist, das Invertieren geht
immer. Der !-Operator macht aus einem wahren Wert einen unwahren Wert
und aus einem unwahren Wert einen wahren Wert:
1
#define TRUE 5
2
#define FALSE 0
3
4
uint8_tvar;
5
6
var=TRUE;// var hat den Wert 5 (ungleich 0, also wahr)
7
var=!var;// aus wahr wird unwahr, d.h. var ist jetzt 0.
8
var=!var;// aus unwahr wird wahr, d.h. var ist jetzt 1
9
// (vielleicht auch was anderes ungleich 0, z.B. 255).
10
var=!var// aus wahr wird unwahr, d.h. var ist jetzt 0.
Das einzige was man lassen sollte sind Abfragen wie:
1
if(var==TRUE)
Denn wenn man TRUE nicht richtig definiert hat, geht das schief. Gerade
bei fremden Funktionen kann man da reinfallen, wenn sie einen anderen
Wert zurückliefern, den man als bool interpretiert. Also bei Abfragen
immer nur
1
if(var!=0)bzw.if(var==0)
oder kurz (und bei sinnvoller Variablenbennenug sehr gut lesbar)
Sven Weinmann schrieb:> if (var) ist das gleiche wie if (var ==1) ?
NEIN!!!
if(var) ist das gleiche wie if(var == !0) oder if(var != 0)
Denn var könnte ja auch 143, -27 oder 172572373833 sein. Und dann ist es
nicht 1.
Dann würde if(var) true und if(var == 1) false ergeben.
mfg.
So ist es eigentlich noch schöner...
Hier sieht man direkt den Zahlenwert, ohne dass der Compiler da noch was
rum-interpretiert. Bei der Ausgabe des ~true hat der Compiler vorher den
Wert in true interpretiert. Mit diesem Code sieht man jetzt auch warum:
bedeutet "falls der Wert wahr ist" und "wahr" ist in C alles, was nicht
0 ist. Es ist also das gleiche wie:
1
if(var!=0)
Deshalb ist es ja so gefährlich, sich TRUE per Define zu definieren,
weil es dann nur einen bestimmten Wert hat (z.B. 1) und nicht "alles
ungleich 0" bedeutet, wie es eigentlich sein müsste.
Ich glaube Svens frage ist jetzt beantwortet. Lustig wie sich alle immer
auf die einfachen Fragen stürzen (mich eingschlossen :)).
Ich sehe kein Problem TRUE per Define zu definieren. So lange man nicht
definiert:
#define TRUE 0
#define FALSE 1
Das könnte wohl zu Problem führen :-)
Peter II schrieb:> Sven Weinmann schrieb:>> wieso wird eine variable mit>> einem wert 1 wenn ich sie invertiere 0? oder eben wenn sie 0 ist 1=>> das muss nicht so sein. Dann True ist definiert als !0 und nicht 1. Es> kann also durchaus sein das aus 0 eine 255 oder eine 65536 wird.
Das kann allerdings nicht sein.
!0 ergibt 1
das ist so definiert.
Wenn der Compiler einen 'boolschen Wert' zu erzeugen hat, dann wird für
das Ergebnis True IMMER 1 herauskommen.
Daher ist das Ergebnis für
i < j
entweder 0 oder 1, je nach den aktuellen Werten der Variablen. Aber das
Ergebnis dieses Ausdrucks kann nicht 2 oder 8 oder 255 oder 65536 sein.
Die Regelung mit 'ungleich 0' gilt nur in der Verwendung eines
Ausdrucks. Dort wird jeder Wert ungleich 0 als logisch wahr gewertet.
Wenn aber aus einem Ausdruck ein logischer Wahrheitswert resultiert (wie
zb die Ergebnisse der logischen Operatoren &, |, !, aber auch
Vergleiche) dann wird der Wert 'logisch wahr' durch 1 repräsentiert. Der
Compiler muss dafür Sorge tragen, dass nur die beiden Ergebnisse 0 und 1
möglich sind.
Das Ergebnis von
int i = 8;
i = !!i;
ist also definitiv und garantiert eine 1 in i.