(3) textzeichentyp feld des typs char - tu dresdennoack/lehrerinf/vorles32_inf_st.pdf · sinnvoll...

18
(3) Textzeichentyp char reserviert (i.a.)   1 Byte = 8 Bit   Speicherplatz für genau ein Zeichen (Erinnerung: z.B. ASCII-Code stellt Zeichen auf 8 Bit dar) ein erster abgeleiteter Variablentyp: Zeichenkette Aufeinanderfolge von Zeichen (z.B. Wörter) dargestellt und gespeichert als     Feld des Typs char anderer Name:     string Deklaration: dabei ist n die maximale Anzahl Zeichen, d.h. die Feldlänge - durch die Deklaration wird ein Block von n Byte Speicherplatz im   Arbeitspeicher reserviert. Achtung!   Der Name stringname enthält dabei die Speicheradresse , an der   die Zeichenkette im Arbeitspeicher beginnt (stringname ist ein sog. Zeiger ) - Zugriff auf die Komponenten, also die einzelnen Zeichen durch stringname[i] wobei   der Index i   das   i-1 . Zeichen der Zeichenkette bezeichnet, da in C die Numerierung bei 0 beginnt! z.B. char str[5]="INFO";      I    N    F    O  \0 1012 1013 1014 1015 1016 1017     ...    str[0]   str[1] str[2] str[3]  Endezeichen str enthält die Adresse 1015 str[0] = 'I', str[1]='N' , ... - gespeichert wird natürlich jedes Zeichen in seiner Binärdarstellung!   char      stringname[n];  str

Upload: trinhkiet

Post on 17-Sep-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

(3) Textzeichentypchar

reserviert (i.a.)   1 Byte = 8 Bit   Speicherplatz für genau ein Zeichen(Erinnerung: z.B. ASCII­Code stellt Zeichen auf 8 Bit dar)

ein erster abgeleiteter Variablentyp:Zeichenkette Aufeinanderfolge von Zeichen (z.B. Wörter)

dargestellt und gespeichert als     Feld des Typs char

anderer Name:     stringDeklaration: 

dabei ist n die maximale Anzahl Zeichen, d.h. die Feldlänge

­ durch die Deklaration wird ein Block von n Byte Speicherplatz im  Arbeitspeicher reserviert. ­ Achtung!   Der Name stringname enthält dabei die Speicheradresse, an der  die Zeichenkette im Arbeitspeicher beginnt (stringname ist ein sog. Zeiger)­ Zugriff auf die Komponenten, also die einzelnen Zeichen durch

stringname[i]

wobei   der Index i   das   i­1 . Zeichen der Zeichenkette bezeichnet, da in C die Numerierung bei 0 beginnt!

z.B.  char  str[5]="INFO";

➘      I    N    F    O  \0

1012 1013 1014 1015 1016 1017     ...   str[0]   str[1] str[2] str[3]   Endezeichen

str enthält die Adresse 1015str[0] = 'I', str[1]='N' , ...­ gespeichert wird natürlich jedes Zeichen in seiner Binärdarstellung!

  char      stringname[n];

 str

­ es muß stets ein Byte Platz für das Endezeichen eingerechnet werden,  sonst kann es zu Problemen führen   Beispiel: Erreichen des Endezeichens 

  

­ Achtung! Zuweisung eines ganzen Wortes nur in der Deklaration erlaubt  danach nur noch Zugriff auf Einzelkomponenten möglichBeispiel:

str = "text";   (FALSCH!)str[0] = 't'; (RICHTIG!)str[1] = 'e';str[2] = 'x';str[3] = 't';

(4) leerer Typ void

sinnvoll z.B. Für Funktionen ohne Ergebniswert (sog. Prozeduren oder Subroutinen)

aus diesen Grundtypen lassen sich dann beliebig komplexere Typen selbstdefinieren(dazu mehr in der 4. Vorlesung)

3.3 Ausdrücke und Operatoren

Ein Ausdruck ist eine Aneinanderreihung von Zahlen, Strings und Operatoren, die sich zu einem Wert auflösen lassen, sprich: eine mehr oder weniger komplexe Rechenvorschrift

