Forum: Mikrocontroller und Digitale Elektronik do/while-schleife


von Ulf (Gast)


Lesenswert?

was ist falsch an der syntax?

ich kann keine eingabe machen, nach dem ich aufgefordert werde, die
frage mit ja oder nein zu beantworten.

do
  {
  printf("Gut gemacht");
        printf("\n");
  printf("\n Nochmal? (J/N)");
  scanf("%c", &b);
  }

while (b=='J' || b=='j');

(ich habe das beispiel ein bissel abgewandelt, damit es einfacher
aussieht.)

von Tobi (Gast)


Lesenswert?

bei mir läuft das beispiel einwandfrei. was für einen typ hat deine
variable b. du solltest vor dem scanf noch den input buffer leeren,
kann sonst zumindest bei dem beispiel probleme geben

von Ulf (Gast)


Lesenswert?

@Tobi

die variable b ist vom typ char (siehe scanf-funktion, c steht für
char)

wie kann ich denn den input puffer leeren?

von Tobi (Gast)


Lesenswert?

das %c heisst ja nicht, dass es wirklich char ist.. :)
fflush(stdin) normalerweise

von Rufus T. Firefly (Gast)


Lesenswert?

Verwende besser statt scanf entweder getc/getch oder gets.

von Ulf (Gast)


Lesenswert?

@Tobi

ich dachte, dass ist so vereinbart unter c.

d=dezimal
x=hex
und c eben char.

wo genau soll ich denn den fflush(stdin) einfügen?

vor die do-schleife?

von Ulf (Gast)


Lesenswert?

@ Rufus T. Firefly

do
  {
  printf("Gut gemacht");
        printf("\n");
  printf("\n Nochmal? (J/N)");
  b=gets(); //oder b=getc();
  }

while (b=='J' || b=='j');

von Rufus T. Firefly (Gast)


Lesenswert?

fflush sollte in Deinem Fall vor den Aufruf von scanf kommen.

von Ulf (Gast)


Lesenswert?

@ Rufus T. Firefly


Habe mit diesem Entleerungsbefehl noch nie gearbeitet.

Sieht die Syntax dann so aus?

do
  {
  printf("Gut gemacht");
        printf("\n");
  printf("\n Nochmal? (J/N)");
  fflush(stdin);
  scanf("%c", &b);
  }

while (b=='J' || b=='j');

von Rufus T. Firefly (Gast)


Lesenswert?

Wenn, dann so.
Besser, aber das habe ich in einem vorherigen Post bereits erwähnt:

Kein scanf verwenden, sondern getc oder getch.

von MSE (Gast)


Lesenswert?

@Ulf:
>>ich dachte, dass ist so vereinbart unter c.
>>d=dezimal
>>x=hex
>>und c eben char.

Die Funktionen printf, scanf & Co führen keinerlei Typprüfung durch. Du
kannst einem printf("%d") statt einem int jeden beliebigen anderen Typ
übergeben. Dann passiert natürlich meist nicht das erwartete, den
Compiler schert es jedoch nicht, er übersetzt es ohne Warnung.

Gruß, Michael

von Ulf (Gast)


Lesenswert?

@ Rufus T. Firefly

ich arbeite zur zeit mit dem c-compiler von keil.

dieser kennt den befehl fflush(stdin); nicht.

muss ich da noch ne header-datei einfügen, in der dieser befehl
vereinbart ist?

wenn ja, welche?

von Rufus T. Firefly (Gast)


Lesenswert?

Such' selbst danach:

findstr /s /c:"fflush" %include%\*.h

(statt %include% nötigenfalls das include-Verzeichnis Deines Compilers
angeben)

Ansonsten: nicht ich habe Dir den fflush-Tip gegeben, also beschwer'
Dich nicht bei mir.

Ich wiederhol's nochmal: Nimm getc/getch!

von Ulf (Gast)


Lesenswert?

