Informatik: Abschnitt 4 Programmiersprache C

Werbung
Informatik: Abschnitt 4
Inhalt:
4. Programmiersprache C
4.1 Programmaufbau in C
4.2 Basisdatentypen und einfache Anweisungen
4.3 Steuerfluss-Konstrukte
4.4 Arbeit mit indizierten Größen (Felder)
4.5 Arbeit mit Zeigern
4.6 Zeichen und Zeichenketten
4.7 Funktionen (Unterprogramme)
…
Peter Sobe
1
Programmiersprache C
Die C-Sprachfamilie:
 K&R – C (1972, Kerningham-/Ritchie, Entwickler von C)
 ANSI/ISO-C89
 ANSI/ISO-C99
Weiterentwickelt zu C++
 C++
(1985, Bjarne Stroustrup)
 ANSI/ISO-C++ 98
 ANSI/ISO-C++ 0x
Weitere C-ähnliche Sprachen:
 Java – C++-ähnliche Programmiersprache, SUN 1995
 C# – C++-ähnlich, Microsoft 2001
Peter Sobe
2
Programmiersprache C
Imperative Programmiersprache:
C-Anweisungen werden in der im Programm angegebenen
Reihenfolge ausgeführt:
 zeilenweise (von oben nach unten)
 innerhalb Zeile möglicherweise mehrere Anweisungen,
dann von links nach rechts
 Steuerfluss-Anweisungen (if, for, while, repeat, break, continue)
zur Beeinflussung der Abarbeitungsreihenfolge
Zum Vergleich: manch andere Programmiersprachen (logische und
funktionale, beispielsweise PROLOG) arbeiten die Ausdrücke nicht
notwendigerweise in der im Programm angegebenen Reihenfolge
ab.
Peter Sobe
3
Programmiersprache C
Ein Programm besteht aus:
Variablenvereinbarungen: hier werden Bezeichner für die
Verarbeitungselemente festgelegt. Es wird ein Typ für jede Variable
angegeben, z.B. Ganzzahl (int) oder Zeichen (char)
Anweisungen:
 zur Verarbeitung der Variablen
 zur Beeinflussung des Steuerflusses
Mehrfach auftretende Anweisungsfolgen werden oft in Funktionen
gekapselt.
Eine Hauptfunktion (main-Funktion) ist der Punkt, an dem mit der
Ausführung eines C-Programms begonnen wird.
Peter Sobe
4
Programmiersprache C
Peter Sobe
ausführbarer
Code
Bibliotheken
Linker
Maschinencode
Compiler (2. Stufe)
Assembler
Programm
C-Compiler
C-Programm
C-Präprozessor
Header
vorgegebene
C-Programm
Vor dem Ausführen des Programms:
5
Inhalt
Inhalt:
4. Programmiersprache C
4.1 Programmaufbau in C
4.2 Basisdatentypen und einfache Anweisungen
4.3 Steuerfluss-Konstrukte
4.4 Arbeit mit indizierten Größen (Felder)
4.5 Arbeit mit Pointern
4.6 Zeichen und Zeichenketten
4.7 Funktionen
…
Peter Sobe
6
4.1 Programm-Aufbau in C
// Beispielprogramm fakultaet.c
#include <stdio.h>
Kommentar
Include-Präprozessor-Anweisung
main()
{ int fakultaet;
int i;
main-Funktion
printf("Geben Sie bitte n ein >");
scanf("%d",&n);
fakultaet = 1;
for (i=2;i<=n;i++)
fakultaet = fakultaet * i;
Variablen-Deklarationen
Anweisungen
printf("Die Fakultaet von %d betraegt %d \n",n, fakultaet);
return 1;
SteuerflussAnweisung
}
Peter Sobe
7
Kommentare
Zur Kommentierung gibt es in C++ (nicht in C) die
Zeichenfolge „//“ (sog. Inline-Kommentare). Alles ab “//“, bis
zum Ende der Zeile wird vom Compiler als Kommentar
betrachtet:
int anzahl = 0; // Zähler für die Anzahl der Häuser,
// die ein weißes Dach haben
int i;
Bei den Kommentarzeichen “/*” wird alles bis zu den
Kommentarendezeichen “*/” als Kommentar vom Compiler
überlesen (in C und C++):
int anzahl = 0; /* Zähler für die Anzahl der
Häuser, die ein weißes Dach haben */
int i;
Peter Sobe
8
Kommentare
Kommentare in Kommentaren
Kommentare der Form „/*...*/“ können nicht geschachtelt
werden:
/*
int anzahl = 0; /* Zähler für die Anzahl der
Häuser, die ein weißes Dach haben */
int i;*/
falsch
Inline-Kommentare können dagegen in Kommentaren der
Form „/*...*/“ geschachtelt werden:
/*
int anzahl = 0; // Zähler für die Anzahl der Häuser,
// die ein weißes Dach haben
int i; */
richtig
Probleme, wenn Codeteile durch Auskommentieren deaktiviert
werden müssen!
Peter Sobe
9
Präprozessor-Anweisungen
Präprozessor-Anweisungen beginnen mit ‚#‘ und werden vor
der Übersetzung verarbeitet
Hier können z.B.Text-Ersetzungen vorgenommen werden.
#define EPS 0.000001
….
if ( diff < EPS ) return value;
else { /* berechne weitere Werte */ …}
Einbinden von so genannten Header-Dateien (*.h) zur
Bekanntgabe von Funktionsinterfaces, z.B.
#include <stdio.h>
Peter Sobe
10
Präprozessor-Anweisungen
Präprozessor-Anweisungen können zur Versionierung des
Codes benutzt werden
#ifdef VERSION_1
int a = 0,b = 0, c =0; // hier alles mit Integerzahlen
#endif
#ifdef VERSION_2;
float a = 0.0, b = 0.0, c = 0.0; // jetzt alles mit Fließkommazahlen
#endif
Präprozessor-Anweisungen auch zum “Auskommentieren“ von
Code – anstelle geschachtelter Kommentare
#ifdef IRGENDETWAS_UNDEFINIERTES
int anzahl = 0; // Zähler für die Anzahl der Häuser,
// die ein weißes Dach haben
int i;
#endif
Peter Sobe
11
Die main-Funktion
 Der Beginn der main-Funktion ist der Startpunkt des Programms.
 Die main-Funktion kann aus dem Aufruf des Programms