⇨Ausdrücke können über Operatoren miteinander verknüpft werden ⇨Ausdrücke können Variablen zugewiesen werden

Operatoren: es gibt grundsätzlich unäre, binäre und terniäre Operatoren

     z.B.:(1) unäre Operatoren:  (in C)  Inkrementoperator ++ausdruck

     ausdruck++ Dekrementoperator  ­­ausdruck

            ausdruck­­

(2) binäre Operatoren:  arithmetische Grundoperationen + , ­ , * , / (in allen Programmiersprachen)

(3) terniäre Operatoren:  eher seltenin C  z.B.        Ausdruck1  ?  Ausdruck2  : Ausdruck3ist Ausdruck 1 wahr so berechne Audruck2 sonst berechne Ausdruck3

Zuweisung: (binärer Operator)

­ eine Zuweisung  ist selbst wieder ein Ausdruck ­ die Zuweisung hat den Wert, der der Variablen zugewiesen wird

Vergleiche und logische Operatoren

VergleicheSymbolik fürVergleiche in Programmiersprachen ähnlich der ausder Mathematik bekannten: 

< ,  >   ≤  ...    <=≥ ... >== ... == doppeltes Gleichheitszeichen, da '=' der Zuweisung entspricht

allgemein ist die Syntax:

­ liefert wieder einen Ausdruck­ dieser Ausdruck hat einen int­Wert, und zwar    0 ,  falls der Vergleich nicht zutrifft

  1,   falls der Vergleich zutrifft

  Variablenname   =    Ausdruck

  Ausdruck   Vergleichsoperator    Ausdruck

Logische OperatorenAussagenlogisches    UND ODER VERNEINUNGSymbolik:     &&    || ! (in C)

   .and.     .or.          .not. (in FORTRAN)      &    | ~ (in MATLAB)

­ liefert wieder einen Ausdruck­ dieser Ausdruck hat einen int­Wert, und zwar   0 ,  falls der Gesamtausdruck wahr

 1,   falls der Gesamtausdruck falsch ist 

Anweisungen ­ sind in der jeweiligen Programmiersprache erlaubte Ausdrücke, die zeilenweise in 

den  Programmen geschrieben werden (oder durch entsprechende Zeichen voneinander  abgegrenzt, z.B. ein Komma in FORTRAN oder in MATLAB)­ möglicherweise prinzipiell durch ein Zeichen abgeschlossen werden 

in C: 

Priorität von Operatoren

(von höchster zu niedrigster Priorität)Symbol          Name/Bedeutung                                                      Assoziativität-----------------------------------------------------------------++ Erhöhung nach Auswertung von links nach rechts-- Erniedrigung nach Auswertung ( ) Funktionsaufruf [ ] Arrayelement -> Zeiger auf Strukturfeld . Felder einer Struktur oder Union -----------------------------------------------------------------++ Erhöhung vor Auswertung von rechts nach links-- Erniedrigung vor Auswertung ! logisches NOT - unäres Minus + unäres Plus & Adresse von * Dereferenzierungsizeof Größe in Bytes (type) Typumwandlung (cast) -----------------------------------------------------------------

  Ausdruck    logischer Operator    Ausdruck

  Ausdruck ;

* Multiplikation von links nach rechts/ Division % Divisionsrest (modulo) -----------------------------------------------------------------+ Addition von links nach rechts- Subtraktion -----------------------------------------------------------------< kleiner als von links nach rechts<= kleiner oder gleich > größer als >= größer oder gleich -----------------------------------------------------------------== gleich von links nach rechts!= ungleich -----------------------------------------------------------------&& logisches AND von links nach rechts-----------------------------------------------------------------|| logisches OR von links nach rechts-----------------------------------------------------------------? : Bedingung von rechts nach links-----------------------------------------------------------------= Zuweisung von rechts nach links*= zusammengesetzte Zuweisung/=%=+=-=<<=>>=&=^=|= -----------------------------------------------------------------, Komma-Operator von links nach rechts-----------------------------------------------------------------

Typumwandlungnötig, falls in einer Operation Operanden verschiedenen Typs beteiligt sind