@ Rufus T. Firefly

ok danke. jetzt geht´s.

wenn ich getc / getch benutze, sieht dann die schleife wie folgt?

do
  {
  printf("Gut gemacht");
        printf("\n");
  printf("\n Nochmal? (J/N)");
  b=getc(); //oder b=getch();
  }

while (b=='J' || b=='j');

von Rufus T. Firefly (Gast)


Lesenswert?

Was passiert, wenn Du's so ausprobierst?

von Ulf (Gast)


Lesenswert?

@ Rufus T. Firefly

erst mal kommt beim compilieren ne warnung. die kann man ja übergehen.

beim ausführen stockt das programm dann aber. ich kann zwar 'j'
eingeben, aber dann passiert nix. er hängt sich auf. irgendwie
komisch...

hast du noch nen tipp?

von Rufus T. Firefly (Gast)


Lesenswert?

> erst mal kommt beim compilieren ne warnung. die kann man ja
übergehen.

Das machen viele. Und wundern sich.

Lass' Dein Programm doch mal im Debugger laufen.

von Peter D. (peda)


Lesenswert?

"erst mal kommt beim compilieren ne warnung. die kann man ja
übergehen."

Wo steht denn das ?

Eine Warnung ist in der Regel nicht nutzlos (bis auf Ausnahmen, z.B.
beim AVR-GCC: suggest parentheses around && within || ).

Man muß sie verstehen und dann erst weiß man ob man sie übergehen kann.
Besser ist allerdings, den Quelltext so umzuschreiben, daß die Warnung
entfällt.


Peter

von Matthias (Gast)


Lesenswert?

Hi

@MSE
>Die Funktionen printf, scanf & Co führen keinerlei Typprüfung durch.
Du
>kannst einem printf("%d") statt einem int jeden beliebigen anderen
Typ
>übergeben. Dann passiert natürlich meist nicht das erwartete, den
>Compiler schert es jedoch nicht, er übersetzt es ohne Warnung.

Der GCC bringt da durchaus eine Warnung.

Matthias

von Tobi (Gast)


Lesenswert?

"Der GCC bringt da durchaus eine Warnung."

das liegt aber, wie hier vor kurzem schon einmal festgestellt wurde an
einer speziellen erweiterung des gcc die nicht standard ist.
normalerweise kann ein compiler nicht das format von diesen befehlen
überprüfen

@rufus

die warnung besagt bei mir zumindest,dass getc zu wenig parameter
hat.(normaler win gcc) allerdings bleibt das problem, dass das programm
sofort nach egal welcher eingabe abbricht, da noch zeichen im
eingabepuffer sind (mindestns das enter)

von Matthias (Gast)


Lesenswert?

Hi

und? Ist das jetzt negativ das der GCC einen vor evtl.
Programmierfehlern warnt?

Peter schreibt z.B.
>Eine Warnung ist in der Regel nicht nutzlos (bis auf Ausnahmen,
>z.B. beim AVR-GCC: suggest parentheses around && within || ).

Warum soll denn diese Warnung nutzlos sein? && bindet stärker als ||.
Das ist nicht unbedingt allgemein bekannt und kann schonmal zu Fehlern
führen bzw. erleichtert eine Klammer um den Ausdruck beim überfliegen
von fremdem Sourcecode die Lesbarkeit.
Ich hab in den letzten Wochen in mehrere kLOC eingelesen. Da ist man um
jede Erleichterung froh. Und diese Warnungen ermutigen den Programmierer
lesbaren Code zu erzeugen.


Matthias

von Tobi (Gast)


Lesenswert?

"und? Ist das jetzt negativ das der GCC einen vor evtl.
Programmierfehlern warnt?"

nein, ganz sicher nicht. ich wollte damit nur sagen, dass man sich
darauf nicht verlassen kann/soll.

meistens sind compiler-warnung sehr sinnvoll und zur not kann man ja
alles ausschalten :)

