5.2.20
03/29/20

Diff for AlgoDat_LU11 between 5 and 6

+ Algorithmen und Datenstrukturen 
++ Übung zum Kapitel "Kontrollstrukturen" 
** W. Tasin, M.Sc. **

 _
 
+++ Theoretische Fragen

* Folgendes Codefragment liest Zeichen von der Tastatur ein und gibt diese (sobald //**<Enter>**// gedrückt wurde) wieder aus. _
Dies wird so lange wiederholt bis die Eingabe mit //**Ctrl-D** (Linux/Mac)// bzw. //**Ctrl-Z** (Windows)// beendet wird. _
Alle eingegebenen Grossbuchstaben (ohne Umlaute) sollen vor der Ausgabe in Kleinbuchstaben umgewandelt werden. _
Ergänzen Sie das folgende Codefragment entsprechend.

<code type="c">int ch;
while ((ch=getchar())!=-1)
{
   if (ch>='A' && ch<='Z')
     ch=ch-'A'+'a';
  
   putchar(ch);
}
</code>

 _
 
* Folgendes Codefragment ermittelt die Länge eines Strings. Für welchen konstanten String arbeitet dieser Code **nicht** richtig? _
Wie kann dieses Problem gelöst werden?
<code type="c">const char *meldung="Dies ist ein Test!";
unsigned laenge=0;
do
{
  laenge++;
}
while (*(meldung+laenge)!='\0'); /* Vergleiche das Zeichen mit dem NUL-Character */
 
printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
 
Für den Leerstring:
<code type="c">const char *meldung="";
unsigned laenge=0;
do
{
  laenge++;
}
while (*(meldung+laenge)!='\0'); /* Vergleiche das Zeichen mit dem NUL-Character */
 
printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
liefert das Programm eine falsche Lösung, denn {{*(meldung+0)}} ist {{'\0'}}. 
Die Variable {{laenge}} besitzt bei der Überprüfung des Zeichens im String bereits den Wert {{1}}.

Somit zeigt {{meldung+1}} bereits auf eine Speicheradresse, die nicht mehr gültig ist.
Die Variable {{laenge}} wird so lange erhöht bis der Inhalt der Adresse {{meldung+laenge}} (zufällig) den Wert {{'\0'}} beinhaltet.
In gewissen Fällen kommt es auch zu einem Laufzeitfehler.

**Lösung des Problem:**
Verwendung einer abweisenden Schleife!
 

<code type="c">const char *meldung="Dies ist ein Test!";
unsigned laenge=0;
while (*(meldung+laenge)!='\0')    /* Vergleiche das Zeichen mit dem NUL-Character */
{
  laenge++;
}

printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
 
 

 
* Folgende Codefragmente sollen - falls sinnvoll und möglich - mithilfe des bedingte Auswerteoperators realisiert werden.

<code type="c">if ((wert % divisor) != 0)
  puts("Division geht nicht auf.");
else
  puts("Division geht auf.");

/* Mit bedingtem Auswerteoperator: */
puts((wert % divisor!=0) ? "Division geht nicht auf." : "Division geht auf.");

<code type="c">if (divisor == 0)
  puts("Division darf nicht ausgefuehrt werden!");
else
  printf("Ergebnis ist: %d\n", wert/divisor);

/* Verwendung des bed. Auswerteoperators hier nicht sinnvoll. */ 
</code>
 
<code type="c">if (zeichen != ' ')
  putchar(zeichen);

/* Verwendung des bed. Auswerteoperators hier nicht moeglich. */ 

 
<code type="c">if (zahl>=0)
  zahl%=10;


/* Anders dargestellt: */
if (zahl>=0)
  zahl= zahl % 10;
else
  zahl=-zahl % 10;

zahl= ((zahl>=10) ? zahl : -zahl) % 10;  /* Praezedenz beachten!! */

</code>
 
<code type="c">binaerWert=-1;
if (asciiWert>='0' && asciiWert<='9')
  binaerWert=asciiWert-'0';

/* Mit bedingtem Auswerteoperator: */
binaerWert= (asciiWert>='0' && asciiWert<='9') ? asciiWert-'0' : -1;

</code>
 
 _
 
 _
 
* Folgendes Codefragment ermittelt die Länge eines Strings. Für welchen konstanten String arbeitet dieser Code **nicht** richtig? _
Wie kann dieses Problem gelöst werden?
<code type="c">const char *meldung="Dies ist ein Test!";
unsigned laenge=0;
do
{
  laenge++;
}
while (*(meldung+laenge)!='\0'); /* Vergleiche das Zeichen mit dem NUL-Character */
 
printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
 
Für den Leerstring:
<code type="c">const char *meldung="";
unsigned laenge=0;
do
{
  laenge++;
}
while (*(meldung+laenge)!='\0'); /* Vergleiche das Zeichen mit dem NUL-Character */
 
printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
liefert das Programm eine falsche Lösung, denn {{*(meldung+0)}} ist {{'\0'}}. 
Die Variable {{laenge}} besitzt bei der Überprüfung des Zeichens im String bereits den Wert {{1}}.

Somit zeigt {{meldung+1}} bereits auf eine Speicheradresse, die nicht mehr gültig ist.
Die Variable {{laenge}} wird so lange erhöht bis der Inhalt der Adresse {{meldung+laenge}} (zufällig) den Wert {{'\0'}} beinhaltet.
In gewissen Fällen kommt es auch zu einem Laufzeitfehler.

**Lösung des Problem:**
Verwendung einer abweisenden Schleife!
 
 

<code type="c">const char *meldung="Dies ist ein Test!";
unsigned laenge=0;
while (*(meldung+laenge)!='\0')    /* Vergleiche das Zeichen mit dem NUL-Character */
{
  laenge++;
}

printf("String: \"%s\" hat die Laenge: %u\n", meldung, laenge);
</code>
 

----
++ Links
((AlgoDat_Uebungen|Uebungen Algorithmen und Datenstrukturen))
((AlgoDat_Unterlagen|Unterlagen Algorithmen und Datenstrukturen))
((AlgoDat_Praktikum|Praktikum Algorithmen und Datenstrukturen))
((Wiki/Home|Zur Hauptseite))