● implizite Typumwandlung:   durch den Compilerz.B.   int i=1, k=3;

float x;x = i*k;        int*int liefert int,  in der Zuweisung Umwandlung intfloat

● explizite Typumwandlung:       durch einen cast­Operator z.B.  float y = 6.78;

i = 3 + (int) y;

4. Entwurf von Algorithmen

Entwurfbeispiel: 

Prinzipien zum Entwurf:● Zerlegung des Problems in Teilprobleme (Modularisierung)

 durch schrittweise Verfeinerung (TOP­DOWN­Entwurf)  ausgehend von Lösungen für Teilaufgaben Zusammensetzen zu einem Programm

(BOTTOM­UP­Entwurf)● Zerlegen in Teilaufgaben durch Teilen der Eingangsdaten und Anwendung des 

selben Algorithmus auf die kleineren Datenmengen⇨ Prinzip „TEILE UND HERRSCHE“ (DIVIDE & CONQUER)

● exakte Analyse der Daten ⇨ entsprechende Definition von passenden Datentypen         ⇨ abstrakte Datentypen (Datentyp + zugehör. Operationen)

● UnterprogrammtechnikTeilprobleme in (für sich abgeschlossenen) Funktionen/Routinen implementieren⇨Mehrfachnutzung von Teilalgorithmen möglich⇨ unabhängig voneinander programmierbar (nur Schnittstellen müssen klar sein)

Ziel ist ein effizienter Algorithmus zur Problemlösung, d.h. möglichst geringer Ressourcenaufwand (Speicher & Laufzeit)

Grundsätzliche Schritte:gegeben sei eine Problemstellung, deren Lösung die auf dem Computer umsetzbar ist

1. Präzise Problembeschreibung (Spezifikation)2. Eingabedaten? Welche Ergebnisse (Ausgabedaten) werden erwartet?3. Welche Fälle sind zu unterscheiden?4. Zerlegung in Teilprobleme, schrittweise Verfeinerung5. Lösen der Teilprobleme ⇨Teilalgorithmen

Formulierung unter alleiniger Verwendung der Grundstrukturen (Sequenz, Schleife, Selektion)dabei Definition passender Datentypen

graphische Veranschaulichung von Algorithmen:  FlußdiagrammeStruktogramme(s. Wikipedia für die Elemente)

oder Formulierung als sogenannten Pseudocode  (halbformale Form)

Struktogramm

Oder:

Algorithmus für welches mathematische Problem?

Beispielalgorithmus:

Auszugeben ist die Summe derjenigen von N einzulesenden Zahlen,  die zwischen den vorzugebenden Werten L und R liegen. 

Flußdiagramm:

Struktogramm:

Pseudocode­Darstellung:

Beispiel Eingabe: N, L, R 

   Zähler = 1

  Summe = 0 

  solange Zähler <= N 

        führe aus: Eingabe: Zahl 

   falls L < Zahl < R 

       dann Summe = Summe + Zahl;

  Zähler = Zähler + 1

  Ausgabe: Summe 

Beispielende

5. Unterprogrammtechnik/Module

Unterprogramm/Modul: ● separate Programmeinheit, die Anweisungen umfaßt, um eine bestimmte Aufgabe zu 

erfüllen● bekommt i.a. Argumente (Werte, Informationen) vom aufrufenden Programm ● gibt i.a. ein Ergebnis an das aufrufende Programm zurück● Bezeichnung und Funktionalität kann je nach Programmiersprache variieren:

           Bezeichnung:  in C:         function  in FORTRAN:    function (mit Rückgabewert), subroutine (ohne Rückgabewert)  in PASCAL:        function (mit Rückgabewert), procedure (ohne Rückgabewert)

          Funktionen in Funktionen definieren (Verschachtelung von Unterprogrammen)?in C          nein

        alle Funktionen existieren hierarchisch auf der gleichen Ebenein FORTRAN       nein

        alle Funktionen existieren hierarchisch auf der gleichen Ebenein PASCAL         ja

        Unterprogramme von Unterprogrammen sind erlaubt

         Hauptprogramm:        in C          ebenfalls eine Funktion

        trägt immer den Namen main ,         kann nicht von anderen Funktionen aufgerufen werden         

