www.mikrocontroller.net

Forum: Compiler & IDEs While Schleife bricht nicht ab


Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe grade versucht den folgenden Code auf einem Mega168 zu benutzen
#include "utils/strings.h"

unsigned char itoa(unsigned int uiVal, char* pBuff)
{
  unsigned char ucIndex = 0;
  unsigned char ucHelper = 0;
  unsigned char ucLenght = 0;
  
  char cDigit;
  
  do
  {
    cDigit = '0' + uiVal % 10;
    pBuff[ucIndex++] = cDigit;
  }
  while(uiVal /= 10);
  
  ucLenght = ucIndex;
  pBuff[ucIndex--] = 0;
  
  while(ucHelper < ucIndex)
  {
    cDigit = pBuff[ucIndex];
    pBuff[ucIndex--] = pBuff[ucHelper];
    pBuff[ucHelper++] = cDigit;
  }
  
  return ucLenght;
}

Das Teil soll einfach einen Integer in einen ASCII String umwandeln. Das 
hat auch mal funktioniert, als ich es in nem C++ Projekt benutzt habe. 
Jetzt ist es in C-Projekt.

Allerdings bricht die obere while Schleife nicht ab. Ich hab mir per 
UART mal uiVal ausgeben lassen und das ist irgendwann 0. Allerdings 
scheint die Abbruchbedingung die Schleife absolut nicht zu kratzen. Der 
rennt da fröhlich weiter drin rum und schreibt den RAM voll.


Ich bin langsam so durcheinander, dass ich vorne und hinten 
verwechsel... Mal besser ne Pause machen.

Achso... Fragt mich nicht, warum ich nicht die stdlib.h nutze. Tu ich 
gleich. Nur will ich jetzt einfach wissen, wieso der Scheiß da nicht 
funktioniert grr

Autor: Willivonbienemaya .. (willivonbienemaya)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"uiVal /= 10" ist eine Zuweisung.
Mach mal eine Bedingung daraus.

Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C++ scheint das allerdings wunderbar zu funktionieren!
A property that C++ has over other programming languages is that the assignment operation can be used as the rvalue (or part of an rvalue) for another assignment operation. For example:

a = 2 + (b = 5);

is equivalent to:

b = 5;
a = 2 + b;
http://www.cplusplus.com/doc/tutorial/operators.html

Entweder da kommt bei mir oben was gleich 0 oder ungleich 0 raus.
Gleich 0: false
Ungleich 0: true


Aber damit wäre geklärt, warum das nicht geht. In C scheint das nicht so 
zu sein ;)


edit:
Grade getestet.
Beispiel in C++:
#include <iostream>
using namespace std;

int main(void)
{
        do
        {
                cout << "hallo" << endl;
        }
        while(0);

        do
        {
                cout << "hallo2" << endl;
        }
        while(1);

        return 0;
}

Die 2. Schleife läuft ewig.

Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm... Nochmal editieren darf ich nicht ;)

So... Um nochmal Klarheit zu schaffen: Es ist eine C++ Eigenheit, dass 
der Rückgabewert einer Zuweisung der rechtsseitige Wert der selbigen 
ist. Somit funktioniert der Kram von mir da oben in C++ aber nicht in C.
Das is aber auch dreckig ;)

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Galauner wrote:
> So... Um nochmal Klarheit zu schaffen: Es ist eine C++ Eigenheit, dass
> der Rückgabewert einer Zuweisung der rechtsseitige Wert der selbigen
> ist. Somit funktioniert der Kram von mir da oben in C++ aber nicht in C.
> Das is aber auch dreckig ;)

??? Das ist doch in ANSI-C genau so. Eigentlich müsste die Routine 
meiner Meinung nach funktionieren, wenn die Operationen korrekt 
ausgeführt werden.

PS: Da der Mega-AVR Divisionen in Software ausführen muss, ist das kein 
effizientes Verfahren zur Umwandlung.

