kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Informatik -- Lehrveranstaltung vom 24.04.2024

(EN google-translate)

(PL google-translate)

Themen

  1. Arraytypen: int, double, char, char-Ketten
  2. Bestimmung der Größe von Arrays
  3. Übergabe von Arrays an Funktionen
  4. Beispiel Mittelwertbildung
  5. Beispiel Farbwörter merken und verwenden
  6. Java und C++
  7. Java / Processing: Widerstandwert aus Widerstandscode
  8. Java und Objektorientierte Programmierung
  9. Übungsaufgaben 5

1. Arraytypen: int, double, char, char-Ketten

2. Bestimmung der Größe von Arrays

3. Übergabe von Arrays an Funktionen

4. Beispiel Mittelwertbildung

5. Beispiel Farbwörter merken und verwenden

  • In Arrays können mehrere Werte eines Datentyps zusammengefasst werden.
  • Man kann sie mit einem mathematischen Vektor vergleichen, der ja auch mehrere Zahlen in geordneter Weise beinhaltet.
  • Es gibt auch mehrdimensionale Arrays. Ein zweidimensionales Array wäre mit einer mathematischen Matrix vergleichbar.
  • Kennzeichen eines Arrays sind die eckigen Klammern [].
  • Statt der eckigen Klammern kann auch der Stern * auftauchen. In diesem Fall ist die Speicheradresse gemeint, ab der das Array liegt.
  • Es existiert die Möglichkeit, die Größe eines Arrays mit Hilfe der Funktion sizeof(...) zu bestimmen.
  • Ein Text wird in C auch als Array behandelt, nämlich als Array vom Typ char.
  • Im Gegensatz dazu gibt es in C++ noch die Klasse string, die in dieser Lehrveranstaltung nicht behandelt wird.
  • Außerdem erlaubt C++ dass dynamische Allokieren von Speicher für ein Array. Auch diese Technik wird nicht Gegenstand dieser Lehrveranstaltung sein.

Beispiel orientierte Darstellung zum Umgang mit Arrays in C:

Arrays.zip -- alle nachfolgend aufgelisteten Beispiele zu Arrays in C.
#include <iostream>
using namespace std;
int main(void)
{
    int arr[3];
    arr[0]=7;
    arr[1]=6;
    arr[2]=5;
    cout<<"arr[0]="<<arr[0]<<endl;
    cout<<"arr[1]="<<arr[1]<<endl;
    cout<<"arr[2]="<<arr[2]<<endl;
    return 0;
}
array1.cpp -- Deklaration, Initialisierung und Verwendung eines Integer-Arrays.

#include <iostream>
using namespace std;
int main(void)
{
    int arr[] = {1,2,3};
    int anzahl = sizeof(arr)/sizeof(int);
    for(int i=0;i<anzahl;i++)
        cout<<"arr["<<i<<"]="<<arr[i]<<endl;
    return 0;
}

Code 0-1: array2.cpp -- Definition (keine Angabe der Größe in eckigen Klammern nötig), Verwendung von sizeof.

  • sizeof(arr) liefert die Anzahl von Bytes, die vom Array arr belegt werden.
  • sizeof(int) liefert die Anzahl von Bytes, die von einem einzelnen Integer-Wert im Speicher belegt werden.
  • sizeof(arr)/sizeof(int) liefert somit die Anzahl an Elementen, aus denen das Array arr besteht.
#include <iostream>
using namespace std;

double berechneMittelwert(double x[],int anz)
{
    double y = 0.0;
    for(int i=0;i<anz;i++)
        y+=x[i];
    y/=(double)anz;
    return y;
}

void showArray(double x[], int anz)
{
    cout<<"{";
    for(int i=0;i<anz;i++)
    {
        cout<<x[i];
        if(i<anz-1)
            cout<<",";
    }
    cout<<"}";
}

int main(void)
{
    double arr[] = {10.0,20.0,30.0,40.0};
    int anzahl = sizeof(arr)/sizeof(double);
    cout<<"arr[]=";
    showArray(arr,anzahl);     
    cout<<endl<<"Mittelwert="<<berechneMittelwert(arr,anzahl)<<endl;
    return 0;
}

Code 0-2: array3.cpp -- Verwendung von Funktionen und Arrays: Mittelwertbildung / Ausgabe eines Arrays.

#include <iostream>
#include <string.h>
using namespace std;
#define ANZAHLFARBEN 4
#define MAXZEICHEN 20
int main(void)
{
    char farbe[ANZAHLFARBEN][MAXZEICHEN] = {"schwarz","braun","rot","orange"}; 
    char wort[] = "Hallo";

    int anz = sizeof(wort);
    for(int i=0;i<anz;i++)
        cout<<"wort["<<i<<"]="<<wort[i]<<" (int)wort["<<i<<"]="<<(int)wort[i]<<endl;

    for(int i=0;i<ANZAHLFARBEN;i++)
    {
        for(int k=0;k<MAXZEICHEN;k++)
        {
            if(farbe[i][k]=='')
                break;
            cout<<farbe[i][k];
        }

        if(strcmp(farbe[i],"rot")==0)
            cout<<" ROT GEFUNDEN! ";

        cout<<"."<<endl;
      
    }

    return 0;
}