in FORTRAN       hat den Rahmen PROGRAM programmname ...END PROGRAM         

in PASCAL        hat den Rahmen      program programmname     ...

                   end.

        Bibliotheksfunktionen:­ vordefinierte Standardfunktionen, die mit der Entwicklungsumgebung/ mit dem  Compiler geliefert werden   in C   in Funktionsdateien mit einer zugehörigen Headerdatei  name.h        z.B.: Standardmathebibliothek     Header: math.h

Standard­I/O­Bibliothek Header: stdio.hBibliothek für string­Funktionen Header: string.h

   in FORTRAN  in Modulen   in PASCAL      in units

­ Sammlungen von bereits vorhandenen Funktionen zu bestimmten Themen,  die frei oder mit Bezahlung erhältlich sind (z.B. im Netz)  in FORTRAN z.B.: lapack, blas, daspk, ...  in C z.B.: cblas, cvode, ...

Rückgabetyp Funktionsname(Liste von Argumenten) {

  Deklarationen lokaler Variabler 

  Anweisungen

  return Ergebniswert

}

5.1 Formaler syntaktischer Aufbau einer Funktion

Definition einer Funktion (Syntax in C)

  Funktionskopf             Funktionsblock                        

besteht aus: ­ Funktionskopf      Schnittstellen zum aufrufenden Programm  d.h. Struktur der Funktion (Name, Argumente, Ergebnis)­ Funktionsblock/rumpf  Algorithmus, den die Funktion umfaßt, d.h. eigentliche   Umsetzung der Aufgabe der Funktion

            Dateneingabe                       Datenrückgabe(Argumente) (Ergebnis)

Komponenten:● Funktionsname ... Bezeichung der Funktion, unter der sie aufgerufen wird● Argumentliste   ... ­ Liste der Eingabeparameter mit ihren Datentypen, die vom

    aufrufenden Programm an die Funktion gegeben werden  ­ für die dort aufgelisteten Variablen wird mit Aufruf der 

           Funktion Speicherplatz bereitgestellt● lokale Variable ...  ­ sind nur im Funktionsblock gültig, ab ihrer Deklaration

     reservieren sie Speicher bis zum Abschluß der Funktion                                            ­ dienen der Zwischenspeicherung von Werten während der

            Funktionsausführung● return                ... Anweisung ist dann erforderlich, wenn ein Ergebnis zurückgegeben

 wird● Rückgabetyp    ... Datentyp des Ergebnisses (Funktionswertes), das an das aufrufende

Programm zurückgegeben wirdbei Funktionen ohne Rückgabe:    void­Typ   und  return; (ohne Wert) ist optionalErinnerung:  in anderen Programmiersprachen tragen solche Funktionen auch 

einen anderen Namen (subroutine, procedure)

Funktion

 Rückgabetyp Funktionsname(Liste der Argumenttypen);

Beispiel: Funktion zur Berechnung des Mittelwertes dreier Zahlen

Aufruf im Programm/in einer anderen Funktion:● in Zuweisung: m = mittelwert(x1, x2, x3);● in einem Ausdruck: y = sin(3.5*mittelwert(x1, x2, x3));

           printf(''Der Mittelwert ist %7.3f. \n'',mittelwert(x1,x2,x3));Wo wird die Funktion definiert?

Alle im Programm benutzten Funktionen müssen dem Compiler vor Beginn der main­Funktion (Hauptprogramm) bekannt sein.

Funktionen, die durch andere Funktionen aufgerufen werden, müssen vor letzteren dem Compiler bekannt sein.

Varianten zum „Bekanntmachen“:1. Definition der Funktion innerhalb des Programms

a) vor dem Hauptprogramm

b) nach dem Hauptprogramm und Deklaration vor dem Hauptprogramm

Deklaration einer Funktion:

Bekannmachen des Namens zusammen mit allen Schnittstellen zum aufrufenden Programm, d.h. mit den Argumenttypen und dem Rückgabetyp=  Prototyp der Funktion

