Hallo zusammen,
Wir sitzen hier mit vier Mann zusammen und versuchen ein Programm zu
erstellen, da wir C erlernen wollen. Leider fehlt uns im Moment der
Ansatz. Könntet ihr uns helfen, wie man die folgende Aufgabe lösen kann?
Schreiben Sie ein Programm, das acht einzelne Lampen an- und ausschalten
kann und das den Status aller Lampen in einem einzigen Byte (8 Bit,
C-Typ char) hält. Dabei steht jedes der acht Bit für den Status der
jeweiligen Lampe, d.h. 0 steht für „Lampe an“, 1 steht für „Lampe aus“.
Der Benutzer muss über Eingaben die einzelnen Lampen an- und ausschalten
können. Die Benutzereingabe 7X muss Lampe 7 anschalten, die Eingabe 4-
muss die Lampe 4 ausschalten.
Hinweis: Die Bitoperationen & und | sind hier hilfreich.
Der Benutzerdialog muss wie folgt aussehen:
1
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
2
| - | - | - | - | - | - | - | - |
3
> 4X
4
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
5
| - | - | - | X | - | - | - | - |
Man könnte doch zunächst mit
unsigned char status=8 beginnen. So hat man zumindest schon mal ein
char, das genau ein Bit groß ist. aber wie gehe ich dann dann weiter
vor?
Wir arbeiten mit Eclipse auf einem Windos 7 OS und GCC compiler.
Schnubbi schrieb:> kann und das den Status aller Lampen in einem einzigen Byte (8 Bit,> C-Typ char) hält.
unsigned char.
Wenn von Bytes die Rede ist, dann ist unsigned char der Datentyp der
Wahl. Gewöhn dir an, den Datentyp char ausschliesslich für
Textverarbeitung zu benutzen.
> unsigned char status=8 beginnen. So hat man zumindest schon mal ein> char, das genau ein Bit groß ist.
Nö.
Ein unsigned char ist sowieso 1 Byte groß. (ok, ist nicht garantiert,
aber ich wills jetzt nicht noch zusätzlich verkomplizieren). Und 1 Byte
hat definitionsgemäß 8 Bit. Ob du da jetzt einen Wert vorgibst, der in
'Status' gespeichert wird oder nicht.
> aber wie gehe ich dann dann weiter> vor?
Indem du dir klar machst, wie man in einem Byte (einem unsigned char)
gezielt
* 1 Bit setzt
* 1 Bit löscht
* abfragt, ob 1 Bit auf 1 ist oder nicht
Und zwar unter Vorgabe der gewünschten Bitnummer.
Eure Gedanken kreisen momentan um das falsche Thema. Mit
1
intmain()
2
{
3
unsignedcharStatus=0;
4
...
hast du bereits die Speicherfläche für 8 Bit. Die Zuweisung von 0 sorgt
einfach nur dafür, dass an dieser Stelle alle 8 Bits gezielt auf 0 sind.
Du musst sie nur noch gezielt einzelne Bits auf 1 bzw. auf 0 setzen,
bzw. entsprechend abfragen.
> aber wie gehe ich dann dann weiter vor?
Es hat sich gezeigt, dass es sinnvoll ist, zunächst mal mit der Ausgabe
zu beginnen.
In eurem Fall also mit einer Funktion, die das hier
1
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
2
| - | - | - | - | - | - | - | - |
hinmalt, wenn 'Status' den Wert 0 hat, die das hier
1
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
2
| X | - | - | - | - | - | - | - |
hinmalt, wenn Status den Wert 1 hat (denn 1 ist binär ja 00000001, und
da ist dieses eine Bit auf 1), bzw. die zb das hier hinmalt
1
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
2
| X | - | X | - | - | - | - | - |
wenn Status den Wert 5 hat (denn 5 ist binär ja 00000101)
Dazu braucht ihr noch keine Eingabe und auch keine Bit setzen oder
löschen. Sondern einfach nur
1
...
2
intmain()
3
{
4
Status=5;
5
6
....euerCodehier
7
}
und dann muss das Programm diese Ausgabe
1
| L1 | L2 | L3 | L4 | L5 | L6 | L7 | L8 |
2
| X | - | X | - | - | - | - | - |
produzieren.
Durch Verändern von Status direkt im Code und neucompilieren, könnt ihr
erst mal testen, ob dieser Ausgabecode korrekt ist.
Damit würde ich anfangen, wenn ich ihr wäre.
Das grundlegende Prinzip lautet: Teile und herrsche.
Teile die Aufgabe in Teilbereiche auf und barbeite diese Teilbereiche in
einer Reihenfolge, so dass du sie testen kannst und spätere
implementierte Teilbereiche auf der vorhergehenden Arbeit aufbauen.
Man kann natürlich mit der Eingabe und dem Setzen von Bits anfangen.
Kann man. Aber wie testest du das? Um zu testen ob das alles korrekt
ist, braucht es eine Möglichkeit für die Ausgabe. Eine funktionierende
Ausgabe ist daher so etwas eine Voraussetzung, um die Bereiche Bits
setzen bzw. löschen auch verifizieren zu können. Also fängt man erst mal
damit an. Es zeigt sich im allgemeinen, dass diese Strategie, erst mal
die Ausgabe zu machen, in vielen Fällen eine gute Wahl ist. Dann kann
man für andere Dinge einfach mal etwas annehmen (wie zb hier den Wert
und damit die Bitbelegung in Status) und so die Ausgabefunktionalität
durchtesten. Eine funktionierende und gesichert korrekte Ausgabe ist
dann in weiterer Folge viel wert, weil die Unsicherheit, wo jetzt der
Fehler im Progamm sitzt, in der Verarbeitung oder in der Ausgabe, schon
mal wegfällt. Ist die Ausgabe ausreichend getestet, dann sitzt ein
auftauchender Fehler meist in der Verarbeitung bzw. Eingabe.
Erstmal danke für die Antworten. Hat uns schonmal um einiges
weitergeholfen. Eine Frage habe ich aber noch:
Wenn wir zunächst den Char "Lampen" mit
1
unsignedcharlampen=255;
angeben, sollte es sich doch um Byte handeln und nur die Stellen der
einzelnen Bits. Sprich die 255 ergeben sich aus 128,64,32,16,8,4,2,1 der
einzelnen Bits die addiert werden oder?
Danke schonmal.
Schnubbi schrieb:> angeben, sollte es sich doch um Byte handeln und nur die Stellen der> einzelnen Bits. Sprich die 255 ergeben sich aus 128,64,32,16,8,4,2,1 der> einzelnen Bits die addiert werden oder?
Ja.
es ist ein Stellenwert System, so wie du es auch in den dir vertrauten
Dezimalzahlen kennst.
| | | +----------------- Wertigkeit 16, oder 2 hoch 4
12
| | +--------------------- Wertigkeit 32, oder 2 hoch 5
13
| +------------------------- Wertigkeit 64, oder 2 hoch 6
14
+----------------------------- Wertigkeit 128, oder 2 hoch 7
Das ist alles wie in den Dezimalzahlen, wie du die kennst. Nur dass wir
10 unterschiedliche Ziffern haben und nicht nur 2, und dass die
Wertigkeit einer Stelle '10 hoch x' ist und nicht '2 hoch x'.
Die Dezimalzahl 5289 setzt sich zusammen aus
1
5289
2
+--- 9 * 10 hoch 0 = 9
3
+---- 8 * 10 hoch 1 = 80
4
+----- 2 * 10 hoch 2 = 200
5
+------ 5 * 10 hoch 3 = 5000
6
-----
7
5289
nichts anders ist es bei Binärzahlen
die Binärzahl 01101100 setzt sich zusammen aus
1
01100100
2
+-- 0 * 2 hoch 0 = 0
3
+--- 0 * 2 hoch 1 = 0
4
+---- 1 * 2 hoch 2 = 4
5
+----- 1 * 2 hoch 3 = 8
6
+------ 0 * 2 hoch 4 = 0
7
+------- 1 * 2 hoch 5 = 32
8
+-------- 1 * 2 hoch 6 = 64
9
+--------- 0 * 2 hoch 7 = 0
10
-----
11
108
die Binärzahl 01101100 entspricht also der Dezimalzahl 108
Das mal ausprobieren und dabei mit dem Debugger vertraut machen!
> Wir arbeiten mit Eclipse auf einem Windos 7 OS und GCC compiler.
Schnappt euch die Express Version vom MS Visual Studio (ist frei), es
gibt keinen besseren Debugger unter Windows :-)
Random ... schrieb:> es> gibt keinen besseren Debugger unter Windows :-)
Da muss ich zustimmen. Das habe ich auch schon oft von Kollegen gehört,
die sonst eher der Linux-Fraktion angehören. Wer unter Windows arbeitet,
fährt mit Visual Studio (2010 oder 2012) am besten.
Auch wenn der Beitrag etwas älter ist, hat jemand die Lösung dazu?
Möchte gerne die C-Sprache lernen und wollte diese Aufgabe mal testen.
Habe nur keine Ahnung wie... :( Bzw. wie man anfangen soll, da mein
Problem gerade die logische Umsetzung ist.
lg Struddel
Die logische Umsetzung hat Karl Heinz in epischer Breite erklärt. Wie
wäre es, wenn Du einfach nochmal den Thread genau und gründlich
durchlesen würdest?
Die Aufgabe ist so einfach, daß das ein Programmieranfänger ohne weitere
fremde Hilfe lösen können muss, erst recht mit dem, was Karl Heinz
geschrieben hat, im Gepäck.
Lesen! Verstehen!
(Und dann, aber wirklich erst dann, Fragen stellen. Konkrete Fragen.
Fragen, die erkennen lassen, daß Du auch wirklich was gelesen hast)
Äh? Wie war das im Mittelteil?
(Otto (Kevin Kline) in: "Ein Fisch namens Wanda")
P.S.
Kann gelöscht werden. Ist mir nur durch den Kopf geschossen.
P.P.S
Ach Karl-Heinz. Waren das noch Zeiten!
Ich habe es so weit geschafft:
#include <stdio.h>
#include <stdlib.h>
#define Max 255
int Lampe[2][8] = {1,2,3,4,5,6,7,8};
int main()
{
int i, j;
//Schleife fuer Zeilen, Y-Achse
for (i=0; i<2; i++)
{
//Schleife fuer Spalten, X-Achse
for (j=0; j<8; j++)
{
printf("|%d", Lampe[i][j]);
}
printf("|\n");
}
}
nur leider spuckt er mir das aus:
|1|2|3|4|5|6|7|8|
|0|0|0|0|0|0|0|0|
und hier, trotz mehrfachem Lesen, komme ich nicht weiter. Wenn man es
kann, dann kommt einem immer alles leicht vor. Nur leider habe ich
gerade einen Denkfehler, den ich nicht rausbekomme.
Struddel schrieb:> int Lampe[2][8] = {1,2,3,4,5,6,7,8};
Was soll deiner Meinung nach in der zweiten Zeile stehen?
Was hat das mit "Bitoperationen" zu tun?
(Ersetze doch mal das 2dimensionale Feld durch eine einfache 8 Bit
Variable)
Das Hauptproblem wird wohl die falsch platzierte schließende Klammer der
zweiten for-Schleife sein. Die anderen "Feinheiten" musst du dann selber
rausfinden können!
(setz aber mal status am Anfang auf 170, (0xAA, 0b1010101010) damit man
gleich was sieht)
Erstmal vernünftig einrücken. Dann schau dir mal an, was du so in deiner
Schleife tust. Geh den Inhalt der Schleife mal Schritt für Schritt
durch. Was passiert alles vor der schließenden Klammer der Schleife?