Parameter übernehmen
 Das Ende der main-Funktion bedeutet das Ende des
Programmlaufs.
int main()
{ // hier beginnt die Verarbeitung
…
return 1;
// hier ist alles zu Ende
}
 exit oder return aus der main-Funktion bedeutet auch das Ende
der Programmverarbeitung
Peter Sobe
12
Die Form eines C-Progamms
C ist eine formatfreie Sprache, d.h. das Aussehen,
Zeilenumbrüche, Einrückungen haben keinen Einfluss auf
die Funktion.
Beispiele:
main() { scanf("%d",&a);
main()
printf(" quadrat = %d\n", a*a);
{
return 1; }
scanf("%d",&a);
printf(" quadrat = %d\n", a*a);
return 1;
}
Trotzdem sollte Code wie links dargestellt aussehen, um
bessere Lesbarkeit zu gewährleisten.
Peter Sobe
13
Inhalt
Inhalt:
4. Programmiersprache C
4.1 Programmaufbau in C
4.2 Basisdatentypen und einfache Anweisungen
4.3 Steuerfluss-Konstrukte
4.4 Arbeit mit indizierten Größen (Felder)
4.5 Arbeit mit Pointern
4.6 Zeichen und Zeichenketten
4.7 Funktionen
…
Peter Sobe
14
4.2 Basisdatentypen und einfache Anweisungen
Die Verarbeitung erfolgt durch Anweisungen, die die Werte der Variablen
verändern.
Variablen können Zahlenwerte, logische Werte (wahr, falsch), Zeichen,
Zeichenketten, Zeiger, Felder aufnehmen
Variablen müssen vor ihrer ersten Benutzung auf jeden Fall deklariert
worden sein.
Bezeichner (Namen für Variable, Funktionen, ...)
• Namen beginnen mit einem Buchstaben oder einem Unterstrich.
• Die weiteren Zeichen sind Buchstaben, Zahlen oder Unterstriche.
• Schlüsselworte der Sprache dürfen nicht als Name verwendet werden
Peter Sobe
15
Variablennamen
Zulässige Variablennamen:
• a; i; j; k;
• _pointer;
• ganz_langer_name_24_undNochLaenger;
• name; Name; // Groß- und Kleinschreibung wird unterschieden
Nicht als Variablenname zulässig:
• 34Name; // Fehler Zahl am Anfang nicht erlaubt
• Strassen Name; // Leerzeichen nicht erlaubt: Strassen_Name
• Ölinhalt // Fehler, Umlaute verboten
• C&A; // Fehler; Sonderzeichen verboten
• while; // da es ein Schlüsselwort while bereits gibt
Variablenname sollten kurz sein, aber inhaltlich ihre Bedeutung
wiedergeben
Peter Sobe
16
Variablennamen
Variablenname sollten kurz sein, aber inhaltlich ihre Bedeutung
wiedergeben, z.B.
int anzahl_patienten;
float gewicht;
Indexvariable und Zähler werden oft mit i, j, k oder z bezeichnet.
Beispiele für schlecht gewählte Variablennamen:
int meinkleinerschleifenzähler=0;
int grosserschleifenzaehler;
Peter Sobe
17
Schlüsselwörter
Folgende C-Schlüsselworte dürfen nicht als Variablennamen
benutzt werden:
auto double int struct break else long switch
case enum register typedef char extern return union
const float short unsigned continue for signed void
default goto sizeof volatile do if static while
In C++ weitere Schlüsselwörter:
asm export private true bool false protected try
catch friend public typeid class inline reinterpret_cast
typename const_cast mutable static_cast using delete
namespace template virtual dynamic_cast new this
wchar_t explicit operator throw
Peter Sobe
18
Konstanten
Konstanten und Zeichenfolgen (Literale)
Konstanten sind
• ganze Zahlen, z.B. 123, -465, 033, 0xab, 0XFF, 123L, 123UL,
• Gleitkommazahlen, z.B. 12.34, 12.45e-3, 0123, 1e20,
• Zeichenkonstanten, z.B. ‘a‘, ‘X‘, ‘\07‘, ‘\xb‘ und
• Aufzählungswerte, z.B. rot, Montag, ...
(wenn vorher entsprechend definiert)
Zeichenfolgen sind z.B.
• "Guten Morgen" (besteht aus Ein-Byte-Zeichen) und
• L"Guten Morgen" (besteht aus Mehr-Byte-Zeichen)
Peter Sobe
19
Operatoren
Operatoren zur Anwendung auf eine oder zwei Variablen:
[] () . ->
++ -- & * + - ~ ! sizeof
/ % << >> < > <= >= == !=
^ | && || ? :
= *= /= %= += -= <<= >>= &= ^= |=
Beispiele:
a++; // a=a+1;
if (aussage1 && aussage2) {printf("zwei Aussagen \n");} // logisch UND
glück = liebe || geld; // logisch ODER
Interpunktionszeichen in C: { } . ;
Peter Sobe
20
Trennzeichen (white spaces)
Trennzeichen der Sprache C sind:
Zwischenraum (space, blank), horizontaler Tabulator, neue Zeile
vertikaler Tabulator, Seitenvorschub (form feed)
→ siehe formatfreie Sprache
Leerzeichen und Zeilenumbrüche dürfen in C / C++ an beliebiger
Stelle außer in Namen stehen:
int var_i=17;
int var_i = 17;
int
var_i
= 17;
int var_
i=17; // ist aber verboten
Peter Sobe
21
Elementare Datentypen (1)
Wertebereich
Genauigkeit
char = signed char
unsigned char
1 Byte
1 Byte
-2^7 ... +2^7-1
0 ... 2^8-1
2 Dezimalstellen,
z.B. ‚88‘ ist genau
int = signed int
unsigned int
4 Byte
4 Byte
-2^31 ... +2^31-1
0 ... 2^32-1
9 Dezimalstellen
short int = signed short int
unsigned short int
2 Byte
2 Byte
-2^15 ... +2^15-1
0 ... 2^16-1
4 Dezimalstellen
long int = signed long int
unsigned long int
8 Byte
8 Byte
-2^63 ... +2^63-1
0 ... 2^64-1
19 Dezimalstellen
(ab C99, 64 Bit)
bool (nur C++)
1 Byte
{true,false}
Die angegebenen Werte stellen Beispiele für 32-Bit Umgebungen
dar, sie sind implementierungsabhängig
Peter Sobe
22
Elementare Datentypen (2)
Wertebereich
Genauigkeit
enum { list }
enum id { list }
enum id
4 Byte
4 Byte
4 Byte
2^32 verschiedene Werte
float
double
long double
4 Byte
8 Byte
10 Byte
ca. -10^38 ... +10^38
ca. –10^308 ... +10^308
ca. -10^4932 ... +10^4932
7 Dez.-Stellen
15 Dez.-Stellen
19 Dez.-Stellen
type*
void*
4 Byte
4 Byte
0...2^32-1
0...2^32-1
einzelne Bytes
im Speicher
adressierbar
type&
4 Byte
0...2^32-1
Peter Sobe
23
Elementare Datentypen (3)
Datentypen für ganze Zahlen in C:
int, signed int, unsigned int,
long, signed long, unsigned long,
short, signed short, unsigned short
Beispiel:
int i = -64;
long li = 3;
Integer-Variablen werden für beispielsweise für zählbare Dinge
benutzt, oder für Index-Berechnungen.
Peter Sobe
24
Elementare Datentypen (4)
Gleitkommazahlen:
float, double, long double
Beispiele:
double d = 64.3345;
double d1 = 1.234e-22; // ohne Leerzeichen zu schreiben
float f = 67.31f;
float f1 = 2.9744e-22f;
double x = 5.; // 5. entspricht 5.0
Gleitkommazahlen werden für Eigenschaften, Größen verwendet,
die als rationale oder reelle Zahlen angegeben werden, z.B.
Spannung (=4.5 V).
Peter Sobe
25
Elementare Datentypen (5)
Wahrheitswerte (bool) mit den Werten true und false (nur C++)
Beispiele:
bool gefunden = true;
bool ende = false;
Einzelne Zeichen (char) - die Werte entsprechen in der Regel dem
ASCII-Zeichensatz
Beispiele:
char c = 64;
char c1 = ‘h’;
char c2 = ‘\n’;
Peter Sobe
26
Zeichenkonstanten
Spezielle Zeichenkonstanten:
/* Zeilenvorschub: */ ‘\n’
/* Horizontaler Tabulator: */ ‘\t’
/* Vertikaler Tabulator: */ ‘\v’
/* Backspace: */ ‘\b’
/* Carriage-Return: */ ‘\r’
/* Form-Feed: */ ‘\f’
/* Alarm: */ ‘\a’
/* Backslash: */ ‘\\’
/* Fragezeichen: */ ‘\?’
/* Einfaches Anfuehrungszeichen: */ ‘\’’
/* Doppeltes Anfuehrungszeichen: */ ‘\”’
Peter Sobe
27
Konstanten
Die Verwendung von Konstanten erhöht die Lesbarkeit des
Programms und macht es änderungsfreundlicher
Anstatt: umfang = 2 * radius * 3.14159;
Besser: const double PI = 3.14159;
umfang = 2 * radius * PI;
const heißt nur, dass die Variable nicht mehr verändert werden darf,
der Wert muss nicht schon zur Übersetzungs-Zeit bestimmt werden
können. Beispiel:
const double UmfangMeinKreis = 2.0 * radius * PI;
// radius muss keine Konstante sein
Peter Sobe
28
Konstanten
Guter Programmierstil ist es, außer den Konstanten –1, 0 und 1
keine expliziten Zahlenkonstanten in seinem Programm zu
verwenden, sondern diese immer über const einen Namen
zuzuweisen.
Anstatt:
for (int i=0;i<10;i++)
spieler[i].anzahl_huetchen= …
Besser:
const int ANZAHL_DER_MITSPIELER = 10;
…
for (int i=0; i < ANZAHL_DER_MITSPIELER; i++)
spieler[i].anzahl_huetchen=…
Peter Sobe
29
Typkonvertierungen
Ohne Angabe hat eine Gleitkommakonstante den Typ double.
double d = 0.6;
float f = 0.6;
...
d = f; // ergibt keine Warnung
f = d; // ergibt eine Warnung
Bei einer Zuweisung eines double an ein float wird eine Warnung
erwartet:
float ff = 0.5987654321987; // kann man mal ausprobieren
Peter Sobe
30
Interne Darstellung von Gleitkommazahlen
0.6 ist im Binärsystem:
1001 1001 1001 1001 1001 1001 1001 1001 ...
32 Bits (Mantisse genannt)
Dieses bedeutet:
1* 1/2 + 0 * 1/4 + 0 *1/8 + 1 * 1/ 16 + 1* 1/ 32 ... * 1/268435456
und ergibt: 0.59999999776482500000
Wenn float nur 24-Bit zur Darstellung der Mantisse verwendet (ist
üblich, da normalerweise noch 8 Bit zur Darstellung des Exponenten
verwendet werden), ist die Genauigkeit noch etwas geringer.
Die Zuweisung dieser 24 Bit-Genauigkeit an eine double-Zahl
ergibt somit eine Warnung
Peter Sobe
31
Explizite Typkonvertierungen
In einigen Fällen ist eine explizite Typkonvertierung unbedingt
erforderlich:
int a = 5;
int b = 2;
// In C/C++
double x = ((double) a ) / ((double) b); // x ist 2.5, sonst 2.0
In C++ auch erlaubt:
double x = double(a) / double(b)
// In C++ empfehlenswert:
double x = static_cast<double>(a) / static_cast<double>(b);
Peter Sobe
32
Aufzählungstypen
Manchmal ist es sinnvoll, eine Vielzahl gleichartiger Konstanten zu
einer Menge zusammenzufassen. Jedes Element dieser Menge
bekommt eine Ordinalzahl Das erste Element erhält z.B. die
Ordinalzahl 0, das zweite 1 usw.,
Beispiel:
enum Wochentag { Mon, Die, Mit, Don, Fri, Sam, Son };
Wochentag Tag;
Tag = Mon;
Syntax von Aufzählungen:
enum AufzTyp { Bezeichnerl, Bezeichner2, ... } Variable;
enum { Bezeichnerl, Bezeichner2, ... } Variable;
enum AufzTyp { Bezeichnerl = 2, Bezeichner2, ... };
Peter Sobe
33
Herunterladen