Code 0-3: array4.cpp

linux@Xubuntu2004:~/PLANUNG_YSOSE2024/INFORMATIK1/Arrays$ g++ -o array4 array4.cpp 
linux@Xubuntu2004:~/PLANUNG_YSOSE2024/INFORMATIK1/Arrays$ ./array4
wort[0]=H (int)wort[0]=72
wort[1]=a (int)wort[1]=97
wort[2]=l (int)wort[2]=108
wort[3]=l (int)wort[3]=108
wort[4]=o (int)wort[4]=111
wort[5]= (int)wort[5]=0
schwarz.
braun.
rot ROT GEFUNDEN! .
orange.
linux@Xubuntu2004:~/PLANUNG_YSOSE2024/INFORMATIK1/Arrays$ 

Code 0-4: Terminalausgabe zu array4.cpp

Anmerkungen zu array4.cpp:

  • Wörter sind Zeichenketten, die in einem (etwas größeren) Array aus char-Zeichen stehen und mit dem ASCII Zeichen Null enden.
  • Einzelne Character-Werte können aus einem Character-Array einzeln ausgelesen werden.
  • Das Ende des Wortes sieht man an der Null am Ende. Der Rest des Speicherplatzes bleibt dann ungenutzt.
  • Wenn ein Wort N Buchstaben hat, muss es in einem Array mit mindestens N+1 char-Werten gespeichert werden, damit die Null am Ende noch Platz hat.
  • Die Standard-Methode strcmp(..) liefert den Wert Null, wenn zwei ihr übergebene Zeichenketten gleich sind (hier das Wort rot).

6. Java und C++

36_Java
36_Java/01_GettingStarted

7. Java / Processing: Widerstandwert aus Widerstandscode

Screenshot zum Processing-Sketch

Bild 0-1: Screenshot zum Processing-Sketch "Widerstandswert"

int[][] farbe = {
  {0,0,0}, //0 schwarz
  {188,96,0}, //1 braun
  {255,0,0}, //2 rot
  {255,165,0}, //3 orange
  {255,255,0}, //4 gelb
  {0,255,0}, //5 grün
  {0,0,255}, //6 blau
  {238,130,238}, //7 violett
  {127,127,127}, //8 grau
  {255,255,255} //9 weiss
};  

public void setup()
{
    size(640,480);
    frameRate(30);
}
int INDEX=0;
int[] CODE = new int[3];
int WERT=0;
public void draw()
{
     background(255);
 
     float dx = width/(float)farbe.length;
     noStroke();
     for(int i=0;i<farbe.length;i++)
     {
         fill(farbe[i][0],farbe[i][1],farbe[i][2]);
         rect(dx*(float)i,0,dx,height/2);
     }
 
     textSize(30);
     textAlign(CENTER);
     if(INDEX==3)
     {
          fill(0);
          text(WERT+"Ohm",width/2,height/2+height/4);
          for(int i=0;i<CODE.length;i++)
          {
               fill(farbe[CODE[i]][0],farbe[CODE[i]][1],farbe[CODE[i]][2]);
               rect(i*(width/3),height-height/8,width/3,height/8);
          }
     }
     else
     {
          for(int i=0;i<INDEX;i++)
          {
               fill(farbe[CODE[i]][0],farbe[CODE[i]][1],farbe[CODE[i]][2]);
               rect(i*(width/3),height-height/8,width/3,height/8);
          }
     }
}

public void mouseClicked()
{
    if(INDEX>2)
       INDEX=0;
    float dx = width/(float)farbe.length;
    if(mouseY<height/2)
    {
         CODE[INDEX] = (int)(mouseX/dx);
    }
    if(INDEX==2)
    {
        WERT = (CODE[0]*10 + CODE[1]);
        for(int i=0;i<CODE[2];i++)
            WERT*=10;          
    }    
    INDEX++;
}

Code 0-5: Processing-Sketch "Widerstandswert".

8. Java und Objektorientierte Programmierung

  • Die in C/C++ eingeführten Sprachmittel sollen in diesem Kurs stark begrenzt bleiben.
  • So soll auch Objektorientierte Programmierung ausschließlich in Java eingeführt werden.
  • Insbesondere sind bereits Arrays in Java so genannte Objekte.
  • Objekte sind nicht-einfache Datentypen, die neben verschiedenen Eigenschaften ("Daten") auch Methoden ("Funktionen") enthalten können.
  • Daten und Methoden können bei einem Objekt durch den Punktoperator abgerufen werden.
  • So kann in Java bei jedem Array arr dessen Größe durch das Attribut length mit arr.length abgerufen werden.
