mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verständnisproblem bei C-Programmierung


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe einen Auf- und Abwartszähler für ein LC-Display in C mit ATMega16 
programmiert. Der Code funktionierte, war aber noch etwas lang. Habe ihn 
also etwas gekürzt. Darauf hin funktionierte nur noch das 
Aufwärtszählen. Ich kann mir nicht erklären warum nur noch das 
Aufwärtszählen funktioniert und das Abwärtszählen nicht. Kann mir das 
jemand erklären? Oder habe ich einen Fehler gemacht, den ich nicht 
entdeckt habe?

Hier die Programmausschnitte.

Funktionierende Abwärtszählung
if ((*z_i <= 48 ) & (*e_i <= 48))
   {
       *h_i = *h_i - 1;
  
        *z_i = 57;
        *e_i = 57;
   }

   else
   {
        if (*e_i <=48)
        {
          *z_i = *z_i - 1;
          *e_i = 57;
        }
            
        else
        {
          *e_i = *e_i - 1;
        }
   } 

Funktionierende Aufwärtszählung gekürzt
if ((*z_u & *e_u) >= 57)
{
        *h_u = *h_u + 1;

        *z_u = 48;
        *e_u = 48;
}

else
{
        if (*e_u >=57)
        {
           *z_u = *z_u + 1;
           *e_u = 48;
        }    

        else
        {
            *e_u = *e_u + 1;
        }
}

Nichtfunktionierende Abwärtszählung gekürzt
if ((*z_u & *e_u) <= 48)
{
        *h_u = *h_u - 1;

        *z_u = 57;
        *e_u = 57;
}

else
{
        if (*e_u <= 48)
        {
          *z_u = *z_u - 1;
          *e_u = 57;
        }    

        else
        {
          *e_u = *e_u - 1;
        }
}

Autor: us73 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kennst den Unterschied zwischen "bitwise AND" und "logical AND" ??

Ich bin mir nahezu sicher, dass Du statt "&" hier besser "&&" verwenden 
solltest..., weil ich kann mir nicht vorstellen, dass Du die 
Dereferenzierungen von z_u und e_u bitwise UND verknüpfen willst.

Autor: us73 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zudem sind das zwei Bedingungen, die Du prüfen willst. Also prüfe sie 
auch getrennt.

if ((*z_u <= 48) &&  (*e_u <= 48))

Da gibt es nichts zu verkürzen.

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

Bewertung
0 lesenswert
nicht lesenswert
Deine magischen Konstanten kommen mir aber sehr bekannt vor.

Wenn du den Code so schreiben würdest
    if ((*z_i <= '0' ) && (*e_i <= '0' ))
   {
       *h_i = *h_i - 1;
  
        *z_i = '9';
        *e_i = '9';
   }

   else
   {
        if (*e_i <= '0')
        {
          *z_i = *z_i - 1;
          *e_i = '9';
        }
            
        else
        {
          *e_i = *e_i - 1;
        }
   } 

dann wäre wenigstens ansatzweise klar, dass dein Zähler im Grunde im 
ASCII Code zählt.

Noch einfacher wäre es allerdings, wenn du das Ganze so machst, wie man 
das auch mit Papier und Bleistift machen würde. Man fängt bei den Einern 
an und subtrahiert 1. Bei einem Unterlauf (borgen von der nächsten 
Stelle) arbeitet man sich dann immer weiter 'nach links' vor.
     *e_i = *e_i - 1;          // Einerstelle 1 abziehen

     if( *e_i < '0' )          // Unterlauf?
     { 
       *z_i = *z_i - 1;        //    von den Zehnern eines runter
       *e_i = '9';

       if( *z_i < '0' )        //    Zehner Unterlauf?
       {
         *h_i = *h_i - 1;      //        von den Hundertern eines runter
         *z_i = '9';           
       }
     }

In vielen Fällen ist es klug, einfach zu beobachten wie man selbst ein 
Problem mit Papier und Bleistift löst, und diese Lösungsstrategie dann 
in Code umsetzt.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Hilfe. Habe den vereinfachten Code benutzt. Jetzt 
klappt es einwandfrei. Auch das mit dem ASCII war sehr nützlich, war mir 
gar nicht klar, dass ich das in dieser Form so machen kann.

Was ich jetzt noch gerne zum Verständnis und für das nächste mal genauer 
wissen würde ist:
Warum hat das hier geklappt mit dem Verknüpfen:
if ((*z_u & *e_u) >= 57)

und hier nicht?
if ((*z_u & *e_u) <= 48)

Mal davon abgesehen das es hier besser wäre logisch statt bitweise zu 
verknpüfen, weil das erste hat ja trotzdem funktioniert.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:

> Warum hat das hier geklappt mit dem Verknüpfen:
>
if ((*z_u & *e_u) >= 57)
>
> und hier nicht?
>
if ((*z_u & *e_u) <= 48)

Weil das ganz was anderes macht.

Hier wird *z_u  mit *e_u UND verknüpft und das Ergebnis der Verknüfung 
befragt, ob es kleiner als 48 ist.

Autor: us73 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian schrieb:
> Warum hat das hier geklappt mit dem Verknüpfen:if ((*z_u & *e_u) >= 57)
> und hier nicht?if ((*z_u & *e_u) <= 48)

Weil eben das Ergebnis der Operation >= 57 war.
Ich würde es als zufällig richtiges Verhalten bezeichnen - und nicht als 
gewünscht.
Es hätte ebenso auch andersrum sein können - oder auch gar nicht.
Rein zufällig, und auch abhängig von den Daten, die Du bereitstellst. 
Aber nicht so, wie Du das haben wolltest...

Christian schrieb:
> Mal davon abgesehen das es hier besser wäre logisch statt bitweise zu
> verknpüfen, weil das erste hat ja trotzdem funktioniert.

Es wäre nicht besser. Es wäre richtig.

Logisch und Bitweise sind wie Apfel und Birne, das hat miteinander 
nichts zu tun, zwei komplett unterschiedliche Operationen.

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.