Hallo zusammen,
ich hab mal ein Frage bezüglich nem C Code: (C8051 Silicon Lab)
"while(!TI0);" ist doch identisch mit "while(TI0==0);"
#solange senden des UART0 nicht beendet, mache "nichts".
anschliessend lösche das Flag wieder;
"TI0=0;"
richtig.
In C können alle Variablen auch boolean interpretiert werden, d.h. 0 ist
FALSE und alles andere ist TRUE.
So gehen z.B:
1
while(!i);
2
while(i--);
3
4
do{
5
sendchar(*pointer);
6
}while(*pointer++);
7
8
for(i=10;i;i--){...}
usw.
Die Bedingung für irgendetwas in so einer Abfrage (while, for, if) wird
stets auf TRUE geprüft, um den Rumpf (der auch nur ein ";" sein kann,
auszuführen.
Will man auf "0" prüfen, muss man vorher invertieren.
VG,
/th.
Ja, aber nicht alles was in C möglich ist sollte man auch so schreiben.
Ein expliziter Vergleich kann hier die Lesbarkeit des Codes deutlich
erhöhen.
Dem Compiler ist es wurscht und macht in beiden Fällen identischen
Maschinencode.
Hochsprachen wurden entwickelt, um Programme für den Menschen lesbarer
und verständlicher zu schreiben.
Aber leider gibt es Programmierer die das nicht verstanden haben.
Gruß
Sowas sagen allerdings nur ungeübte c Programmierer.
Wenn man auch nur etwas erfahrung mit C hat, erkennt man sachen wie
while(!i) auf anhieb, ohne zu überlegen und aus 3 Meter Entfernung.
Klaus wrote:
> Wenn man auch nur etwas erfahrung mit C hat, erkennt man sachen wie> while(!i) auf anhieb, ohne zu überlegen und aus 3 Meter Entfernung.
Das sagen nur die, die sich fuer erfahren und den Anfaengern ueberlegen
halten. Mit zunehmender Reife nimmt die Anzahl der "coolen" Konstrukte
zugunsten der Lesbarkeit wieder ab...
Peter Stegemann wrote:
> Klaus wrote:>>> Wenn man auch nur etwas erfahrung mit C hat, erkennt man sachen wie>> while(!i) auf anhieb, ohne zu überlegen und aus 3 Meter Entfernung.>> Das sagen nur die, die sich fuer erfahren und den Anfaengern ueberlegen> halten. Mit zunehmender Reife nimmt die Anzahl der "coolen" Konstrukte> zugunsten der Lesbarkeit wieder ab...
Also ich finde es wirklich weitaus lesbarer, ein
1
while(TargetRunning())
2
{
3
...
4
}
zu lesen, als ein
1
while(TargetRunning()==1)
2
{
3
...
4
}
Der Grund dafür ist einfach:
Im zweiten Fall muss ich mich mit dem Rückgabewert auseinandersetzen.
Im ersten Fall kann ich das einfach so weglesen:
Solange der Target noch läuft, mache irgendwas.
Aber das ist Ansichtssache. Genau so wie while(*pointer++) :-)
Noch was:
>Peter Stegemann wrote:> Klaus wrote:>>>>> Wenn man auch nur etwas erfahrung mit C hat, erkennt man sachen wie>>> while(!i) auf anhieb, ohne zu überlegen und aus 3 Meter Entfernung.>>>> Das sagen nur die, die sich fuer erfahren und den Anfaengern ueberlegen>> halten. Mit zunehmender Reife nimmt die Anzahl der "coolen" Konstrukte>> zugunsten der Lesbarkeit wieder ab...>>Also ich finde es wirklich weitaus lesbarer, ein>while(TargetRunning())>{> ...>}>>>>zu lesen, als ein>while(TargetRunning() == 1)>{> ...>}
Ich auch. Irgendwann gewöhnt man sich an den Anblick.
Irgendwann habe ich mal ein Programm gesehen, dass fast nur aus einer
For-Schleife bestand. Das war wirklich "übersichtlich".
Man kann in C unübersichtliches Zeug schreiben - muß man nicht - kann
man aber auch in diversen anderen Programmiersprachen.
Und nicht jedes Programm ist für Anfänger (oder Leute, die meinen, alles
müsste für Anfänger geschrieben sein) geschrieben...
Sinnvolle Kommentare helfen übigens auch bei der Übersichtlichkeit.
Manchmal ist es doch gar nicht interessant, wie es funktioniert,
sondern, was da passiert (nicht der Weg, sondern das Ziel...).
Ein bischen fies ist in diesem Zusammenhang allerdings der Posix(Unix)
API, dessen Funktionen ihren Erfolg üblicherweise mit dem Return-Code 0
bekannt geben.
Also, wenn es so cool ist implizite Vergleiche zu schreiben, wozu gibt
es dann MISRA?
Der Vergleich mit "while(TargetRunning() == 1)" hinkt im Übrigen etwas,
da hier auch ohne expliziten Vergleich klar ist was gemeint ist.
Allerdings würde ich nicht unterschreiben, dass man sich nicht mit dem
Funktionsergebnis auseinandersetzen muss. Wer garantiert, dass die
Funktion wirklich 0 und !0 zurückliefert. Möglich wäre ja auch ein
Enumwert z.B. RUNNING (1), STOPPED(2).
PS:
Ich denke, dass ich (mit meinen vielen Jahren C Erfahrung) Konstrukte
wie
"while(!TI0);" sofort auflösen kann. Dennoch würde ich soetwas nie
schreiben. Eben wegen meiner langjährigen Erfahrung.
Fehler lauern hinter jeder falschen Annahme!
Gruß
> Ein bischen fies ist in diesem Zusammenhang allerdings> der Posix(Unix) API, dessen Funktionen ihren Erfolg> üblicherweise mit dem Return-Code 0 bekannt geben.
Einer der guten Gründe dafür, sich beim Programmieren zu fragen, ob das,
was man da prüft, tatsächlich ein bool-scher Wert ist oder ob man es nur
aus Faulheit oder Coolness so um-interpretiert.
Es ist dringend anzuraten, Werte als das zu behandeln, was sie ihrer
Natur nach sind, und die POSIX-Rückgaben sind Fehlercodes, an denen man
die Art des Fehlers ablesen kann. Wer das unbedingt eindampfen will auf
"hat geklappt" oder "ist schiefgegangen", der verwendet ein Makro wie
1
#define POSIX_SUCCESS(n) (n == 0)
Das ist gut lesbar und semantisch richtig und hat keine
Performancestrafe.
"TargetRunning" ist entweder Ja oder Nein, also ist eine boolsche
Auswertung da schon passend.
Sachen wie while(!i) oder while (*pointer++) erkennen C-Programmierer
meist richtig wieder. Aber nur, weil sie "Insiderwissen" über die
Äquivalenz von false und 0 haben. Wer in anderen Sprachen programmieren
kann und bloß die C-Syntax nicht kennt, wird sich hier schwertun,
schwerer als mit "while (i != 0)" - das erschließt sich fast von selbst.
> while(TargetRunning() == 1) ...> Allerdings würde ich nicht unterschreiben,> dass man sich nicht mit dem Funktionsergebnis> auseinandersetzen muss. Wer garantiert, dass die> Funktion wirklich 0 und !0 zurückliefert.> Möglich wäre ja auch ein Enumwert z.B.> RUNNING (1), STOPPED(2).
Dann wäre der Name falsch gewählt. "TargetRunning" impliziert, dass der
Wert entweder Ja oder Nein sein kann. Manche APIs unterstreichen das,
indem sie ein "is" voranstellen: isTargetRunning.
Wenn da ein Enum-Wert zurückkäme, müsste die Funktion TargetRunState()
oder so ähnlich heißen.
Das mit dem TargetRunning war nur ein Beispiel, um es zu verdeutlichen.
Ich spare mir sehr gerne immer den Vergleich auf 0, weils meiner Meinung
nach übersichtlicher ist. Da hat halt jeder seinen eigenen
Programmierstil.
Vorteil dieser Kurzschreibweise sind sehr elegante Konstrukte, die man
sofort als "Bild" im Code wiederfinden und ohne nachzudenken
interpretieren kann.
An dieser Stelle noch mal mein Mini-printf, wo ich von diesen Sachen
"derben" Gebrauch mache:
1
intthprintf(char*string,...)
2
{
3
va_listtag;
4
inti=0;
5
char*pointer=0;
6
signedintint_tmp=0;
7
8
va_start(tag,string);
9
10
do
11
{
12
if(*string=='%')
13
{
14
switch(*(++string))
15
{
16
case'i':
17
{
18
int_tmp=va_arg(tag,int);
19
20
if(int_tmp<0)
21
{
22
fputc('-',0);
23
int_tmp=-int_tmp;
24
}
25
26
27
pointer=(char*)int_tmp;
28
for(i=MAX_NUM_DEC;i;i/=10)
29
{
30
if((int)pointer/i)
31
{
32
fputc((int_tmp/i)+48,0);
33
int_tmp%=i;
34
}
35
elseif(i<10)fputc(0+48,0);
36
}
37
}break;
38
39
case'c':
40
{
41
fputc((char)va_arg(tag,int),0);
42
}break;
43
44
case's':
45
{
46
pointer=va_arg(tag,char*);
47
48
do
49
{
50
fputc(*pointer,0);
51
}while(*pointer++);
52
}break;
53
}
54
}// end if '%'
55
56
elseif(*string=='\\')
57
{
58
switch(*(++string))
59
{
60
case'n':fputc('\n',0);
61
break;
62
63
case't':fputc('\t',0);
64
break;
65
66
case'r':fputc('\r',0);
67
break;
68
}
69
}// end if '\'
70
71
elsefputc(*string,0);
72
73
}while(*(++string));
74
75
va_end(tag);
76
77
return(0);
78
}
Für die "Anfänger" zum Nachdenken und für die "Profis" zum schmunzeln
:-)
VG,
/th.
Das Schmunzeln bleibt da bei mir aus. Dein Code zeigt sehr schoen, wie
wichtig ein guter Stil ist...
Zum Beispiel "TargetRunning()" - das gehoerte eigentlich als bool
deklariert. Und nun bitte nicht wieder darueber jammern, dass das im
guten alten C nicht existiert, fuer die meissten Projekte duerfte dieses
Argument schlicht und einfach nicht zutreffen.
Peter Stegemann wrote:
> Das Schmunzeln bleibt da bei mir aus. Dein Code zeigt sehr schoen, wie> wichtig ein guter Stil ist...
... und der ist auch teilweise Geschmacksache. Allein für die Klammern
gibts beliebig viele Stile, und jeder schwört auf seinen eigenen.
A. K. wrote:
> Peter Stegemann wrote:>>> Das Schmunzeln bleibt da bei mir aus. Dein Code zeigt sehr schoen, wie>> wichtig ein guter Stil ist...>> ... und der ist auch teilweise Geschmacksache. Allein für die Klammern> gibts beliebig viele Stile, und jeder schwört auf seinen eigenen.
Keineswegs. Es gibt nur einen guten Klammern-Stil und das ist meiner :-)
Auch die Verteilung von Leerzeichen fördert die Lesbarkeit. Sowas
1
int_tmp=-int_tmp;
würde ich zb. nie schreiben. Da muss ich 5 Sekunden hin starren um das
kleine - da mittendrin zu finden. Und dann brauch ich noch 2 Sekunden um
zu erkennen ob da jetzt =- oder -= steht.
1
int_tmp=-int_tmp;
vs.
1
int_tmp-=int_tmp;
Aber auch das ist letztendlich Geschmackssache.
Genauso wie das hier:
1
fputc((int_tmp/i)+48,0);
Würd ich von meinen Leuten nicht akzeptieren. Wieso 48, was hat es damit
für eine Bewanntnis? Wenn ich solch magische Zahlen in einem Code sehe,
dann ist das immer die erste Frage: Was bedeutet die Zahl?
1
fputc((int_tmp/i)+'0',0);
Aaaah. zim Ergebnis der Division wird noch der Zeichencode von '0'
dazugezählt. Alles klar, das ist eine 'Verschiebung' eines einstelligen
Rechenergebnisses in den Coderaum der sichtbaren Zeichen.
So gibt es viele Dinge, und jeder hat da was anderes vor seinem
geistigen Auge, die zur Klarheit von Code beitragen können.
Die Unterscheidung zwischen einem boolschen Returnwert und einem
Enumeration-Returnwert ist nur einer davon. Was sich bei mir auch
bewährt hat, ist ein klares Namensschema, das zwischen Owning und
Non-owning Pointern unterscheiden lässt. Alleine damit werden schon
Unmengen an Problemen im dynamischen Speichermanagement beseitigt, die
Newbies zur Verzweiflung bringen. Nur der Owning-Pointer besitzt den
Speicher und ist für seine Freigabe zuständig. Alle Kopien davon sind
Non-Owning Pointer und haben sich als solche von free() oder delete fern
zu halten.
1
char*pointer=0;
Die Variable pointer ist ein Pointer. Und für solche benutze ich zur
Initialisierung mit dem 'zeigt auf keine Adresse' Wert immer NULL (auch
wenn NULL nichts anderes als 0 in einer anderen Verpackung ist :-)
1
char*pointer=NULL;
Selbiges für char Variablen bzw. doubles.
1
chara='\0';
2
doublen=0.0;
(Aus irgendeinem Grund kann ich mich an das Makro NUL für '\0' einfach
nicht gewöhnen)
doubles kriegen bei mir immer einen Dezimalpunkt. Und wenn die
Nachkommastelle 0 ist, schrieb ich auch .0 hin. Man soll von aller Weite
sehen, dass ich double meine, wo double draufsteht
1
Umfang=2.0*PI*radius;
Manchmal wird auch ein Leerzeichen oder Einrückungsschema zugunsten
einer 'Tabellenstruktur' über den Haufen geworfen. Aber nur dann, wenn
mir die Tabellenstruktur etwas zeigen kann, was ich sonst nocht sofort
sehen würde und was mir wichtig ist
1
m_ctlButton1.ShowWindow(x==5?SW_SHOW:SW_HIDE);
2
m_ctlText.ShowWindow(x==7?SW_SHOW:SW_HIDE);
3
m_ctlCheck.ShowWindow(x==9?SW_SHOW:SW_HIDE);
Hier ist es mir wichtiger den Unterschied in der Freigabebedingung der
einzelnen Controls optisch herauszuarbeiten. Wichtiger als konsistent 1
Leerzeichen vor den Funktionsargumenten zu machen.
Karl heinz Buchegger wrote:
> Und dann brauch ich noch 2 Sekunden um> zu erkennen ob da jetzt =- oder -= steht.
War nicht sogar ,,ganz früher'' mal »=-« ein Synonym für »-=«? :-o
> Sinnvolle Kommentare helfen übigens auch bei der Übersichtlichkeit.
Dieser Punkt ist IMHO einer der Schwierigsten überhaupt.
1
/* globale Variablen */
2
inti;
3
intj;
4
5
/* Protoypen */
6
voidFuncA();
7
voidFuncB();
8
9
/***************************************/
10
/* main Funktion */
11
intmain()
12
{
13
doubleo=0.2;/* Mehrwertsteuersatz = 20% */
14
....
15
}
BIs auf den Kommentar der Variablen o in main() sind alle Kommentare
völlig sinnlos, auch wenn sich so mancher Lehrer auf sowas versteift.
Der Kommentar erzählt mir nichts,w as ich nicht auch im Code sehen
würde.
Und bei o muss ich mich fragen: Warum nennt der Autor die Variable o und
gibt ihr nicht ganz einfach einen Namen, der an Mehrwertsteuersatz
erinnert. Er könnte ja das lange Wort soweit abkürzen, dass man es noch
leicht erkennen kann und sich trotzdem keinen Wolf tippt.
Aus
1
x=o*l;/* Berechne Bruttopreis aus Mwst und Nettopreis */
wird so
1
bruttoPreis=Mwst*nettoPreis;
und der Kommentar ist hinfällig, weil er mir nicht mehr erzählt als was
im Code sowieso schon steht. Und jeder Kommentar den ich einsparen kann,
ist ein guter Kommentar, weil durch sein Wegfallen die Gefahr wegfällt,
dass irgendwann Kommentar und Code nicht mehr zusammenstimmen.
Allerdings bin ich ein eifriger Verfechter von Blockkommentaren!
Erzähl in eurem Kommentar ruhig, was im nächsten Codeabschnitt passiert,
warum es passiert, was die Idee dahinter ist, in welchem Buch das
gefunden wurde, etc.
Diese Kommentare sind sehr wohl hilfreich.
<Einwurf>
Manchmal sollen ja Kommentare auch ganz toll sein. ;-)
</Einwurf>
@Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Speziell mit dem Smiley hintendran sieht die Zeile echt klasse aus. ;-)
Lothar Miller wrote:
> while(TargetRunning = 1) {> Und das ist u.U. nur schwer zu finden :-o
Das war vor 20 Jahren schwer zu finden. Welcher heutige Compiler
schmeißt dafür keine Warnung raus?
> while(1 == TargetRunning) {
Total hässlich zu lesen (IMHO), da es unserer normalen Leserichtung
widerspricht.
Da geb ich recht, normalerweise schreibe ich nur beim initialisieren
foo=0; oder foo++. Aber so was kann auch mal dazwischen vorkommen :-)
Bei den Magic Numbers geb ich dir absolut recht. Normalerweise liebe ich
#defines für MagicNumbers. Hier hab ich aber selbst auf das '0'
"verzichtet", weils zu offensichtlich ist.
---
Haha, keiner hat die "Gemeinheit" gefunden, schaut mal hier rein:
1
case'i':
2
{
3
int_tmp=va_arg(tag,int);
4
5
if(int_tmp<0)
6
{
7
fputc('-',0);
8
int_tmp=-int_tmp;
9
}
10
11
12
pointer=(char*)int_tmp;
13
for(i=MAX_NUM_DEC;i;i/=10)
14
{
15
if((int)pointer/i)
16
{
17
fputc((int_tmp/i)+48,0);
18
int_tmp%=i;
19
}
20
elseif(i<10)fputc(0+48,0);
21
}
22
}break;
Da versteckt sich was drin, was man eigentlich nicht tun sollte; in
diesem Kontext ist es aber safe.
Wenn noch jmd. nen Vorschlag hat, wie man das noch kleiner kriegt, her
damit!
VG,
/th.
Jörg Wunsch wrote:
> War nicht sogar ,,ganz früher'' mal »=-« ein Synonym für »-=«? :-o
Nicht synonym, sondern das war die ursprüngliche Version. Hatten aber
sehr schnell gemerkt, dass das Unfug ist.
Random ... wrote:
> Bei den Magic Numbers geb ich dir absolut recht. Normalerweise liebe ich> #defines für MagicNumbers. Hier hab ich aber selbst auf das '0'> "verzichtet", weils zu offensichtlich ist.
:-)
<Betroffen schau>
So eine Umwandlung hab ich sicher schon zig mal gemacht, und ich muss
gestehen, dass ich eine ASCII Tabelle hervorgekramt hab und nachgesehen
hab
</Betroffen schau>
> Haha, keiner hat die "Gemeinheit" gefunden, schaut mal hier rein:
:-)
Wenn du schon so anfängst.
Ich denke du meinst:
> pointer = (char*)int_tmp;
Karl heinz Buchegger wrote:
> Ich denke du meinst:>>> pointer = (char*)int_tmp;
Dann is das aber mehr Kacke als Gemeinheit.. das kann man so schön mit
unions lösen...
Sven P. wrote:
> Karl heinz Buchegger wrote:>> Ich denke du meinst:>>>>> pointer = (char*)int_tmp;> Dann is das aber mehr Kacke als Gemeinheit.. das kann man so schön mit> unions lösen...
An der Stelle hätte es auch eine zusätzliche int Variable getan :-)
Schau dir an was mit pointer weiter passiert
> if((int)pointer/i)
... und mehr macht er nicht damit. Auf einen char* casten, nur damit er
dann wieder auf einen int zurückgecastet wird :-)
Der char* wird als Zischenspeicher für einen int misbraucht :-)
Unions zur Typkonvertierung sind ganz ganz übel. Stell dir eine Maschine
vor, deren (char *) anders aussehen als deren (int *). Bei denen also
bei Konvertierung zwischen Pointern verschiedenen Typs evtl. eine
Wertkonvertierung stattfindet.
War früher nicht ungewöhnlich (Data General Nova beispielsweise). Aber
das gibt es sogar heute noch, sogar ganz frisch, man sollte es kaum
glauben: MaxQ2000. Ich wäre auch nicht überrascht, wenn der eine oder
andere Compiler für Harvard-Architekturen das macht.
A. K. wrote:
> Unions zur Typkonvertierung sind ganz ganz übel.
Wir konvertieren ja garnix.
> Stell dir eine Maschine> vor, deren (char *) anders aussehen als deren (int *). Bei denen also> bei Konvertierung zwischen Pointern verschiedenen Typs evtl. eine> Wertkonvertierung stattfindet.
Ist doch hier vollkommen wurscht. Solange ich einen Wert immer nur über
einen Zugang der Union benutze, ist alles ok.
Die Variante, den Zeiger als Zwischenspeicher zweckzuentfremden ist da
gefährlicher, da Zeiger weder zwangsläufig Zahlen sind, noch immer vier
Bytes lang sind.
Sven P. wrote:
> A. K. wrote:>> Unions zur Typkonvertierung sind ganz ganz übel.> Wir konvertieren ja garnix.>>> Stell dir eine Maschine>> vor, deren (char *) anders aussehen als deren (int *). Bei denen also>> bei Konvertierung zwischen Pointern verschiedenen Typs evtl. eine>> Wertkonvertierung stattfindet.> Ist doch hier vollkommen wurscht. Solange ich einen Wert immer nur über> einen Zugang der Union benutze, ist alles ok.
Ich hab allerdings auch zuerst gedacht, dass du an eine Umwandlung
gedacht hast :-)
Aber du hast recht, man könnte das 'Speichersharing' wunderbar mit einer
union lösen.
> Aber du hast recht, man könnte das 'Speichersharing' wunderbar mit einer> union lösen.
Stimmt, das könnte man machen :-)
Sinn dieses Projektes für mich war es, a) va_arg kennenzulernen und b)
es möglichst klein zu kriegen.
Ansonsten ist das mein normaler programmierstil, da kommt dann an so ner
Stelle auch mal ne 48 vor **grins**
" da kommt dann an so ner Stelle auch mal ne 48 vor **grins** "
Mich wundert, warum statt 48 nicht 0x30 geschrieben wird.
Wenn wir gerade bei Schleifen sind:
do ..... while (i--)
der generierte Code ist effizienter, falls man
do ..... while (--i)
schreibt, weil der Prozessor nach dem Decrement direkt das Zero-Flag für
den BRE verwenden kann.
Bei (i--) ist ein extra Vergleich nötig, da ja zuerst i mit Null
verglichen wird und dann erst decrementiert wird.
Die meisten Compiler decrementieren doch zuerst und
vergleichen dann mit -1 .
Natürlich muss das i vorher um 1 korrigiert werden.
Das mit dem Weglassen von Leerzeichen und Klammern ist wirklich
Gewohnheits- und Übungssache.
m_ctlButton1.ShowWindow( x == 5 ? SW_SHOW : SW_HIDE );
m_ctlText.ShowWindow( x == 7 ? SW_SHOW : SW_HIDE );
m_ctlCheck.ShowWindow( x == 9 ? SW_SHOW : SW_HIDE );
schreibe ich aber lieber
m_ctlButton1.ShowWindow( x == 5 ? SW_SHOW : SW_HIDE );
m_ctlText.ShowWindow ( x == 7 ? SW_SHOW : SW_HIDE );
m_ctlCheck.ShowWindow ( x == 9 ? SW_SHOW : SW_HIDE );
d.h. möglichst viel gleiches untereinander.
wobei ich das gleich anders schreiben würde:
m_ctlButton1.ShowWindow( x == 5 );
m_ctlText.ShowWindow ( x == 7 );
m_ctlCheck.ShowWindow ( x == 9 );
d.h. das boolsche Ergebnis des Vergleichs wird übergeben.
eProfi wrote:
> m_ctlButton1.ShowWindow( x == 5 ? SW_SHOW : SW_HIDE );> m_ctlText.ShowWindow( x == 7 ? SW_SHOW : SW_HIDE );> m_ctlCheck.ShowWindow( x == 9 ? SW_SHOW : SW_HIDE );>> schreibe ich aber lieber> m_ctlButton1.ShowWindow( x == 5 ? SW_SHOW : SW_HIDE );> m_ctlText.ShowWindow ( x == 7 ? SW_SHOW : SW_HIDE );> m_ctlCheck.ShowWindow ( x == 9 ? SW_SHOW : SW_HIDE );
Ja, ist auch eine Möglichkeit.
Aber auf jeden Fall besser als
m_ctlButton1.ShowWindow( x == 5 ? SW_SHOW : SW_HIDE );
m_ctlText.ShowWindow( x == 7 ? SW_SHOW : SW_HIDE );
m_ctlCheck.ShowWindow( x == 9 ? SW_SHOW : SW_HIDE );
> wobei ich das gleich anders schreiben würde:> m_ctlButton1.ShowWindow( x == 5 );> m_ctlText.ShowWindow ( x == 7 );> m_ctlCheck.ShowWindow ( x == 9 );> d.h. das boolsche Ergebnis des Vergleichs wird übergeben.
Damit kannst du aber auf die Schnauze fallen :-)