von Rufus T. Firefly (Gast)


Lesenswert?

Na, Tobi, wenn die Warnung besagt, daß getc() zu wenige Parameter hat,
dann solltest Du Dir mal die Dokumentation ansehen, die beschreibt, wie
getc() zu verwenden ist - offensichtlich machst Du da was falsch.
Das ist ja der Sinn von Warnungen ...

von Tobi (Gast)


Lesenswert?

ich hab in der hilfe geschaut und weiss auch was da hinkommt. das war
mehr ein hinweis an den threadstarter, der sich wegen einem fehler
wunderte.
ich suche immer erst selber, bevor ich andere frage

von Zotteljedi (Gast)


Lesenswert?

@Tobi:

ISO/IEC 9899:1999 sagt:

7.19.5.2, Absatz 2:

If stream points to an output stream or an update stream in which the
most recent operation was not input, the fflush function causes any
unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.


Kurz: fflush(stdin) kann alles mögliche veranlassen, man sollte sich
also auf nichts verlassen, und schon gar nicht, daß es dieses Problem
zuverlässig löst. Wenn es klappt, dann weil Dein Compiler und Deine
libc es gut mit Dir meinen, kann morgen oder gar auf einer anderen
Plattform schon ganz anders aussehen.

von Tobi (Gast)


Lesenswert?

ok, werd ich mich mal bei meinem prof beschweren, haben wir dort
gelernt.

womit kann man denn iso kompatibel die daten in einem stream verwerfen?

von Zotteljedi (Gast)


Lesenswert?

Gar nicht :-(

Du kannst es nur weglesen. Wenn Du z.B. weißt, daß als nächstes
erwünschtes Zeichen eine Ziffer kommt, kannst Du solange mit fgetc
lesen, bis isdigit() greift, die erste Ziffer mit fungetc wieder
zurückschreiben, und dann mit scanf drangehen. fungetc ist iirc aber
auch nur auf ein einziges Zeichen definiert.

scanf habe ich übrigens wegen der zahlreichen Komplikationen, die einem
ständig irgendwie in die Beine springen, bisher so weit gemieden wie
möglich, und das mit Erfolg.

von Peter D. (peda)


Lesenswert?

"Warum soll denn diese Warnung nutzlos sein? && bindet stärker als
||."


Ich erwarte von einer Programmiersprache, daß sie streng logisch ist.
Aber nur bei einer bestimmten Vorrangregel zu warnen ist doch völlig
unlogisch.

Wenn eine Warnung, dann aber gefälligst auch bei sämtlichen anderen
kombinierten Ausdrücken:

warning: suggest parentheses around * within +
warning: suggest parentheses around % within -
warning: suggest parentheses around + within &
warning: suggest parentheses around | within &&
usw. usw.

Entweder ich kenne die Vorrangregeln oder ich nehme Klammern.


Peter

von Matthias (Gast)


Lesenswert?

Hi

die Erfahrung von vielen C-Programmierern zeigt eben das dieses
Verhalten (und speziell dieses) bei if-Abfragen zu Fehlern führt.

Matthias

von Peter D. (peda)


Lesenswert?

@Matthias,

aber dann wohl nur bei GCC-Programmierern :)

Weder Borland noch Microsoft Visual C++ usw. kennen diese Warnung.

Ich toleriers ja auch, daß manche Entwickler eben ihre persönliche Note
reinbringen wollen, ist ja schließlich kostenlos.
Aber sagen darf ich doch, daß ich persönlich solche Ungleichbehandlung
unlogisch und überflüssig finde. Ich würde es bei einem
kostenpflichtigen Compiler jedenfalls als Bug reklamieren.


Peter

von Thomas (Gast)


Lesenswert?

