Guten Tag, folgendes Progtramm zum Setzen von einzelnen Bits(für 8 Bit Register), habe ich soeben geschrieben. Ist dieses korrekt oder habe ich etwas übersehen? // setBit-Funktion #include<stdio.h> /*********************************************************************** *******/ unsigned char setBit(unsigned char, int); /*********************************************************************** *******/ int main(void) { unsigned char new_value; unsigned char value; int position; printf("Wert eingeben(z.B.: 0x67): 0x"); scanf("%X", &value); printf("Stelle fuer das zu setzende Bit eingeben(0 bis 7): "); scanf("%i", &position); new_value = setBit(value, position); printf("Der neue Wert betraegt: 0x%.2X\n\n", new_value); system("pause"); return 0; } /*********************************************************************** *******/ unsigned char setBit(unsigned char value, int position) { value = value | (1<<position); return value; } /*********************************************************************** *******/ Grüße Austrianer
>Ist dieses korrekt oder habe ich etwas übersehen?
Trau Dir selbst mehr zu.
Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es
tun soll!
Definiere was das Programm tun soll, prüfe das nach und Du weisst es.
Ich bin einfach noch extrem unsicher und deswegen wende ich mich an die Profis :-)
>Ich bin einfach noch extrem unsicher und deswegen wende ich mich an die >Profis :-) Ich verstehe das. Sicherheit erhälst Du aber nur, wenn Du es selber versuchst und eigene Fehler machst. Nicht, indem Du die Fehler von anderen vermeiden lässt. Und zum versuchen gehört beim programmieren nicht nur das Programm zu schreiben sondern auch: 1. Beschreiben was das Programm machen soll. 2. Einen Entwurf machen 3. Implementieren 4. Testfälle definieren 5. Testen 6. Ergebnisse auswerten 7. Programm korrigieren Gerade bei so einem trivialen Fall, kannst Du vor allem bei den Grundlagen was lernen was Du nicht erst in komplexeren Fällen lernen solltest. Wir können das schon sind aber durch die selbe Schule gegangen. Also. Versuch einfach mal.
Und noch was: Fehler machen gehört zum Lernprozess dazu. Dazu gehört auch, dass man lernt, wie man seine Fehler feststellt ehe man sie behebt. Also: keine Scheu vor Fehlern. Es passiert ja nichts in dem Sinne, das irgendwas kaputt werden würde. Das Rechenergebnis ist halt nicht das was es sein sollte. Dazu musst du aber wissen, was eigentlich raus kommen sollte und mit dem vergleichen was raus kommt. Das ist alles. Wenn du Bitoperationen verstanden hast, wenn du den Zusammenhang von Binärdarstellung und Hexadezimalzahlen verstanden hast, dann ist das überhaupt kein Problem. In dem Sinne ist es auch eine Überprüfung für dich selber, ob du diese Dinge verstanden hast. ALso: Nicht zurücklehnen und sagen "Super da kommt jetzt das raus" sondern "Als nächstes gebe ich das und das als Eingabe in mein Programm und ich erwarte, dass das Ergebnis dieses und jenes ist". Und dann kommt die spannende Frage: Kommt das von dir vorhergesagte Ergebnis auch raus. D.h. du musst vorher schon wissen, was rauskommen müsste, und dann vergleichst du mit der Ausgabe deines Progammes. Wenn beides nicht übereinstimmt, gibt es 2 Möglichkeiten: entweder deine Vorhersage ist falsch (in dem Fall kann dir das Programm helfen dein Wissen aufgrund dessen du deine Vorhersage ge,acht hast zu präzisieren) oder das Programm ist falsch. Das alles gehört zum Lernprozess und ist nichts schlechtes. Nur: Das musst DU machen. Malen lernt man nur indem man selber malt!
Dominik M. schrieb: > printf("Der neue Wert betraegt: 0x%.2X\n\n", new_value); Merkwürdige Formatanweisung. Warum nicht 0x%02X?
>.2 = 02 >Liege ich da falsch? Ich fürchte ich gehe Dir furchterlich auf den Wecker, aber: Was sagt denn die Dokumentation des printf Befehls dazu? Ich nehme zu Deinen Gunsten an, das die Doku schon gelesen hast und unsicher bei der Interpretation bist. Falls das zutrifft, beschreibe doch mal was Du gelesen hast (Zitat) und was Du daran verstanden hast. Dann können wir sinnreich weiterhelfen so das Du auch was dabei lernst. Die Art wie Du Fragen stellst, zieht normalerweise eine Rechnung nach sich. :-)
Der Punkt kommt normalerweise nur bei Gleitkommazahlen vor und trennt die Angabe der kompletten Anzahl der Stellen von der Angabe wieviele davon Nachkommastellen sein sollen. Bei Ganzzahlen gibt es aber keinen Dezimalpunkt. Kann eventuell sein, dass deine printf IMplementierung den . ignoriert. Richtig ist es IMHO aber trotzdem nicht. Wenn du führende 0-en haben willst, dann brauchst du eine 0 im Formatstring! Steht aber alles auch in der Doku zu printf
Karl Heinz Buchegger schrieb: > Bei Ganzzahlen gibt es aber keinen Dezimalpunkt. Kann eventuell sein, > dass deine printf IMplementierung den . ignoriert. Richtig ist es IMHO > aber trotzdem nicht. Jetzt bist aber du auf dem Holzweg. Der Punkt hat auch bei den Inte- gerformaten eine Bedeutung. Welche, das verrät jedes bessere C-Buch ;-)
Noname schrieb: > Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es > tun soll! Nein. Das ist einer der häufigsten Irrtümer: Ein Programm macht, was es tun soll, und es wird deshalb als korrekt angesehen. Das einzige, was sicher ist: F: "Was ist das Zeichen, das ein Programm nicht korrekt ist?" A: "Es macht nicht das, was es tun soll!" Daraus die obige Aussege zu folgern ist aber nicht möglich. Nochmal zum Mitschreiben: 1) Programm tut nicht was es soll => Programm ist falsch Gleichbedeutend mit 1) ist: 2) Programm ist korrekt => Programm tut was es soll Folgende beiden Aussagen 3) und 4) sind auch äquivalent zueinander, aber weder äquivalent zu 1) noch zu 2): 3) Programm tut was es soll => Programm ist korrekt 4) Programm ist nicht korrekt => Programm tut nicht was es soll
Yalu X. schrieb: > Karl Heinz Buchegger schrieb: >> Bei Ganzzahlen gibt es aber keinen Dezimalpunkt. Kann eventuell sein, >> dass deine printf IMplementierung den . ignoriert. Richtig ist es IMHO >> aber trotzdem nicht. > > Jetzt bist aber du auf dem Holzweg. Der Punkt hat auch bei den Inte- > gerformaten eine Bedeutung. Welche, das verrät jedes bessere C-Buch ;-) Echt? Muss ich gleich mal googeln. :-) (Danke für den Hinweis)
Karl Heinz Buchegger schrieb: > Yalu X. schrieb: >> Karl Heinz Buchegger schrieb: >>> Bei Ganzzahlen gibt es aber keinen Dezimalpunkt. Kann eventuell sein, >>> dass deine printf IMplementierung den . ignoriert. Richtig ist es IMHO >>> aber trotzdem nicht. >> >> Jetzt bist aber du auf dem Holzweg. Der Punkt hat auch bei den Inte- >> gerformaten eine Bedeutung. Welche, das verrät jedes bessere C-Buch ;-) > > Echt? > Muss ich gleich mal googeln. :-) > > (Danke für den Hinweis) Tatsache. Na da haben Rufus und ich uns schön blamiert.
1 | The precision |
2 | An optional precision, in the form of a period ('.') followed by an optional |
3 | decimal digit string. Instead of a decimal digit string one may write "*" or |
4 | "*m$" (for some decimal integer m) to specify that the precision is given in the |
5 | next argument, or in the m-th argument, respectively, which must be of type int. |
6 | If the precision is given as just '.', or the precision is negative, the preci‐ |
7 | sion is taken to be zero. This gives the minimum number of digits to appear for |
8 | d, i, o, u, x, and X conversions, the number of digits to appear after the radix |
9 | character for a, A, e, E, f, and F conversions, the maximum number of signifi‐ |
10 | cant digits for g and G conversions, or the maximum number of characters to be |
11 | printed from a string for s and S conversions. |
(vorgestern erst gebraucht, um mit sprintf)= bei *s nicht zuviel auszugeben und einen Pufferüberlauf zu riskieren)
Johann L. schrieb: > Noname schrieb: > >> Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es >> tun soll! > > Nein. Das ist einer der häufigsten Irrtümer: Ein Programm macht was es > tun soll und es wird als korrekt kategorisiert. Warum ist Nonames Aussage falsch? Wenn das Programm immer genau das tut, was man (oder genauer gesagt: die Spezifikation) von ihm erwartet, dann kann es nach meinem Dafürhalten als korrekt angesehen werden. Das Problem ist nur, dass dieses Kriterium nicht immer leicht nachzuprü- fen ist. In diesem Fall geht es aber gerade noch: 256 verschiedene Byte- werte kombiniert mit 8 verschiedenen Shiftweiten ergeben 2048 zu über- prüfende Fälle, was mit etwas Fleiß noch zu beherrschen sein sollte ;-)
Karl Heinz Buchegger schrieb: > Tatsache. Na da haben Rufus und ich uns schön blamiert. So schlimm ist das ja nicht. Bei mir war es bis vor ein paar Jahren genau anders herum: Ich kannte nur die "%.2x"-Notation, um Hexzahlen mit führenden Nullen aufzufüllen. Anfangs schrieb ich sogar immer "%2.2x", später optimierte ich dann die erste 2 weg, und irgendwann erfuhr ich, dass "%02x" das Gleiche tut. Seither nehme ich bevorzugt diese letzte Variante, außer wenn sich die Field-Width von der Precision unterscheidet, also bspw. in "%5.2x" oder "%*.2x", also wenn nur ein Teil der Feldbreite mit Nullen aufgefüllt werden soll.
Yalu X. schrieb: > Warum ist Nonames Aussage falsch? Wenn das Programm immer genau das tut, > was man (oder genauer gesagt: die Spezifikation) von ihm erwartet, dann > kann es nach meinem Dafürhalten als korrekt angesehen werden. Johann hat da schon recht. Wenn man genau auf die (seine) Worte achtet, so beschreibt er eine Implikation. (A => B) und in dieser kann man nunmal über A nichts aussagen, wenn man B (das Ergebnis) betrachtet (Umformung -AvB). Es ist sogar noch schlimmer: die Korrektheit eines Programmes lässt sich nichteinmal immer Beweisen. @Dominik M. lass dich hiervon nicht einschüchtern! Try and Error gehört oft zum Entwickeln dazu und ist nicht schlimm, solange man keine Sicherheitskritischen Anwendungen schreibt ;-)
Ich halte es für überflüssig hier Aussagenlogik zu verwenden um einen der Antworter (in diesem Fall mich) eines Irrtums zu üeberführen. Es ging ja darum, dass gesagt werden sollte, das der TO selbst feststellen kann, ob das was er geschrieben hat, ein korrektes Programm ist. Ich weiss nicht wo hier der Zweifel aufgekommen sein könnte es handele sich um etwas anderes als eine im umgangssprachlich Sinne übliche Form von Schlussfolgerung. Demzufolge halte ich es einfach nur für irrelevant auf einen solchen Satz in der Weise zu antworten wie Johann L. (gjlayde). Falls nicht, kann einfach jede Aussage aus einem Kontext genommen werden in einen anderen gestellt und je nach Wunsch als falsch oder richtig bewertet werden. Ich meine es ist allgemein anerkannt, das unter "Korrektheit" in Bezug auf ein Programm verstanden wird, dass es sich seiner Spezifikation entsprechend verhält. Das ist genau der Sinn meiner Aussage: > Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es > tun soll! Worin darin ein Irrtum liegen soll hat Johann nicht erklärt. Er hat es nur behauptet. Vielleicht erklärt Johann das ja mal, aber wenn nicht soll es mir auch egal sein. Letztlich heisst dieser Satz nur das "der Spezifikation entsprechen" und "korrekt sein" Synonyme sind. Mehr nicht. Wo kann darin ein Irrtum liegen, als eine Schlussfolerung im eigentlichen Sinne garnicht vorliegt? Dann schreibt Johann: >Das einzige, was sicher ist: >F: "Was ist das Zeichen, das ein Programm nicht korrekt ist?" >A: "Es macht nicht das, was es tun soll!" >Daraus die obige Aussage zu folgern ist aber nicht möglich. Ich habe in keiner Weise behauptet das meine Aussage das Ergebnis einer Schlussfolgerung sei. Ich lasse mich dann mal auf die Aussagenlogik ein. Sei meine Aussage gegeben mit A: Das Programm tut was es soll und B: Das Programm ist korrekt und als Schlussfolgerung (nicht als Synonymdefinition) aufgefasst, so lautet sie formal -A+B. Die Aussage, die ich beginnend mit "Das einzige, was sicher ist:" zitiert habe würde dann, wenn vorausgesetzt wird, das die Begriffe im gleichen Sinne gemeint sind, lauten: --A+-B oder kurz A+-B Jede Anfänger, der mal drei Stunden Aussagenlogik gehört hat, weiss, das nicht gilt -(A+-B) + (-A+B), es sei denn man postuliert das. Warum sollte ich so einen Quatsch behaupten wollen? Warum unterstellt Johann das? Mit welcher Berechtigung? Aufgrund welcher sonstigen Äusserung von mir? Aufgrund welchen anerkannten Lehrsatzes von irgendwem? Falls hier überhaupt eine relevante Diskussion über meine Aussage hätte stattfinden können, dann eine darüber, wie die Beschreibung des Verhaltens eines Programmes und des Programmes selbst in Beziehung stehen. Wenn ich also hier Johanns Bemerkung kritisch qualifiziert habe, dann sicher mit einiger Berechtigung; und zwar sowohl in Bezug auf den Inhalt als auch die Form.
Nochmals zum Nachlesen: Noname schrieb: > Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es > tun soll! > > Definiere was das Programm tun soll, prüfe das nach und Du weisst es. Zur Einstimmung zwei Beispiele aus dem Alltag eines Software-Entwicklers oder Hobby-Hackers, wie sie fast wöchentlich in diesem oder jenem Forum zu finden sind: • Eine Anwendung funktioniert seit Jahren "einwandfrei und ohne Probleme". Nachdem man ein neue Version der Entwicklungsumgebung eingespielt hat, geht plötzlich nichts mehr. Natürlich ist die neue Entwicklungsumgebung an allem Schuld. • Weil sich eine bestimmte Aufgabe nicht in Hochsprache ausdrücken lässt, kommt Inline-Assembler zur Anwendung. Die Syntax ist schnell nachgeschaut und die Aufgabe fix erledigt. Um gaaanz sicher zu sein, wird ein Review des erzeugten Assembler-/Maschinencodes durchgeführt. Anhand der erzeugten Instruktionen wird nachgewiesen, daß die Imple- mentierung "100% richtig und für alle möglichen Eingaben korrekt" ist. Drei Jahre später wird an der Firmware eine Erweiterung vorgenommen, die von anderen Applikationen als "stabil funktionierend" bekannt ist. Dennoch ist die neue Firmware instabil und zeigt "sporadisch seltsames und nicht nachvollziehbares" Verhalten. Zum Zutat von oben: Was ist ein "Programm"? Das, was man in einen Editor klöppelt oder in einer GUI zusammenclickt? Das, was schlussendlich auf der Hardware zur Ausführung kommt? Das "prüfe das nach" ist idR nicht möglich. Bereits für eine 64-Bit Zahl, bei der ein Bit zu setzen ist, braucht ein so geführter Nachweis auf einer Maschine, die pro Sekunde 1.000.000.000 Tests fahren kann, 35000 Jahre. Und selbst für den Fall von oben, daß in einem Byte ein per Variable übergebenes Bit zu setzen ist, lauern bereits Fußangeln: Nehmen wir an, daß gültige Werte für position von 0 bin 31 reichen und daß Positionen > 7 keinen Effekt haben sollen, da value nur über Bits 0...7 verfügt. Ein Durchnudeln aller 8192 möglichen und gültigen Eingaben ergibt, daß "das Progrmm korrekt ist". (Weil es, wie es den Anschein hat, auf einem PC zum Laufen kommt.) Wird das Programm aber auf einem kleineren System übersetzt, auf dem ein int nur 16 Bits groß ist, geht es plötzlich nicht mehr. Neben dem Programm und den Eingaben, sind also auch der Progamm(ier)- und Ausführungskontext mit in die Betrachtung einzubeziehen. Gerade dies geschieht idR jedoch nicht, denn der übliche Ablauf, um eine Software zu erweitern, ist, die Erweiterung — wenn überhaupt — in vitro zu testen bevor sie eingebaut wird. Eine solch klinisch reine Umgebung hat man in der Anwendung allerdings nicht mehr vorliegen, und in der Anwendung — und damit im realen Kontext — immer und immer wieder zu testen, wenn sich irgendwo in der Anwendung was geändert hat, ist schlicht unrealistisch. Sei es wegen des Aufwands, sei es, weil das Testen selbst bereits den Kontext verändert, oder sei es, weil in der Anwendung überhaupt keine Möglichkeit mehr für Tests nebst Einsammeln der Testergebnisse besteht. Man braucht also weitere Annahmen wie "Unabhängigkeit und Rückwirkungsfreiheit der Komponenten", die in der Praxis in den seltensten Fällen zu 100% gegeben ist weil sich Komponenten Resourcen teilen, miteinander kommunizieren, etc. Von einigen Testergebnissen auf die Korrektheit zu schliessen, halte ich für keinen guten Rat und es entspricht eher einem unbeholfenem Reverse-Engineering als solidem Handwerk. Für mich sind Tests kein Designwerkzeug, an denen man sich entlanghangeln sollte, um gute Software zu schreiben. Und in dem Feld, in dem ich mich momentan tummle (ein Text-Text-Transformator mit unendlich vielen gültigen Eingaben) ist es nicht einmal im Ansatz möglich, Trial+Error als Design-Pattern zu verwenden. Tests sind bestenfalls dazu geeignet, große Schatzer rauszufischen; mehr nicht. Und daß das alles kein theoretisches Blahfasel ist, zeigen die beiden Beispiele von oben.
Dann ist aber diese Aussage > Was ist das Zeichen, das ein Programm korrekt ist? Es macht, das was es > tun soll! für sich gesehen nicht falsch. Der Fehler liegt nach deinen Ausführungen (denen ich voll und ganz zustimme) darin, dass die Leute (Programmierer, Tester, Anwender) zu schnell und leichtfertig behaupten "Es macht das, was es tun soll", ohne dass für diese Behauptung eine ausreichende Grundlage besteht.
ist eben wie in der Physik man kann einen Theorie nicht mit (noch so vielen) Experimenten beweisen.. man kann aber mit einem einzigen Experiment beweisen dass die Theorie falsch ist.. in der Praxis sind Programme NIE fehlerfrei, weil das einfach nicht wirtschaftlich ist..
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.