Forum: PC-Programmierung Programm zum Setzen von einzelnen Bits in C


von Da Mo (Gast)


Lesenswert?

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

von Noname (Gast)


Lesenswert?

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

von Da Mo (Gast)


Lesenswert?

Ich bin einfach noch extrem unsicher und deswegen wende ich mich an die 
Profis :-)

von Noname (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dominik M. schrieb:
> printf("Der neue Wert betraegt: 0x%.2X\n\n", new_value);

Merkwürdige Formatanweisung.

Warum nicht 0x%02X?

von Da Mo (Gast)


Lesenswert?

.2 = 02

Liege ich da falsch?

von Noname (Gast)


Lesenswert?

>.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. :-)

von Karl H. (kbuchegg)


Lesenswert?

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

von Yalu X. (yalu) (Moderator)


Lesenswert?

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 ;-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

(vorgestern erst gebraucht, um mit sprintf)= bei *s nicht zuviel 
auszugeben und einen Pufferüberlauf zu riskieren)

von Yalu X. (yalu) (Moderator)


Lesenswert?

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 ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Stryker (Gast)


Lesenswert?

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 ;-)

von Noname (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Robert L. (lrlr)


Lesenswert?

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
Noch kein Account? Hier anmelden.