selbst vc++ liefert bei gewissen konstrukten warnungen mit der
empfehlung, klammern zu setzen. ich weiss jetzt nicht mehr genau wann,
möglicherweise bei ausdrücken welche shiftoperationen zusammen mit
weiteren bitweisen operatoren enthalten. hab schon ewigs nicht mehr mit
vc++ gearbeitet.

auch hier ist der grund, dass viele programmierer die
operatorpräzedenzen von c nicht soo genau kennen (wozu auch, dazu gibts
schliesslich klammern:) bzw. hier eine häufige fehlerquelle liegt.

von Matthias (Gast)


Lesenswert?

Hi

@peter
>aber dann wohl nur bei GCC-Programmierern :)

Na was meinst du warum M$-Software im allgemeinen mehr Bugs als kByte
Programmcode hat ;-)


Matthias

von Zotteljedi (Gast)


Lesenswert?

Ach, das ist der Grund warum die Programme immer unflätiger in der Größe
werden, man will also die Bugs/Byte Ratio drücken! Und da die Herren
wohl an der Variable Bugs nichts ändern können... :-)

von Matthias (Gast)


Lesenswert?

Hi

wie beginnt jedes M$-Programm?
char make_programm_look_big[1000000*WINDOWS_VERSION];

Matthias

von Michael (ein anderer) (Gast)


Lesenswert?

@peter dannegger:

> Weder Borland noch Microsoft Visual C++ usw. kennen diese Warnung.

   [...]

> Aber sagen darf ich doch, daß ich persönlich solche
> Ungleichbehandlung unlogisch und überflüssig finde. Ich würde
> es bei einem kostenpflichtigen Compiler jedenfalls als
> Bug reklamieren.

Oh, mann!!!  Software-Qualität ist bei Dir wohl auch ein Bug, wie???

Mach' doch mal die Augen auf: Unmengen von Viren und
Sicherheitsproblemen bei Windows-Plattform die zum Großteil auf simple
Programmierfehler zurück zu führen sind. Buffer- und Integer-Overflows,
switch-Statements mit fehlenden default-Label, unintialisierte
Variablen, falsche if-Statements etc. Über 3/4 dieser Fehler kann ein
Compiler entdecken!

Und jetzt gibt's das auch alles kostenlos bei ganz normaler
Elektronik, da überall Mikrocontroller drinn sind und diese
Mikrocontroller mit kaputten Compilern programmiert werden oder der
Peter den Compiler zurück gibt, wenn er ihn vor einem Fehler warnt.

Und warum das nur? Na, weil der Borland-Compiler keine Warnung ausgibt,
und der Peter dieses kaputte Verhaltener als "Standart" erhoben hat.

Getreu nach dem Motto: Das kaputte Borland- und Microsoft-Verhalten
gleich mal auf die Alltags-Elektronik übertragen.

Man, man, man... Mach' mal Deine Augen auf und erweitere Deinen
Horizont!

Software-Qualität ist wichtiger denn je! Und dafür braucht es
ordentliche Werkzeuge die den Programmierer ordentlich unterstützen.
Wenn ein Programm schon in einer kaputten Programmiersprache wie z.B.
'C' oder 'C++' erstellt werden muss, dann muss der Compiler den
Programmierer vor möglichst allen Problemen warnen und möglichst alle
Fehler entdecken.

Aber solange es noch "Hacker" (Programmierer sind das keine) gibt,
die eine gerechtfertigte Warnung des Compilers als Bug klassifizieren,
solange dürfen wir uns über abstürzende Fernseher und Waschmaschinen
und Viren auf'm Handy erfreuen.

von Zotteljedi (Gast)


Lesenswert?

Vielleicht sollten auch Leute, die nicht programmieren können, keine
Software für Mikrocontroller oder sonstwas schreiben, von dem
wesentlich mehr abhängt als ein entgangener Highscore, weil die
Heldenfigur durch den Boden gefallen ist, weil einer das Vorzeichen
versaubeutelt hat.

