Übungspaket 1 Der Datentyp char Übungsziele: Skript: 1. Umgang mit dem Datentyp char,. Deklarationen von char-variablen, 3. char-konstanten 4. und char-rechenoperationen. Kapitel: 9 bis 31 sowie 4, 5 und 7 Semester: Wintersemester 018/19 Betreuer: Thomas, Tim und Ralf Synopsis: In diesem Übungspaket gibt es einiges zum Thema Zeichen. Die Struktur der Aufgaben ähnelt sehr den vorherigen. Neben der eigentlichen Zeichenverarbeitung ist die Umwandlung von Werten des Datentyps char in Werte des Datentyps int und umgekehrt Teil dieses Übungspaketes.
Teil I: Stoffwiederholung Aufgabe 1: Notation von Zeichenkonstanten In Vorlesung und Skript haben wir gesehen, dass in der Programmiersprache C Zeichen in drei verschiedenen Formen angeben können. Vervollständige folgende Tabelle: C-Notation Zeichen Zeichen Escape/Oktal Ganzzahl Hexadezimal Großbuchstabe A A \101 65 0x41 Semikolon ; \73, \073 59 0x3B Ziffer 3 3 \63, \063 51 0x33 Nullbyte \0, \00, \000 0 0x0 Aufgabe : Ein- und Ausgabe Erläuter anhand von zwei Beispielen, wie Zeichen ein und ausgelesen werden können? Format: %c, %nc Eingabe: scanf( "%c", & c ) Ausgabe: printf( "%3c", c ) Aufgabe 3: Zeichen und deren ASCII-Werte Schreibe ein kleines Testprogramm, das die Zeichen A bis Z nebst ihrer zugehörigen ASCII Werte in tabellarischer Form ausgibt. Frage: Muss man bei der Aufgabe die konkrete ASCII-Kodierung der einzelnen Zeichen selber in der ASCII-Tabelle nachschlagen oder kann das der Compiler dies erledigen? nein, der Compiler kann es: Zeichen 5 char c; 6 printf ( " Zeichen Dezimalwert \n" ); 7 for ( c = A ; c <= Z ; c = c + 1 ) 8 printf ( "%7c %d\n", c, c ); 9 } 1-1 Wintersemester 018/19, Einführung in die Praktische Informatik
Teil II: Quiz Aufgabe 1: Datentyp char vs. Datentyp int Der Datentyp char gehört zu den Ganzzahldatentypen, da die einzelnen Zeichen einzeln aufgeführt werden können. Aber dennoch gibt es einige Unterschiede zum Datentyp int. Diese Unterschiede betreffen in erster Linie die Zahl der verwendeten Bytes im Arbeitsspeicher und damit die Zahl der verfügbaren Bits und dem daraus resultierenden Wertebereich. Ergänze folgende Tabelle: Datentyp # der Bytes # der Bits Wertebereich int 4 3-147 483 648 bis 147 483 647 char 1 8-18 bis 17 bzw. 0 bis 55 Aufgabe : Ausdrücke Welche Werte erhalten die Variablen char c und int i durch die angegebenen Ausdrücke? Ausdruck c = a + 1 c = m - 1 c = a + 4 c = m - a + A Resultat c = b c = l c = e c = M Ausdruck Resultat c = n - z + Z c = N c = P - A + a + 1 c = q i = z - a i = 5 i = 9-0 i = 9 Aufgabe 3: Datentypen Im Zusammenhang mit Variablen und Werten vom Typ char gibt es immer wieder Fragen bezüglich des resultierenden Datentyps. In den folgenden Ausdrücken gilt folgende Variablendefinition: char c und int i Ausdruck Datentyp c char a int \101 int Ausdruck c + 1 c - 0 c + i Datentyp int int int Hinweis: Die Anweisung printf("%d\n", Ausdruck) gibt einen Hinweis auf den resultierenden Typ. Ausdruck kann eine Variable, ein Ausdruck oder ein Typ sein. Einführung in die Praktische Informatik, Wintersemester 018/19 1-
Teil III: Fehlersuche Aufgabe 1: Summenberechnung mit kleinen Fehlern Das folgende Programm soll die Summe der Zeichen a bis z, A bis Z und 0 bis 9 bestimmen. Leider sind dem Programmierer wieder einmal ein paar kleine Fehler unterlaufen. Finde die 14 Fehler und korrigiere sie: 1 # include stdio.h 5 char c, 6 int s. 7 for ( s = a, c = b ; c < z ; c = c + 1 ) 8 s = c; 9 for ( c = A ; c >= Z"; c = + 1 ) 10 s = s + c; 11 for ( c "9 ; c > 0, c = c + 1 ) 1 s = s + c; 13 printf ( " summe = %d\n, s ); 14 ] Zeile Fehler Erläuterung Korrektur 1... statt <...> Die standard.h-dateien müssen in <...> angegeben werden. <stdio.h> 5/6,/. statt ; Alle Anweisungen müssen mit einem Semikolon abgeschlossen werden. char c; int x; 7 < statt <= Gemäß Aufgabentellung muss auch das z mit zur Summe gezählt werden. Daher muss dort der <= Operator stehen. c <= z 8 s + fehlt Es fehlt die Summenbildung. s = s + c 9 c fehlt So wird c nicht weitergeschaltet. c = c + 1 11 Die for- Schleife ist mehrfach fehlerhaft Entweder soll innerhalb der for-schleife aufwärts oder abwärts gezählt werden. Für keine dieser beiden Möglichkeiten passen die Angaben zusammen. Wir entscheiden uns fürs Abwärtszählen. for( c = 9 ; c >= 0 ; c = c - 1 ) 13 statt " Die Ausgabeanweiung benötigt die Textausgaben in Gänsefüßchen "..." eingeschlossen werden. "su... " 1-3 Wintersemester 018/19, Einführung in die Praktische Informatik
Programm mit Korrekturen: 5 char c; 6 int s; 7 for ( s = a, c = b ; c <= z ; c = c + 1 ) 8 s = s + c; 9 for ( c = A ; c <= Z ; c = c + 1 ) 10 s = s + c; 11 for ( c = 9 ; c >= 0 ; c = c - 1 ) 1 s = s + c; 13 printf ( " summe = %d\n", s ); 14 } Einführung in die Praktische Informatik, Wintersemester 018/19 1-4
Teil IV: Anwendungen Aufgabe 1: Umwandlung von Ziffern in Zahlen Ein echter Klassiker: Schreibe ein kleines Programm, das eine einzelne Ziffer, also die Zeichen von 0 bis 9, in ihren entsprechenden Zahlenwerte, also ints von 0 bis 9, umwandelt. Das folgende Programmschnipsel zeigt, wie ihr es nicht machen sollt... 5 char zeichen ; 6 int zahl ; 7 zeichen = 5 ; 8 switch ( zeichen ) 9 { 10 case 0 : zahl = 0; break ; 11 case 1 : zahl = 1; break ; 1 case : zahl = ; break ; 13 case 3 : zahl = 3; break ; 14 case 4 : zahl = 4; break ; 15 case 5 : zahl = 5; break ; 16 case 6 : zahl = 6; break ; 17 case 7 : zahl = 7; break ; 18 case 8 : zahl = 8; break ; 19 case 9 : zahl = 9; break ; 0 } 1 printf ( " Zeichen = %c Zahl = %d\n", zeichen, zahl ); } Eine derartige Umwandlung geht mit einer einfachen Anweisung. Überlege zunächst, in welchem Zusammenhang die ASCII-Zeichen und deren Kodierung zueinander stehen. Formuliere und erkläre die entsprechende C-Anweisung, und schreibe ein entsprechendes Testprogramm: Alle Ziffern sind in der ASCII-Tabelle nacheinander angeordnet, sodass sich die Werte benachbarter Ziffern um eins unterscheiden. Beispielsweise ist der (ASCII-) Wert der Ziffer 7 um genau eins größer als der (ASCII-) Wert der Ziffer 6. Den Wert einer beliebigen Ziffer bekommt man, in dem man vom ASCII-Wert den Wert des Zeichens 0 subtrahiert. Daher kann man einfach formulieren: int value = ascii char - 0 ; 1-5 Wintersemester 018/19, Einführung in die Praktische Informatik
Testprogramm zur einfachen Wandlung von Ziffern in Zahlenwerte: 5 char c; 6 int value ; 7 printf ( " Zeichen Dezimalwert \n" ); 8 for ( c = 0 ; c <= 9 ; c = c + 1 ) 9 { 10 value = c - 0 ; 11 printf ( "%7c %d\n", c, value ); 1 } 13 } Aufgabe : Klassifizierung von Zeichen: <ctype.h> Die Include-Datei <ctype.h> stellt eine Reihe von nützlichen Makros zur Klassifizierung von Zeichen zur Verfügung. Nenne mindestens sechs von ihnen: Bedeutung Buchstaben Kleinbuchstaben Großbuchstaben Makroname isalpha() islower() isupper() Bedeutung Makroname Ziffern isdigit() Hex-Ziffern isxdigit() Leerzeichen isspace() Aufgabe 3: Wandeln von hexadezimalen Ziffern 1. Aufgabenstellung Erweiter das Programm aus Aufgabe 1 dieses Teils so, dass es auch hexadezimale Ziffern, A bis F bzw. a bis f korrekt wandelt.. Pflichtenheft Aufgabe : Umwandlung hexadezimaler Ziffern in die entsprechenden Zahlenwerte Eingabe : eine hexadezimale Ziffer Ausgabe : eingegebene Ziffer und ihr Zahlenwert Sonderfälle : Fehlermeldung bei Eingabe nicht-hexadezimaler Zeichen Einführung in die Praktische Informatik, Wintersemester 018/19 1-6
3. Testdaten Alle Ziffern von 0 bis 9, A bis F und a bis f 4. Implementierung Das Wesentliche haben wir ja schon in der vorherigen Übungsaufgabe gehabt. Jetzt müssen wir nur überprüfen, ob wir eine Ziffer 0-9, einen Kleinbuchstaben a - f oder einen Großbuchstaben A - F vorliegen haben. Je nach dem ändert sich die Umwandlung geringfügig. Im Kern sieht die Änderung also wie folgt aus: Umwandlung von hexadezimalen Ziffern in Zahlenwerte Variablen: Integer: zahl Char: zeichen wenn ziffer 0 und ziffer 9 dann zahl = ziffer - 0 sonst wenn ziffer a und ziffer f dann zahl = ziffer - a + 10 sonst wenn ziffer A und ziffer F dann zahl = ziffer - A + 10 sonst Ausgabe einer Fehlermeldung 5. Kodierung 5 char c; 6 int val, error = 0; 7 scanf ( "%c", & c ); 8 if (c >= 0 && c <= 9 ) 9 val = c - 0 ; 10 else if (c >= a && c <= f ) 11 val = c - a + 10; 1 else if (c >= A && c <= F ) 13 val = c - A + 10; 14 else error = 1; 15 if ( error ) 16 printf (" %c ist kein hex - zeichen \n",c); 17 else printf ( "%c hat den wert %d\n", c, val ); 18 } 1-7 Wintersemester 018/19, Einführung in die Praktische Informatik
Aufgabe 4: Umwandlung von Klein in Großbuchstaben 1. Aufgabenstellung Enwickle ein Programmstückchen, das Kleinbuchstaben in Großbuchstaben umwandeln kann und umgekehrt. Auch diese Umwandlung geht wieder in einer Zeile.. Pflichtenheft Aufgabe : Umwandlung von Klein- in Großbuchstaben und umgekehrt Eingabe : keine; die entwickelten Anweisungen werden direkt in Schleifen aufgerufen Ausgabe : Paare von Klein- und Großbuchstaben in Tabellenform Sonderfälle : keine 3. Testdaten Alle Buchstaben von a bis z und A bis Z. 4. Implementierung Da diese Aufgabe eigentlich keine größeren Schwierigkeiten bereiten sollte, konzentrieren wir uns hier auf die eigentliche Umwandlung der Zeichen. Wie lautet die jeweiligen Anweisungen zum Umwandeln der Buchstaben? Klein- in Großbuchstaben: Groß- in Kleinbuchstaben: upper = lower - a + A lower = upper - A + a 5. Kodierung Schreibe ein entsprechendes Testprogramm für die beiden obigen Anweisungen: 5 char c; 6 printf ( " klein gross \n" ); 7 for ( c = a ; c <= z ; c = c + 1 ) 8 printf ( "%5c %c\n", c, c - a + A ); 9 printf ( "\ ngross klein \n" ); 10 for ( c = A ; c <= Z ; c = c + 1 ) 11 printf ( "%5c %c\n", c, c - A + a ); 1 } Einführung in die Praktische Informatik, Wintersemester 018/19 1-8
Aufgabe 5: Zeichen-Matrix 1. Aufgabenstellung Zur Wiederholung: Eine Variable vom Typ char besitzt in der Regel acht Bits, womit sich 56 verschiedene Werte darstellen lassen. Entwickle ein Programm, das diese 56 Möglichkeiten in Form einer 16 16 Matrix darstellt, und zwar nicht als Zahlenwerte sondern als Zeichen. Da einige Zeichen merkwürdig aussehen, ist es günstig " %c" als Formatierung zu nehmen. Mit etwas Glück wird folgende Matrix ausgegeben. Gewünschte Ausgabe:. Pflichtenheft Aufgabe : Darstellung aller 56 Zeichen in Form einer 16 16 Matrix Eingabe : keine, die Tabelle wird direkt ausgegeben Ausgabe : Ausgabe der Tabelle Sonderfälle : keine 3. Implementierung Ausgabe aller 56 Zeichen als Matrix setze zeichen = 0 für i = 0 bis 16 schrittweite 1 wiederhole für j = 0 bis 16 schrittweite 1 wiederhole setze zeichen = zeichen + 1 Ausgabe zeichen Ausgabe Zeilenumbruch 1-9 Wintersemester 018/19, Einführung in die Praktische Informatik
4. Kodierung 5 int i, j, c; 6 for ( c = i = 0; i < 16; i ++ ) 7 { 8 for ( j = 0; j < 16; j ++, c ++ ) 9 printf ( " %c", c ); 10 printf ( " \n" ); 11 } 1 } 5. Alternative-I: Berechnung des auzugebenen Zeichens in Zeile 9: 5 int i, j; 6 for ( i = 0; i < 16; i ++ ) 7 { 8 for ( j = 0; j < 16; j ++ ) 9 printf ( " %c", i * 16 + j ); 10 printf ( " \n" ); 11 } 1 } 6. Alternative-II: Test auf die notwendigen Zeilenumbrüchen in den Zeilen 9 und 10: 5 int c; 6 for ( c = 0; c < 56; c ++ ) 7 { 8 printf ( " %c", c ); 9 if ( c % 16 == 15 ) 10 printf ( " \n" ); 11 } 1 } Einführung in die Praktische Informatik, Wintersemester 018/19 1-10