Und warum heißt die Funktion eigentlich itoa, wenn du unsigned(!) int 
umwandeln willst. Verwirrst du dich gern selbst?

Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja... Sie geht nicht ;)
Und ob effizient oder nicht is jetzt auch egal. Ich will nur wissen, 
wieso das nicht funktioniert. Die einzige Erklärung die ich dazu hab ist 
wirklich, dass aus der Zuweisung immer irgendwas != 0 rauskommt. Weiß 
der Geier wieso.

>Und warum heißt die Funktion eigentlich itoa, wenn du unsigned(!) int
>umwandeln willst. Verwirrst du dich gern selbst?
Verwirrt mich nicht. Ich hab ja ne Parameterliste ;)

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

Bewertung
0 lesenswert
nicht lesenswert
Du weißt aber, dass es ein itoa() in der Bibliothek gibt?

Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Du weißt aber, dass es ein itoa() in der Bibliothek gibt?

Ich zitier mich mal selbst:
>Achso... Fragt mich nicht, warum ich nicht die stdlib.h nutze. Tu ich
>gleich. Nur will ich jetzt einfach wissen, wieso der Scheiß da nicht
>funktioniert *grr*

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe keinen Grund, warum die Schleife nicht funktionieren sollte. Ob 
C oder C++, es gilt immer noch, dass alle assign-ops den abschliessenden 
Wert der linken(!) Seite wiederspiegeln, und das in diesem Zusammenhang 
bekanntere "++i" ist exakt äquivalent zu "i += 1".

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WinAVR20071221 produziert erwartungsgemäß für
while(uiVal /= 10);
und
while((uiVal /= 10)!=0);

(mit Optimierung -Os) exakt den gleichen Code.

Oliver

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Simulator von AVR Studio bricht bei mir die Schleife ab. (testwerte 
0, 10, 1234).

Welche Revision des Compilers benutzt du denn? Vielleicht gibt es da ja 
einen bereits dokumentierten Bug.

Autor: Andreas G. (andy1988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR-GCC 4.3.0
Aus dem AVR MacPack: http://www.obdev.at/products/avrmacpack/index.html

Allerdings mit dem GNU99 Standard kompiliert. Sollte aber nicht so viel 
dran ändern, oder?

Autor: Manuel Stahl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Teste doch mal obs an dem Zuweisungsproblem liegt:
#include "utils/strings.h"

unsigned char itoa(unsigned int uiVal, char* pBuff)
{
  unsigned char ucIndex = 0;
  unsigned char ucHelper = 0;
  unsigned char ucLenght = 0;
  
  char cDigit;
  
  do
  {
    cDigit = '0' + uiVal % 10;
    pBuff[ucIndex++] = cDigit;
    uiVal /= 10;
  }
  while(uiVal);
  
  ucLenght = ucIndex;
  pBuff[ucIndex--] = 0;
  
  while(ucHelper < ucIndex)
  {
    cDigit = pBuff[ucIndex];
    pBuff[ucIndex--] = pBuff[ucHelper];
    pBuff[ucHelper++] = cDigit;
  }
  
  return ucLenght;
}

Das sollte ja dann gehen. Ich hab aber schon öfter bemerkt, dass der GCC 
eine Warnung ausgiebt, wenn man sowas schreibt:
if(a = b) {
 ...
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das sollte ja dann gehen. Ich hab aber schon öfter bemerkt, dass der GCC
>eine Warnung ausgiebt, wenn man sowas schreibt:

>if(a = b) {

Jupp, dann sollte man weitere Klammern setzen:

if((a = b)) {

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

Bewertung
0 lesenswert
nicht lesenswert
Manuel Stahl wrote:

> Ich hab aber schon öfter bemerkt, dass der GCC
> eine Warnung ausgiebt, wenn man sowas schreibt:
>
>
> if(a = b) {
>  ...
> }
> 

Klar, weil es ein häufiger Flüchtigkeitsfehler ist, dass man bei einem
Vergleich auf Gleichheit eins der beiden Gleichheitszeichen vergisst.

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.