Es gibt selbstverständlich Sprachen, die es einem schwieriger machen
Mist zu bauen, aber das ist keine Entschuldigung dafür, daß Leute Mist
bauen, weil sie ihre Sprache nicht können.

Allerdings finde ich es auch gut, wenn mich der Compiler bei Dingen die
ihm suspekt erscheinen anbläst, aber wenn ich das nicht gezielt
abstellen könnte, würde es mich auch ankotzen.

Manchmal nutze ich sehr gerne -ansi -pedantic, dann ist es auch OK wenn
er darauf besteht, daß eine Quelle in einem Newline endet. Meine
Programme verlassen meinen Rechner auch nicht, wenn sie bei -Wall noch
mucken. Aber wenn ich sowas wie

while(*s)
  *p++ = *s++;

meine, dann will ich nicht

while(*s != NULL)
{
  *(p++) = *(s++);
}

hinschreiben müssen. Gerade der Vergleich auf 0 ging mir bei den
ersten Javaexperimenten tierisch auf den Keks. if (i) war eben nicht
OK, es musste if (i != 0) sein... aber ich schweife ab.

von Rufus T. Firefly (Gast)


Lesenswert?

Zotteljedi: Danke.

von Peter D. (peda)


Lesenswert?

Zotteljedi: auch Danke.


@Michael (ein anderer),

wer denkt, daß ein Compiler einem in den Kopf sehen kann, ob ein
Konstrukt potentiell anders gemeint sein könnte, der ist aber sowas von
auf dem Holzweg.

Warnungen, die funktional völlig richtigen Kode anmeckern, wiegen Dich
nur in einer Scheinsicherheit und verleiten zu weniger Sorgfalt.
Das Risiko von Programmierfehlern erhöht sich dadurch also nur.

Logische Fehler kann eh kein Kompiler entdecken.
Der Kompiler ist kein Mensch, er kann also den Kode nicht verstehen.


Peter

von Rufus T. Firefly (Gast)


Lesenswert?

Peter: Danke.

Du bist zwar in einigen Dingen anderer Ansicht als ich, aber ich
gewinne den Eindruck, daß Du Dich schon etwas länger als ein, zwei
Jahre mit der Materie beschäftigen dürftest ...

Zum mich-in-träumerische-Sicherheit-wiegen nehme ich PC-Lint, um zu
wissen, was passiert, einen Debugger.

von Michael (ein anderer) (Gast)


Lesenswert?

@peter dannegger:

Ich habe nie behauptet, dass ein Compiler logische Fehler entdecken
kann. Was er jedoch wunderbar machen kann, ist den Execution-Path zu
analysieren. Und auf diesem Weg kann ein Compiler eine große Menge
Probleme entdecken.

Wenn ISO-C99 definiert, wie bei scanf und printf die Argumente zum
Format-String passen müssen, ist es für einen ISO-C99 Compiler
überhaupt kein Problem, diese Information auch zu verwerten und zu
analysieren.

Nach der Argumentationsweise, Sicherheitsmasnahmen (Warnungen) wiegen
die Benutzer (Programmierer) in falscher Sicherheit und würden zu
Leichtsinn führen, kann man sämtliche Sicherheitsvorkehrung
anzweifeln.

Beispiel Auto: Danach wäre ein Fahrzeug mit Gurt, Airbag, ABS und
aktivem Fahrwerk potentiell gefährlicher, als ein Auto ohne diese
Einrichtungen.

Richtig ist natürlich, dass es einen Prozentsatz von Autofahrern gibt,
die sich tatsächlich in falscher Sicherheit wägen und aufgrund der
Ausstattung ihrers Autos meinen, ihnen könne nichts passieren und
deshalb sehr risikoreich fahren.

Analog gibt es "Programmierer", die Code zusammen hacken, den durch
den Compiler mit -Wall -pedantic -Werror schicken, und wenn der Code
dann kompiliert, ihn als Fehlerfrei deklarieren.