9. Übungsaufgaben 5

Kleine Aufgaben zu Arrays und Schleifen in C

Aufgabe 5.1

Kompilieren und testen Sie folgenden Quelltext:

#include <iostream>
using namespace std;
int main(void)
{
    int x[10];

    for(int i=0;i<10;i++)
        cout<<x[i]<<endl;

    return 0;
}

Code 0-6: ue1.cpp

  • Ergänzen Sie eine Initialisierung des Arrays mit den Werten {1,2,3,4,5,6,7,8,9,10}.
  • Diese soll vor der Ausgabe stattfinden.
  • Kompilieren und testen Sie das modifizierte Programm.

Aufgabe 5.2

Kompilieren und testen Sie folgenden Quelltext:

#include <iostream>
using namespace std;
int main(void)
{
    double messwerte[]={1.0,2.4,3.8,4.0};
    double mittelwert = 0.0;
    for(int i=0;i<4;i++)
        mittelwert=mittelwert+messwerte[i];
    mittelwert=mittelwert/4.0;
    cout<<"mittelwert="<<mittelwert<<endl;
    return 0;
}

Code 0-7: ue2.cpp

  • Modifizieren Sie das Programm so, dass die Arraygröße mit sizeof(..) als Variable "anzahl" bestimmt.
  • Verwenden Sie überall, wo es Sinn macht "anzahl", anstatt explizit die Arraygröße hinzuschreiben.
  • Ersetzen Sie Strukturen der Form x=x+y durch x+=y, bzw. x=x/y durch x/=y.
  • Kompilieren und testen Sie das modifizierte Programm. Liefert es das gleiche Ergebnis, wie zuvor?

Aufgabe 5.3

  • Geheimsprachen, die durch das Ersetzen von Buchstaben funktionieren, lassen sich durch statistische Analyse entschlüsseln:
  • Bestimmte Buchstaben in einer Sprache treten mit einer bestimmten Häufigkeit auf.
  • Der Buchstabe e taucht im deutschen Texten am häufigsten auf.
  • Nachfolgendes Programm bestimmt die Anzahl des Buchstabens e, bzw. E in mehreren Sätzen.

Analysieren, kompilieren und testen Sie folgenden Quelltext:

#include <iostream>
using namespace std;

double bestimmeHaeufigkeitE(char satz[])
{
    int anzahlE=0;
    char c;
    int index=0;
    do
    {
        c=satz[index++];
        if(c=='e')
            anzahlE++;
        else if(c=='E')
            anzahlE++;
    } while(c!='');
    return anzahlE;
}

int main(void)
{
    char texte[][100] = {
        "Das ist ein Satz.",
        "Das ist ein weiterer Satz.",
        "Dieser Satz ist relativ lang."
    };
    int anzahlTexte = sizeof(texte)/sizeof(texte[0]);
    for(int i=0;i<anzahlTexte;i++)
        cout<<texte[i]<<" ... hat "<<bestimmeHaeufigkeitE(texte[i])<<" E(s)."<<endl;
    return 0;
}

Code 0-8: ue3.cpp

  • Beachten und versuchen Sie sich klar zu machen, wie anzahlTexte bestimmt wird.
  • Modifizieren Sie die Funktion so, dass nun die Anzahl von e bzw. E in Prozent zurück gegeben wird, wobei Leerzeichen unberücksichtigt bleiben sollen (ue3b.cpp).
  • Modifizieren Sie die Funktion so, dass nun weiter, dass auch die Häufigkeit beliebiger Zeichen in Prozent zurück gegeben wird, indem das jeweilige Zeichen mit übergeben wird. Jetzt aber enfällt die gleichzeitige Berücksichtigung von Gross- und Kleinschreibung (ue3c.cpp).
  • Gehen Sie schließlich erneut auf das ursprüngliche Programm zurück und modifizieren es so, dass nun nur vom Benutzer ein einzelner Satz zur Analyse eingegeben wird.
Musterlösung zu Aufgabe 5.3:
#include <iostream>
using namespace std;

double bestimmeHaeufigkeitEinProzent(char satz[])
{
    int anzahlE=0;
    char c;
    int index=0;
    int anzahlLeerzeichen=0;
    do
    {
        c=satz[index++];
        if(c==' ')
            anzahlLeerzeichen++;
        if(c=='e')
            anzahlE++;
        else if(c=='E')
            anzahlE++;
    } while(c!=0);
//cout<<"Index hat den Wert: "<<index<<endl; //TESTAUSGABE
    double prozent = 100.0*(double)anzahlE/(double)(index-1-anzahlLeerzeichen);
    return prozent;
}