Definition der Funktion

 main­ Funktion

Definition der Funktion

 main­ Funktion

Deklaration der Funktion

Definition der Funktion

Deklaration der Funktion

 main­ Funktion

Deklaration der Funktion

durch Einbinden der Headerdatei mit

#include ''func.h''

Beispiel zu 1. :    Mittelwert dreier Zahlen, nun im Programm eingebunden

2. Definition der Funktion in anderer Quelldatei und Deklaration im Programm

        Quelldatei   func.c      Hauptprogramm                                

      Headerdatei   func.h

(beide in demselben Verzeichnis)

­ Deklaration(Bekanntmachen) der Funktion im Hauptprogramm vor der    main­Funktion durch Einbinden (#include) der zugehörigen Headerdatei

   Headerdatei (header = Funktionskopf) beinhaltet nur eine Liste der  Funktionen,  die in der Funktionsdatei definiert sind

­ die Präprozessor­Direktive   #include ''func.h''               fügt den Text, so wie er in der Headerdatei steht, direkt ins Programm ein

   d.h. durch Verwenden der Headerdatei muß man nicht im eigenen Programm alle                Funktionsdeklarationen wieder selbst schreiben

   ­ Standardbibliotheks­Header werden durch  #include < name.h >

    eingebunden. Das sagt dem Präprozessor, daß diese im  Standardbibliotheks­     verzeichnis der Entwicklungsumgebung zu finden sind

­ steht die Funktionsquelldatei in einem anderen Verzeichnis als das Hauptprogramm   muß in der #include­Direktive der volle Pfad zu dem Verzeichnis angegeben werden

­ in PellesC: Funktionsdateien und Hauptprogramm zu einem Projekt zusammenfassenArbeit des Linkers ist dann im Hintergrund automatisch aktiv

­ Verwendung von Headerdateien ist C­typisch, in anderen Programmiersprachen    nicht üblich

//Funktionsdeklaration

double func(int i, double x)

{ double y;

 y= i*x;

 return y;

}

int main

{ int j=1; 

  double z = 0.2;

  z = func(j,z);

  return 0;

sinnvoll, wenn● die Funktionen für mehrere Programme genutzt werden sollen (Module)● das Problem ein größeres Programmpaket erfordert, das sonst nicht mehr 

übersichtlich ist (Zerlegung eines Programms in Teilprogramme)● häufig werden solche Funktionen in Bibliotheken zusammengefaßt, die dann

nur einmal compiliert werden müssen und bei Bedarf nur durch ihreDeklarationen dem Programm bekanntgemacht (nur Funktionsköpfe! Nur Schnittstellen der Funktion nach außen)und durch den Linker in Maschinencode an das übersetzte Programm angebunden werdenz.B. Standardfunktionen in C,  wie  printf,  scanf

                   dazu Einbinden der Headerdatei stdio.h der Standard­I/O­Bibliothek von C 

5.2 Argumentübergabe

Wenn eine Funktion mit einer nichtleeren Argumentliste durch ein Programm aufgerufen wird, bedeutet das einen Transfer der Daten aus den aktuellen Variablen der Liste in die formalen Variablen des Funktionskopfes.

Was geschieht genau beim Aufruf?● Programmabarbeitung springt zum Maschinencode der Funktion● für die formalen Parameter (Argumente) der Funktion wird Speicherplatz reserviert● die Werte (der aktuellen Variablen), die beim Aufruf der Funktion in der Liste 

stehen, werden an die formalen Parameter in der Reihenfolge der Liste übergeben,d.h. an die entsprechenden Speicherplätze geschrieben

● die Funktion arbeitet nur auf den formalen nicht auf den aktuellen Parametern Beispiel:

AS

11

2

 Selbst, wenn die selben Argumentnamen beim Aufruf der Funktion verwendet werden wie  in der Definition der Funktion, sind aktuelle und formale Variablen voneinander verschieden! Für die Zeit des Funktionsaufrufs werden über die Variablennamen stets die „nächsten“(die „innersten“) Variablen angesprochen und die formalen Parameter (Variablen) des Funktionskopfes  sind  der Funktion „näher“ als die im Programm deklarierten „aktuellen“Variablen der Argumente.

Unterschiedliche Arten des Datentransfers:● Argumentübergabe „call­by­value“ (Wertübergabe)● Argumentübergabe „call­by­reference“ (Speicheradressübergabe)

        in vielen Programmiersprachen gibt es diese zwei Arten (z.B. C, FORTAN, PASCAL)      in anderen nicht (z.B. LOGO, MATLAB nur Wertübergaben)

(A) Argumentübergabe „call­by­value“ (Wertübergabe)

Es wird bei Aufruf der Funktion von der als Argument auftretenden Variablen nur dergespeicherte Wert an den entsprechenden formalen Parameter der Funktion übergeben 

⇨d.h. das was auf dem Speicherplatz der „aktuellen“ Variablen steht, wird in den        mit Funktionsaufruf reservierten Speicherplatz der entsprechenden „formalen“     Variablen  geschrieben, s. obiges Beispiel)⇨Funktion kann nur lesend auf die aktuellen Variablen zugreifen aber nicht schreibend.  

(B) Argumentübergabe „call­by­reference“ (Speicheradressübergabe)

Es wird bei Aufruf der Funktion als Argument die Speicheradresse einer Variablen im Arbeitsspeicher an den entsprechenden formalen Parameter der Funktion übergeben 

⇨ da die Funktion damit direkt auf den Speicherplatz einer „aktuellen“ Variablen des      aufrufenden Programms zugreifen kann, kann sie dort sowohl den aktuellen Wert      herauslesen als auch einen neuen Wert hineinschreiben⇨Funktion kann lesend und schreibend auf die aktuellen Variablen zugreifen.  

„call­by­reference“: Referenzparameter = Speicheradresse einer Variablen

 Typ *  zeigervariablenname;

Wie erhält man die Speicheradresse?In C: Adressoperator(Referenzierungsoperator)   &Beispiel: int i; Variable  i  wird deklariert, d.h. 4 Byte Speicherplatz

werden reserviertprintf(''Speicheradresse von i: %d'',&i);

gibt die reservierte Speicheradresse (erstes Byte) auf dem Bildschirm aus

              i

2102  2103 2104 2105 2106 2107  2108   2109   2110   2111   2112    2113

Bildschirmausgabe: Speicheradresse von i: 2105

Objekte, die die Speicheradresse von Variablen speichern, heißen Zeigervariable (Pointer)

Deklaration solcher Zeigervariablen:

Typ ist entscheidend, da damit auch die Information gegeben ist, wieviel Bytedie zu der gespeicherten Anfangsadresse gehörige Variable insgesamt einnimmt

Beispiel: int * p ;    p „zeigt“ auf eine Variable  vom Typ int, d.h.      p reserviert Speicherplatz für eine Speicheradresse einer     int­Variablen 

int i = 1;   Variable i reserviert Speicherplatz von 4 Byte und dieser       wird mit dem Wert '1' initialisiert, d.h. dieser Wert wird     dort als erster Wert gespeichert 

p = &i;     auf den Speicherplatz von p wird die Anfangsspeicheradresse     von i geschrieben

              i

2102  2103 2104 2105 2106 2107  2108   2109   2110   2111   2112    2113

p

Wechselspiel: 

Adressoperator                      &:            Variable       Speicheradresse (Referenzierungsoperator)Dereferenzierungsoperator   *:   Speicheradresse    Variable 

        (Zugriff auf gespeicherten Wert)

Beispiel: Fortsetzungint j;j=*p;   in den Speicherplatz, den j reserviert, wird der Wert eingeschrieben,

der an der Speicheradresse steht, die p speichert („auf die p zeigt“),hier speichert p die Adresse von i  ⇨  j bekommt den  Wert '1'

Standardbeispiel:

Zur Illustration der Unterschiede zwischen den zwei ArgumentübergabenTausch zweier Variablenwerte.

Häufig ist die Argumentliste von Funktionen eine Mischform, d.h. umfaßt sowohlWerte­ als auch Referenzparameter