So funktioniert das natürlich nicht. Diese "Programmierer" werden
ebenfalls wie die oben genannten Autofahrer über kurz oder lang auf die
Nase fallen.

Entscheidend ist doch aber, was unterm Strich übrig bleibt. Und da
führen in der Summe beim Auto Gurt, Airbag, ABS usw. ebenso wie
Warnungen bei Compileren, zu einem minimierten Risiko.

Es ist auch nie Ziel gewesen, garantiert aller Probleme zu eliminieren.
Das wird (wahrscheinlich) auch nie gelingen, da der Faktor Mensch unsere
Welt einfach ausmacht. Aber man kann sich dem Ideal annähern.

von Peter D. (peda)


Lesenswert?

@Michael (ein anderer)

"Was er jedoch wunderbar machen kann, ist den Execution-Path zu
analysieren."

Können könnte er, aber scheinbar macht das keiner, den ich kenne.

Z.B. passiert es oft, daß durch Schreibfehler Bedingungen konstant 0
oder 1 werden und der Compiler diese stillschweigend wegoptimiert.
Da wäre eine Warnung durchaus angebracht.
Auch jedes andere Wegoptimieren sollte angewarnt werden, z.B. leere
Delayschleifen usw.


Eine OR-Verknüpfung mehrerer UNDs ist aber quasi ein Standardkonstrukt,
d.h. in der Regel kein Schreibfehler, deshalb ärgert mich eben diese
Warnung.


Am besten wäre natürlich, wenn man die Warnungen einzeln aus- und
einschalten könnte, am allerbesten sogar auf einzelne Codeteile
beschränkt (z.B. mittels pragma).


Peter

von Rufus T. Firefly (Gast)


Lesenswert?

Wenn in einem Compiler der Aufwand getrieben wird, einige spezielle
Funktionen mit vararg-Argumenten auf korrekte Typisierung zu
überprüfen, dann sollte auch ein Mechanismus geschaffen werden, diesen
Aufwand auf andere vararg-Funktionen zu erweitern.

Sonst werden folgende drei Beispiele unterschiedlich interpretiert:


  int printf(const char *, ...);

  printf("Das ist ein %d Fehler\n", "Fehler");



  int MyOwnSpecialPrintf(const char *, ...);

  MyOwnSpecialPrintf("Das ist ein %d Fehler\n", "Fehler");



  int MyVeryOwnSpecialPrintf(const char *, ...);

  MyVeryOwnSpecialPrintf("Das ist ein ###d Fehler\n", "Fehler");


Das erste Beispiel ist die Standardvariante, das zweite eine, die sich
nur durch den Funktionsnamen unterscheidet, und das dritte eines, bei
dem ein anders strukturierter Formatstring verwendet wird, was ja
jemand aus-was-auch-immer für Gründen schick finden könnte.


Der Compiler wird nur bei der ersten Variante motzen, und dann kann
man's auch sein lassen.

Typüberprüfung nur bei Verwendung einiger weniger Standardfunktionen?

Nee, das ist 'ne Gurkenlösung.

Übrigens: Welcher der auf dem Markt befindlichen C-Compiler ist
überhaupt ein C99-Compiler?
Üblich ist immer noch C89/90, also Ansi-C.

von Zotteljedi (Gast)


Lesenswert?

@Peter:

> Am besten wäre natürlich, wenn man die Warnungen einzeln aus- und
> einschalten könnte, am allerbesten sogar auf einzelne Codeteile
> beschränkt (z.B. mittels pragma).

Je nachdem wie fein granuliert Du's haben willst, ist -Wno-parentheses
vielleicht was für Dich. Pragmas fände ich persönlich nicht so schön,
weil es die Sache wieder compilerabhängig macht (da sie nicht
vorgeschrieben sind könnte ein anderer Compiler nämlich was ganz
furchtbar dummes machen, dürfen dürfte er es zumindest).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.