int main(void)
{
    char texte[][100] = {
        "Das ist ein Satz.",
        "Das ist ein weiterer Satz.",
        "Dieser Satz ist relativ lang."
    };
    int anzahlTexte = sizeof(texte)/sizeof(texte[0]);
    for(int i=0;i<anzahlTexte;i++)
    {
        double p = bestimmeHaeufigkeitEinProzent(texte[i]);
        cout<<texte[i]<<" ... hat anteilig "<<p<<"% E(s)."<<endl;
    }
    return 0;
}

Code 0-9: Musterlösung zu Aufgabe 5.3.

Musterlösung zu Aufgabe 5.3b -- Programm, das nach verschiedenen Buchstaben suchen kann.
#include <iostream>
using namespace std;

double bestimmeHaeufigkeit(char satz[], char suchbuchstabe)
{
    int anzahl=0;
    char c;
    int index=0;
    do
    {
        c=satz[index++];
        if(c==suchbuchstabe)
            anzahl++;
    } while(c!=0);
    return anzahl;
}

int main(void)
{
    char texte[][100] = {
        "Das ist ein Satz.",
        "Das ist ein weiterer Satz.",
        "Dieser Satz ist relativ lang."
    };
    int anzahlTexte = sizeof(texte)/sizeof(texte[0]);
    for(int i=0;i<anzahlTexte;i++)
    {
        cout<<texte[i]<<" ... hat "<<bestimmeHaeufigkeit(texte[i],'e')<<" e(s)."<<endl;
        cout<<texte[i]<<" ... hat "<<bestimmeHaeufigkeit(texte[i],'i')<<" i(s)."<<endl;
    }
    return 0;
}

Code 0-10: Musterlösung zu Aufgabe 5.3b -- Programm, das nach verschiedenen Buchstaben suchen kann.

Aufgabe 5.4

  • Schreiben Sie in C/C++ ein Programm, das aus dem mit "cin" eingegebenen Widerstandsfarbcode dessen Wert in Ohm ausgibt.
  • Dazu sollen die drei Farben als Wörter in cin nacheinander eingegeben werden, beispielsweise gelb lila orange.
  • Dem Benutzer sollte darauf, insbesondere auf die zu verwendende Schreibweise bei den Wörtern nach Start des Programms ein Hinweis gegeben werden.
  • Um zu einer Umsetzungsidee zu gelangen, soll der in der Lehrveranstaltung besprochene Processing-Sketch "Widerstandswert" (vergl. weiter oben) analysiert werden.
#include <iostream>
using namespace std;
int main(void)
{
   int a=0;
   int b=0;
   int c=0;
   int d=0;

   cout<<"der erste Ring: braun=1; rot=2; orange=3; gelb=4; grün=5; blau=6; violett=7; grau=8; weiß=9"<<endl;
   cin>>a;
   cout<<"der 2. Ring: schwarz=0; braun=1; rot=2; orange=3; gelb=4; grün=5; blau=6; violett=7; grau=8; weiß=9"<<endl;
   cin>>b;
   cout<<"der 3. Ring: schwarz= *1; braun= *10; rot= *100; orange= *1000; gelb= *10000; grün= *100000; blau= *1000000; violett"<<endl;
   cin>>c;

   d=a*10 + b;

   int potenz = 1;
   for(int i=0;i<c;i++)
      potenz*=10;
   d = d*potenz;
   cout<<"der Widerstand ist: "<<d<<endl;

   return 0;
}

Code 0-11: Vorläufige Lösung mit der Eingabe der Farben als Code.

Aufgabe 5.5

  • Es kann dem Benutzer/der Benutzerin passieren, dass dieser Eingabefehler macht.
  • Erweitern Sie Ihr bisheriges Programm von 5.4 so, dass diese Eingabefehler erkannt werden und ggf. der Benutzer zur Wiederholung seiner Eingabe aufgefordert wird.
  • Zeichnen Sie ein Flussdiagramm von dem nun vollständigen Programm.

Aufgabe 5.6: Einführende Übung zu Processing

public void setup()
{
     size(200,100);
     frameRate(60);
}

int x=0;

public void draw()
{
     background(0,0,255);
     fill(255,0,0);
     noStroke();
     ellipse(x,height/2,50,50);
     x++;
     x%=(int)width;
}

Code 0-12: Processing Sketch ue6

  • Bringen Sie oben stehenden Processing-Sketch zum Laufen.
  • Schlagen Sie die verwendeten Grafikbefehle und Schlüsselwörter width,height,size,frameRate,background,fill,noStroke,ellipse bei https://processing.org/reference nach.
  • Ändern Sie das Programm so, dass der wandernde Ball nicht zurück springt, sondern an den "Wänden abprallt", also an den Rändern immer die Richtung ändert.