C
C
1 Einleitung
1.1 bersicht
Einleitung
bersicht
Einige grundlegende Begriffe
Geschichtliche Entwicklung, Einordnung
Ein erstes Programm
Grundelemente der Sprache C
Grundlegende Datentypen
Arithmetische Datentypen, Konstanten, Variablen, Zeiger, Felder,
Speicherklassen, Typattribute, Operatoren, Typumwandlung
Kontrollstrukturen
Blockanweisung, Verzweigungs-Anweisungen,
Wiederholungs-Anweisungen, spezielle Anweisungen
Hhere Datentypen
Benutzerdefinierte Datentypen,
Mehrdimensionale Felder, Strukturen und Varianten
Ergnzung: Aufzhlungstyp, Bitfelder
Funktionen
Argumente der main-Funktion, variable Parameteranzahl,
Unterschiede: ANSI-C K&R-C
Standardbibliotheken
Beispiele
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
bersicht (1)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
(primitiver) Datentyp:
(Wertemenge, Operationenmenge)
Datenobjekt:
kann Wert aufnehmen
Systemzustand:
bestimmt durch aktuelle Werte aller Datenobjekte
Operation:
Aktion, abhngig von Argumenten und Systemzustand
Abstrakter Datentyp (ADT):
(Wertemenge(n), Operationenmenge)
nach auen wie primitiver Datentyp. Beispiel: Intervalle.
Abstraktes Datenobjekt:
(Abstrakter Datentyp, Objekt)
ADT, dessen Operationen abhngen von Argumenten,
Systemzustand und Gedchtnis des ADTs; beeinflut
das Gedchtnis die Operationen nicht, liegt ein Abstrakter Datentyp vor. Beispiel: Warteschlange.
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
FORTRAN 57
BASIC
78
APL
68
MODULA-2 80
OBERON
88
LISP
ALGOL 60 60
ALGOL 68 77
PL/1
66
COBOL
68
LOGO
68
81
PASCAL
70
BCPL
67
SIMULA 67 69
PROLOG
ADA
83
PEARL
77
72
SMALLTALK 80
C++
84
59
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
double
else
enum
extern
float
for
goto
if
Einfhrung in C
Dirk Husung
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
2 Grundlegende Datentypen
2.1 Arithmetische Datentypen
Typ
Speicherplatzbedarf
signed
unsigned
signed
unsigned
signed
unsigned
signed
unsigned
long
TUHH
Rechenzentrum
char
char
char
short [int]
short [int]
short [int]
int
int
int
long [int]
long [int]
long [int]
float
double
double
Einfhrung in C
Dirk Husung
1 Byte
1 Byte
1 Byte
2 Bytes
2 Bytes
2 Bytes
maschinenabhngig 2 oder 4 Bytes
maschinenabhngig 2 oder 4 Bytes
maschinenabhngig 2 oder 4 Bytes
4 Bytes
4 Bytes
4 Bytes
4 Bytes
8 Bytes
maschinenabhngig 8, 10 oder
16 Bytes
Bemerkungen:
Der char-Typ kann compilerabhngig vorzeichenbehaftet oder vorzeichenlos sein.
Der jeweilige Speicherplatzbedarf kann mit dem
sizeof-Operator bestimmt werden (durch den
Prprozessor!). Es gilt:
sizeof (short) sizeof (int) sizeof (long).
SHRT_MIN (-32768)
SHRT_MAX
32767
LONG_MIN
((long)0x80000000)
LONG_MAX
0x7fffffff
#define DBL_MIN
2.2250738585072014e-308
#define DBL_MAX
1.7976931348623151e+308
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
IEEE-double-Format:
sign biased exponent significant
1 bit 11 bits
52 bits
msb
lsb
0/1 11 . . . 10
...
00 . . . 01
denormal 0/1 00 . . . 00
...
00 . . . 00
0
0/1 00 . . . 00
+
0 11 . . . 11
1 11 . . . 11
nan
0/1 11 . . . 11
...
11 . . . 11
normal
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
[1.]11 . . . 11 2exponent1023
...
[1.]00 . . . 00
[0.]11 . . . 11 21022
...
[0.]00 . . . 01
00 . . . 00
00 . . . 00
00 . . . 00
11 . . . 11
...
00 . . . 01
2.2 Konstanten
Ganzzahlige Konstanten
Konstante
Typ
1234
1234U
12345678L
134217728UL
0x8000000UL
int
unsigend int
long
unsigend long
unsigned long, hexadezimal
Hexziffern: 09, AF, af.
char, oktal
007
Gleitkommakonstanten
Konstante
Typ
12.7
1e5
2.0E-3
12.7f
1e5f
2.0E-3l
double
double
double
float
float
long double
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Konstanten (1)
Zeichen
Konstante
Typ
a
\007
\x0A
\n
\
char
char, oktale Notation (hier: \a)
char, hexadezimale Notation (hier: \n)
char, Escape-Sequenz
char, Escape-Sequenz
Zeichenketten
Zeichenketten sind Felder von Zeichen mit einem
zustzlichen abschlieenden 0-Zeichen.
Konstante
Typ
"string"
char *
"\"string\"" char *, Escape-Sequenz
Wichtig:
x belegt 1 Byte
"x" belegt 2 Bytes (0-terminierte Zeichenkette)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Konstanten (2)
2.3 Variablen
Variablen sind benannte Datenobjekte, die einen
Wert aufnehmen knnen.
Variablennamen bestehen aus einer Folge von
Buchstaben und Ziffern, beginnend mit einem
Buchstaben. Der Unterstrich _ zhlt dabei zu
den Buchstaben.
Zwischen Gro- und Kleinbuchstaben wird unterschieden.
Variablen sind vor Benutzung zu deklarieren;
z.B.:
extern unsigned int uMemoryUsed;
Sie sind an genau einer Stelle im Programm zu
definieren. Erst mit der Variablendefinition wird
Speicherplatz belegt; z.B.:
unsigned int uMemoryUsed;
Variablen knnen bei ihrer Definition initialisiert
werden; z.B.:
unsigned int uMemoryUsed = 0;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Variablen (1)
0x10000:
0x10004:
0x10008:
1 i
0x1000C: 0x10008 pi
0x10010:
1 aiVector[0] aiVector
0x10014:
2 aiVector[1]
0x10018:
3 aiVector[2]
0x1001C:
4 aiVector[3]
0x10020: 0x10010 piVector
0x10024:
0x10028:
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
2.5 Speicherklassen
Speicherklasse Beschreibung
auto
static
extern
register
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Standard, optional.
Sichtbarkeit: auerhalb aller Funktionen programmweit, innerhalb einer Funktion beschrnkt auf den aktuellen Block.
Lebensdauer: auerhalb aller Funktionen
ber die gesamte Programmlaufzeit, innerhalb einer Funktion fr die Ausfhrung des
betreffenden Blocks.
Initialisierung: auerhalb aller Funktionen
mit 0, sonst undefiniert, wenn nicht explizit
angegeben.
Sichtbarkeit: auerhalb aller Funktionen modulweit, innerhalb einer Funktion beschrnkt
auf den betreffenden Block.
Lebensdauer: ber die gesamte Programmlaufzeit.
Initialisierung: mit 0, wenn nicht explizit angegeben.
Deklaration, Definition i.a. in einem anderen
Modul auerhalb aller Funktionen als auto.
wie auto, jedoch Empfehlung an den Compiler, die betreffende Variable in einem Prozessorregister zu halten.
Speicherklassen (1)
Beispiel:
#include <stdio.h>
int main (void)
{
int i;
for (i = 0; i < 3; i++) {
int k = 0;
/* beliebiger Ausdruck */
printf ("%4d", k++);
}
for (i = 0; i < 3; i++) {
static int k = 0; /* konstanter Ausdruck */
printf ("%4d", k++);
}
return (0);
} /* main */
Ausgabe:
0
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Speicherklassen (2)
2.6 Typattribute
Attribut
Beschreibung
const
legt fest, da eine Variable nicht gendert werden darf, auch nicht komponentenweise (Felder, Strukturen); z.B.:
const double e = 2.7183;
zeigt an, da eine Variable jederzeit gendert werden kann, auch in nicht offensichtlicher Weise etwa im Verlauf einer
Interrupt-Behandlung ( Einschrnkung
fr Compileroptimierungen).
volatile
Beispiel:
Zeiger auf ein Objekt vom Typ
int
int * const pi;
konstanter Zeiger auf ein Objekt vom Typ int
const int * pi;
Zeiger auf ein konstantes Objekt vom Typ int
const int * const pi; konstanter Zeiger auf ein konstantes Objekt vom Typ int
int * pi;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Typattribute (1)
2.7 Operatoren
Arithmetische Operatoren
Inkrement-, Dekrementoperator
Vergleichsoperatoren
Operatoren zur Bitmanipulation
Logische Operatoren
sizeof-Operator
Bedingter-Ausdruck-Operator
Zuweisungsoperatoren
Sonstige Operatoren
Anmerkung:
Die Zuweisung zhlt in C zu den Operatoren.
Es gibt in C keine benutzerdefinierten Operatoren.
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Operatoren (1)
Rechenzentrum
Einfhrung in C
Dirk Husung
Operatoren (2)
bitweiser Operator |:
char a = 0xE4; /* 1110 0100 */
char b = 0xCC; /* 1010 1010 */
char r = a | b; /* 1110 1110 */
bitweiser Operator ^:
char a = 0xE4; /* 1110 0100 */
char b = 0xCC; /* 1010 1010 */
char r = a ^ b; /* 0100 1110 */
bitweiser Operator ~:
char a = 0xE4;
char r = ~a;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
/* 1110 0100 */
/* 0001 1011 */
Operatoren (3)
a
r
ua
ur
=
=
=
=
0xE4;
a >> 1;
0xE4;
ua >> 1;
/*
/*
/*
/*
1110
?111
1110
0111
0100
0010
0100
0010
*/
*/
*/
*/
a
r
= 0xE4;
/* 1110 0100 */
= a << 1; /* 1100 1000 */
logischer Operator !:
char a = 0xE4;
char r = !a;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
/* 1110 0100 */
/* 0000 0000 */
Operatoren (4)
2.8 Typumwandlung
Implizite Typumwandlung
Werden Operanden unterschiedlichen arithmetischen Typs miteinander verknpft, erfolgt eine Typanhebung:
x * ld (long double) x * ld
x * d (double)
x * d
x * f (float)
x * f
, sonst
, sonst
, sonst
long) x
u
long) u
long) l
x
int) x
* ul
* l
*
* l
* u
, sonst
, sonst
, sonst
, sonst
darin bezeichnen:
ld
d
f
ul
l
u
x
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Typumwandlung (1)
Explizite Typumwandlung
Der expliziten Typumwandlung dient der cast-Operator.
Beispiel: Zugriff auf die einzelnen Bytes einer intVariablen i:
((unsigned char *) & i)[0];
:
((unsigned char *) & i)[sizeof(i)-1];
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Typumwandlung (2)
3 Kontrollstrukturen
3.1 Block-Anweisung
Jede Anweisung kann eine Block-Anweisung sein.
Innerhalb jedes Anweisungsblocks ist die Definition
lokaler Variablen mglich.
{
definitions
statements
}
TUHH
Rechenzentrum
int t = a;
a = b; b = t;
}
Einfhrung in C
Dirk Husung
Block-Anweisung (1)
3.2 Verzweigungs-Anweisungen
if-, if-else-Anweisung
if (int_expr)
statement
if (i < 10) {
element[0][i] = i;
element[1][i] = i*i;
}
1
ja
2
int_expr != 0
3
statement
4
if (int_expr)
statement1
else
statement2
if (i < 2)
element[i] = i;
else
element[i] = element[i-2]
+ element[i-1];
1
ja
nein
int_expr != 0
3
statement1
statement2
5
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Verzweigungs-Anweisungen (1)
switch-Anweisung
switch (int_expr) {
case int_const:
statements
[break;]
default:
statements
}
switch (c) {
case \n: /* Zeilenende */
number_of_lines++;
case \t: /* Tabulator oder */
case : /* Leerzeichen */
number_of_words++;
break;
default:
/* bel. sonstiges Zeichen */
number_of_characters++;
break;
}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Verzweigungs-Anweisungen (2)
3.3 Wiederholungs-Anweisungen
while-Anweisung
while (int_expr)
statement
i = 0;
while (i < DIM) {
element[0][i] = i;
element[1][i] = i*i;
i++;
}
for-Anweisung
for (init_expr; int_expr; reinit_expr)
statement
quivalent zu:
init_expr;
while (int_expr) {
statement
reinit_expr;
}
for (i = 0; i < DIM; i++) {
element[0][i] = i;
element[1][i] = i*i;
}
do-while-Anweisung
do {
statements
} while (int_expr);
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
do {
element[0][i] = i;
element[1][i] = i*i;
} while (++i < DIM);
Wiederholungs-Anweisungen (1)
do {
while (int_expr ) for (init_expr ;
statement
statement
int_expr ; reinit_expr )
} while (int_expr );
statement
1
2
init_expr
statement
nein
int_expr != 0
3
statement
ja
4
int_expr != 0
4
int_expr != 0
nein
4
5
statement
6
reinit_expr
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Wiederholungs-Anweisungen (2)
return-Anweisung
return (i);
goto-Anweisung
goto STORAGE_ERROR;
/* ... */
STORAGE_ERROR:
fprintf (stderr, "zu wenig Speicher");
exit (1);
leere Anweisung
;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
3.5 Beispielprogramme
Zeichenkette kopieren
char
achSrc [] = "Zeichenkette";
char
achDest [20];
char * pchSrc
= achSrc;
char * pchDest
= achDest;
int i = 0;
while ((pchDest[i] = pchSrc[i]) != 0)
i++;
oder:
while ((*pchDest = *pchSrc) != 0) {
pchDest++;
pchSrc++;
}
oder:
while ((*pchDest++ = *pchSrc++) != 0)
;
oder:
while (*pchDest++ = *pchSrc++)
;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (1)
/*******************************************
* cel2fahr: Celsius-Fahrenheit-Tabelle
********************************************/
#include <stdio.h>
int main (void)
{
double dCel;
printf ("Celsius
Fahrenheit\n");
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (2)
/*******************************************
* wc: Zeichen, Woerter, Zeilen zaehlen.
********************************************/
#include <stdio.h>
#define FALSE
#define TRUE
0
1
0;
0;
0;
FALSE;
/* eingelesenes Zeichen */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (3)
/*******************************************
* dos2unix: <CR,LF> durch <LF> ersetzen.
********************************************/
#include <stdio.h>
#define CR 0x0D
#define LF 0x0A
int main (void)
{
int
c;
while ((c = getc (stdin)) != EOF) {
switch (c) {
case CR :
do {
if ((c = getc (stdin)) == LF)
break;
putc (CR, stdout);
if (c == EOF) goto ENDWHILE;
} while (c == CR);
/* kein break */
default :
putc (c, stdout);
break;
}
} ENDWHILE:
return (0);
} /* main */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (4)
/*******************************************
* unix2dos: <LF> durch <CR,LF> ersetzen.
********************************************/
#include <stdio.h>
#define CR 0x0D
#define LF 0x0A
int main (void)
{
int
c;
while ((c = getc (stdin)) != EOF) {
switch (c) {
case CR :
do {
putc (CR, stdout);
} while ((c = getc (stdin)) == CR);
if (c == EOF) goto ENDWHILE;
putc (c, stdout);
break;
case LF :
putc (CR, stdout);
default :
putc (c, stdout);
}
} ENDWHILE:
return (0);
} /* main */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (5)
/*******************************************
* tabexp: Tabulatorzeichen expandieren.
********************************************/
#include <stdio.h>
#define TABWIDTH 8
int main (void)
{
int iColumn;
int c;
iColumn = 0;
while ((c = getc (stdin)) != EOF) {
switch (c) {
case \t :
do {
putc ( , stdout);
} while (++iColumn % TABWIDTH);
break;
case \n :
putc (\n, stdout); iColumn = 0;
break;
default :
putc (c, stdout); iColumn++;
break;
} /* switch */
} /* while */
return (0);
} /* main */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispielprogramme (6)
4 Hhere Datentypen
4.1 Benutzerdefinierte Datentypen
Komplexere Vereinbarungen lassen sich schrittweise lesen, wenn die durch Klammerung und Prioritten vorgegebene Reihenfolge beachtet wird; mit
(term)[] Feld von
(term)() Funktion mit Wert
*(term) Zeiger auf
beispielsweise:
int
int
int
int
*x[8];
*x(int);
(*x)[];
(*x)(int);
wichtig:
In der Definition:
int * a, b;
Rechenzentrum
Einfhrung in C
Dirk Husung
void
PVOID;
#define INT
typedef INT *
typedef PINT *
int
PINT;
PPINT;
#define SIZE
size_t; /* aus stdlib.h */
typedef SIZE * PSIZE;
typedef PSIZE * PPSIZE;
typedef INT
typedef FINT *
FINT (INT);
PFINT;
damit:
PINT
PINT
PPINT
PFINT
TUHH
Rechenzentrum
x [8];
x (INT);
x;
x;
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
dynamische Felder
Mat
Mat[0]
Mat[1]
Mat[2]
Mat[3]
#define NROWS
Mat[0][0]
Mat[1][0]
Mat[2][0]
Mat[3][0]
PPINT ppIntMatrix;
SIZE i;
ppIntMatrix = (PPINT) malloc (
NROWS * sizeof (PINT));
for (i = 0; i < NROWS; i++) {
SIZE uSize = (NROWS - i) * sizeof (INT);
ppIntMatrix [i] = (PINT) malloc (uSize);
memset (ppIntMatrix [i], 0, uSize);
}
ppIntMatrix [0][0] = 1;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Bit-Felder
typedef struct {
unsigned Day
: 5; /* Bits 0..4 */
unsigned Month : 4; /* Bits 5..8 */
unsigned Year : 7; /* Bits 9..15 */
} DATE;
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
5 Funktionen
Eine Funktion wird deklariert (Funktionsprototyp) in
der Form
[extern] [Ergebnistyp] Funktionsname ([Parameterliste]);
oder:
static [Ergebnistyp] Funktionsname ([Parameterliste]);
Rechenzentrum
Einfhrung in C
Dirk Husung
Funktionen (1)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Funktionen (2)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
sondern so:
void Swap (int * pa, int * pb)
{
int t = *pa;
*pa = *pb; *pb = t;
} /* Swap */
alternativ:
#define Swap(a, b) {
int t = a;
a = b; b = t;
}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
\
\
\
_fac:
push
mov
ebp
ebp, esp
cmp
jg
[ebp+8],1
L1
mov
jmp
eax,1
L2
mov
dec
push
call
add
imul
eax,[ebp+8]
eax
eax
_fac
esp, 4
eax, [ebp+8]
mov
pop
ret
esp, ebp
ebp
L1:
0x1001C:
0x10018:
0x10014:
8
0x10010: ret-addr
0x1000C:
bp sp
0x10008:
0x10004:
0x10000:
L2:
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Dabei liefert:
aArg[0] den Namen des aufgerufenen Programms.
aArg[1] . . . Zeiger auf Aufrufargumente.
aArg[nArgs] den Wert NULL.
Mit zustzlichem Zugriff auf Umgebungsvariablen:
int main (int nArgs, char* aArg[],
char* pEnv[])
{
...
}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Aufruf:
CylinderVolume (1, 2);
implizite Typanpassung!
oder K&R-C:
double CylinderVolume ();
double CylinderVolume (rad, height)
double rad, height;
{
return (height*rad*rad*3.14159);
} /* CylinderVolume */
Aufruf:
CylinderVolume (1, 2);
Laufzeitfehler!
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
6 Beispiele
6.1 Taschenrechner
# ----------------------------------------# Makefile (dmake): Taschenrechner
# ----------------------------------------CC
CFLAGS
= gcc
= -Wall -O2 # alle Warnungen,
# Optimierungen
OBJS
calc.c
scanner.h
stack.h
scanner.o:
scanner.c scanner.h
stack.o:
stack.c stack.h
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (1)
/******************************************
* calc.c: einfacher Taschenrechner
*******************************************/
#include <stdio.h>
#include <math.h>
#include "scanner.h"
#include "stack.h"
#define loop
for(;;)
/******************************************
* Konstanten-Definitionen
*******************************************/
#define TOKENSIZE
256
/******************************************
* Hauptprogramm
*******************************************/
int main (void)
{
/* ... */
} /* main */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (2)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (3)
/******************************************
* scanner.h: Scanner
*******************************************/
#ifndef __SCANNER__
#define __SCANNER__
/******************************************
* Konstanten-Definitionen
*******************************************/
#define NUMBER
256
/******************************************
* Funktions-Prototypen
*******************************************/
extern int GetToken (char * pchToken);
#endif
/******************************************
* scanner.c: Scanner
*******************************************/
#include <stdio.h>
#include <ctype.h>
#include "scanner.h"
/******************************************
* Implementierung globaler Funktionen
*******************************************/
int GetToken (char * pchToken)
{
/* ... */
} /* GetToken */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (4)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (5)
/******************************************
* stack.h: double-Stack
*******************************************/
#ifndef __STACK__
#define __STACK__
/******************************************
* Funktions-Prototypen
*******************************************/
extern void
Push (double dValue);
extern double Pop (void);
#endif
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (6)
/******************************************
* stack.c: double-Stack
*******************************************/
#include <stdio.h>
#include "stack.h"
/******************************************
* Konstanten- und Variablen-Definitionen
*******************************************/
#define STACKSIZE
32
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Taschenrechner (7)
6.2 Portabilitt
/******************************************
* Portab.h
Spracherweiterungen,
*
Maschinenabhaengigkeiten
*******************************************/
#ifndef __PORTAB__
#define __PORTAB__
#include <stdlib.h>
#if defined (__GNUC__)
#define __ANSI__
#ifndef __32BIT__
#define __32BIT__
#endif
#define __LOWBYTEFIRST__
#endif
#if defined (__XLC__)
#define __32BIT__
#define __HIGHBYTEFIRST__
#endif
#if defined (__STDC__) ||\
defined (__ANSI__) ||\
defined (__cplusplus)
#define ARGS(parameters)
#define NOARGS
#else
#define ARGS(parameters)
#define NOARGS
#endif
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
parameters
VOID
()
Portabilitt (1)
/******************************************
* Konstantendefinitionen
*******************************************/
#define TRUE
#define FALSE
1
0
#define SUCCESS
#define FAILURE
0
(-1)
loop
for (;;)
sqr(a)
((a)*(a))
min(a,b)
(((a) < (b)) ? (a) : (b))
max(a,b)
(((a) > (b)) ? (a) : (b))
dimof(array)\
(sizeof(array) / sizeof(*(array)))
#endif /* !__PORTAB__ */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Portabilitt (2)
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
/******************************************
* DynMem.c
*******************************************/
#include "Portab.h"
#include "DynMem.h"
PVOID _MemNew (SIZE uSize)
{
PPVOID pMemory;
if (uSize <= MEM_MAXSIZE
&& (pMemory = (PPVOID) *((PPVOID)
((PCHAR) MemStore + uSize))) != NULL) {
*((PPVOID) ((PCHAR) MemStore + uSize)) =
*pMemory;
}
else if ((pMemory = (PPVOID) malloc (
uSize)) == NULL) {
INT iErrorClass = 0;
do {
(*MemErrorHandler) (iErrorClass++);
} while ((pMemory = (PPVOID) malloc (
uSize)) == NULL);
}
#if defined (__MEMTEST__)
ulMemUsed += uSize;
if (ulMemUsed > ulMaxMemUsed)
ulMaxMemUsed = ulMemUsed;
#endif
#if defined (__PROTOCOL__)
printf ("MemNew: %p (%d Bytes)\n",
pMemory, uSize);
#endif
return (PVOID) pMemory;
} /* _MemNew */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
F =c:
(f (x), f (x))|x=x0
= (c, 0)
F =x:
(f (x), f (x))|x=x0
= (x0, 1)
Einfhrung in C
Dirk Husung
/******************************************
* Gradient.h: Automatische Differentiation
*******************************************/
#ifndef __GRADIENT__
#define __GRADIENT__
#include <stdio.h>
#include <math.h>
typedef struct {
DOUBLE x;
/* Wert
*/
DOUBLE dx;
/* Wert der 1. Ableitung */
} GRADIENT;
typedef GRADIENT * PGRADIENT;
GRADIENT Const (DOUBLE d);
GRADIENT Deriv (DOUBLE d);
GRADIENT
GRADIENT
GRADIENT
GRADIENT
Add
Sub
Mul
Div
(GRADIENT
(GRADIENT
(GRADIENT
(GRADIENT
a,
a,
a,
a,
GRADIENT
GRADIENT
GRADIENT
GRADIENT
b);
b);
b);
b);
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
/******************************************
* Gradient.c: Automatische Differentiation
*******************************************/
#include "Portab.h"
#include "Gradient.h"
GRADIENT Const (DOUBLE d)
{
GRADIENT r;
r.x = d;
[Link] = 0.0;
return (r);
} /* Const */
GRADIENT Deriv (DOUBLE d)
{
GRADIENT r;
r.x = d;
[Link] = 1.0;
return (r);
} /* Deriv */
GRADIENT Add (GRADIENT a, GRADIENT b)
/* (a, a) + (b, b) = (a+b, a+b) */
{
GRADIENT r;
r.x = a.x + b.x;
[Link] = [Link] + [Link];
return (r);
} /* Add */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
/* todo: Sub */
GRADIENT Mul (GRADIENT a, GRADIENT b)
/* (a, a) * (b, b) = (a*b, a*b+a*b) */
{
GRADIENT r;
r.x = a.x * b.x;
[Link] = [Link] * b.x + a.x * [Link];
return (r);
} /* Mul */
/* todo: Div */
GRADIENT Exp (GRADIENT a)
/* exp (a, a) = (exp(a), exp(a) * a) */
{
GRADIENT r;
r.x = exp (a.x);
[Link] = exp (a.x) * [Link];
return (r);
} /* Exp */
GRADIENT Sin (GRADIENT a)
/* sin (a, a) = (sin(a), cos(a) * a) */
{
GRADIENT r;
r.x = sin (a.x);
[Link] = cos (a.x) * [Link];
return (r);
} /* Sin */
/* todo: Cos */
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Rechenzentrum
Einfhrung in C
Dirk Husung
FORTRAN
INTEGER i
long int i;
REAL x
float x;
DOUBLE PRECISION s double s;
COMPLEX*8 z
struct {float re, im;} z;
COMPLEX*16 w
struct {double r, i; } w;
CHARACTER*6 c
char c[6];
Argumentbergabe
In Fortran werden Argument stets by reference bergeben. Hierbei erhlt das aufgerufene Unterprogramm die Adresse der bergebenen Variable.
In C hingegen werden Argumente stets by value bergeben. Das Unterprogramm erhlt nur
eine Kopie mit dem aktuellen Wert des Arguments, kann so jedoch nicht den Argumentwert
selbst verndern (hierzu mte die Adresse bekannt sein).
Um in C Adressen zu bergeben, benutzt man
den Operator & vor dem Variablennamen.
FORTRAN
INTEGER a, b, sum
int a, b, sum;
call add (a, b, sum) add (&a, &b, &sum);
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
CHARACTER*5 sss
char sss[5];
CHARACTER*8 tt
char tt[8];
call sub (sss, tt) sub (sss, tt, 5L, 8L);
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispiel:
/******************************************
* C-Programm: fprog1.c
*******************************************/
#include <stdio.h>
#if defined (HP)
#define SUBROUTINE(Name) Name
#elif defined (CONVEX)
#define SUBROUTINE(Name) Name_
#endif
float fkt (float *x);
void SUBROUTINE(fkt_uebergabe) (
float *x, float (*f)(float *), float *y);
int main(void)
{
float x=2.0; float y=0.0;
printf ("\n Funktionsname als Argument:\n");
SUBROUTINE(fkt_uebergabe) (&x, fkt, &y);
printf (" x= %g, fkt(x) = %g\n", x, y);
return (0);
}
/******************************************
* C-Programm: fprog2.c
*******************************************/
float fkt(float *x)
{
return(2.0* *x);
}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
1
a+2
[expr $a+2]
a
Ausdrcke:
expr 24/3.2
lindex {rot gelb blau lila} 2
string length "Dies ist ein Test"
Substitutionen:
Variablenersetzung
Befehlsersetzung
Backslash-Substitution
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Kontrollstrukturen:
eval
expr
if
elseif
switch
for
foreach
while
Prozeduren:
proc Potenz {Basis Exponent} {
set Ergebnis 1
while {$Exponent > 0} {
set Ergebnis [expr $Ergebnis*$Basis]
set Exponent [expr $Exponent-1]
}
return $Ergebnis
}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Beispiele
Hello, World:
#!/usr/local/bin/wish -f
button .b -text "Hello, world!" -command exit
pack .b
Potenzberechnung:
#!/usr/local/bin/wish -f
proc Potenz {Basis Exponent} {
set Ergebnis 1
while {$Exponent > 0} {
set Ergebnis [expr $Ergebnis*$Basis]
set Exponent [expr $Exponent-1]
}
return $Ergebnis
}
entry .basis -width 6 -relief sunken\
-textvariable Basis
label .label1 -text "ist in der"
entry .exponent -width 6 -relief sunken\
-textvariable Exponent
label .label2 -text ". Potenz"
label .ergebnis -textvariable Ergebnis
pack .basis .label1 .exponent .label2\
.ergebnis -side left -padx 1m -pady 2m
bind .basis <Return> {
set Ergebnis [Potenz $Basis $Exponent]}
bind .exponent <Return> {
set Ergebnis [Potenz $Basis $Exponent]}
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
Tcl/Tk und C:
/********************************************
* $Id: draw.c
Tcl/Tk-Beispiel
*********************************************/
#include <stdio.h>
#include <tcl.h>
#include <tk.h>
/********************************************
* Variablen-Definitionen
*********************************************/
static Tcl_Interp * interp;
/********************************************
* Prototypen lokaler Funktionen
*********************************************/
static void tcltkInit (
int nArgs, char * aArg []);
static void tcltkTerm (void);
static int drawLine (
int x0, int y0, int x1, int y1);
/********************************************
* Implementierung lokaler Funktionen
*********************************************/
static void tcltkInit (
int
nArgs,
char *
aArg [])
{
char * pArg;
char
ach [16];
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung
TUHH
Rechenzentrum
Einfhrung in C
Dirk Husung