mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C-Code while schleife


Autor: Florian H. (florian1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;"

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
while(!i);
while(i--);

do{
  sendchar(*pointer);
} while(*pointer++);

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.

Autor: fast so (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sind dann eben die Details, die C etwas schwerer lesbar machen...

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Florian H. (florian1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die raschen Antworten...Kann mich da bzg der Lesbarkeit 
nur anschliessen...warum einfach wenns kompliziert auch geht..

Gruss Flo

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)
{
 ...
}

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:
if(err)
{
  ErrHandleFunc(err);
}


VG,
/th.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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...).

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein bischen fies ist in diesem Zusammenhang allerdings der Posix(Unix) 
API, dessen Funktionen ihren Erfolg üblicherweise mit dem Return-Code 0 
bekannt geben.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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
#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.

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
int thprintf(char *string, ...)
{
  va_list tag;
  int i=0;
  char *pointer=0;
  signed int int_tmp=0;
  
  va_start(tag, string);
    
  do
  {  
    if(*string == '%') 
    {
      switch(*(++string))
      {
        case 'i':
        {
          int_tmp = va_arg(tag, int);
        
          if(int_tmp <0)
          {
            fputc('-', 0);
            int_tmp=-int_tmp;
          }
          
          
          pointer = (char*)int_tmp;
          for(i=MAX_NUM_DEC; i; i/=10)
          {                      
            if((int)pointer/i)
            {             
              fputc((int_tmp/i)+48, 0);
              int_tmp%=i;
            }
            else if(i<10) fputc(0+48, 0);
          }        
        } break;
        
        case 'c':
        {        
          fputc((char)va_arg(tag, int), 0);        
        } break;
      
        case 's':
        {
          pointer = va_arg(tag, char*);
          
          do
          {
            fputc(*pointer, 0);          
          } while(*pointer++);                  
        } break;
      }
    } // end if '%'
    
    else if(*string == '\\') 
    {          
      switch(*(++string))
      {
        case 'n': fputc('\n', 0);
          break;
          
        case 't': fputc('\t', 0);
          break;
          
        case 'r': fputc('\r', 0);
          break;
      }  
    } // end if '\'      
    
    else fputc(*string, 0);
  
  } while(*(++string));
    
  va_end(tag);

  return(0);
}

Für die "Anfänger" zum Nachdenken und für die "Profis" zum schmunzeln 
:-)


VG,
/th.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

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

Bewertung
0 lesenswert
nicht lesenswert
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
            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.
            int_tmp = -int_tmp;
vs.
            int_tmp -= int_tmp;

Aber auch das ist letztendlich Geschmackssache.

Genauso wie das hier:
              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?
              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.

  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 :-)
  char *pointer = NULL;

Selbiges für char Variablen bzw. doubles.
  char a = '\0';
  double n = 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
    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
          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 );

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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

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

Bewertung
0 lesenswert
nicht lesenswert
> Sinnvolle Kommentare helfen übigens auch bei der Übersichtlichkeit.

Dieser Punkt ist IMHO einer der Schwierigsten überhaupt.
/* globale Variablen */
int i;
int j;

/* Protoypen */
void FuncA();
void FuncB();

/***************************************/
/* main Funktion                       */
int main()
{
  double o = 0.2;  /* Mehrwertsteuersatz = 20% */
 ....
}

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
     x = o * l;   /* Berechne Bruttopreis aus Mwst und Nettopreis */

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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manche sagen, wenn man zehn Zeilen Kommentar zu einer Zeile braucht, um 
deren Funktion zu beschreiben, dann stimmt mit der Zeile was nicht :-)

Autor: ...... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<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. ;-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angenommen TargetRunning wäre eine Variable.
   while(TargetRunning == 1) {
Dann kann sich (sehr) leicht ein Fehler dieser Art einschleichen:
   while(TargetRunning = 1) {
Und das ist u.U. nur schwer zu finden :-o

Dann müssten die Verfechter der Vergeleichsmethode schon so schreiben:
   while(1 == TargetRunning) {
Damit führe ein fehlendes Gleichheitszeichen zu einem Fehler, weil der 
Konstante 1 nichts zugewiesen werden kann.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joah ...
int_tmp=-int_tmp;
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:
    case 'i':
        {
          int_tmp = va_arg(tag, int);
        
          if(int_tmp <0)
          {
            fputc('-', 0);
            int_tmp=-int_tmp;
          }
          
          
          pointer = (char*)int_tmp;
          for(i=MAX_NUM_DEC; i; i/=10)
          {                      
            if((int)pointer/i)
            {             
              fputc((int_tmp/i)+48, 0);
              int_tmp%=i;
            }
            else if(i<10) fputc(0+48, 0);
          }        
        } 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

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

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

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

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

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

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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**

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
" 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.

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

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl-Heinz, ich komme nicht darauf, warum?

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.