![]() |
Programmieren in Cvon Prof. Dr. Rainer Thomas |
z.B. printf("Hallo !\n"); /* eine Ausdrucksanweisung ! */
In diesem Fall wird der Funktionswert ignoriert.
Funktionen, die keinen Wert zurückgeben (Funktionen
vom Typ void), lassen sich nur in dieser Form der Ausdrucksanweisung
anwenden.
z.B. darf ein aktueller int-Wert für einen formalen double-Parameter übergeben werden
| --> | Die Ausnutzung von Seiteneffekten in den aktuellen Parameterausdrücken
sollte unterbleiben.
z.B. c=power(a=2,a+3); Abhängig von der vom Compiler verwendeten Auswertungsreihenfolge werden verschiedene Werte als aktuelle Parameter übergeben. |
Der Modifizierer pascal legt für die betreffende Funktion
die PASCAL-Konvention der Parameterübergabe fest.
Diese Funktion kann in C oder in einer anderen Sprache geschrieben
sein. z.B. void pascal tsort(int *ifeld, unsigned laenge);
Da mittels eines Compilerschalters ein gesamtes C-Modul gemäß der PASCAL-Konvention übersetzt werden kann, wurde der Modifizierer cdecl zur expliziten Festlegung der C-Konvention für einzelne Funktionen eingeführt (z.B. notwendig für Extern-Deklarationen von C-Bibliotheksfunktionen).
#include <stdio.h>
void main(void)
{ int a=23,b=47,c;
int add(int, int);
c=add(a,b);
printf("\n%d\n",c);
}
int add(int z1, int z2)
{ int z3;
z3=z1+z2;
return (z3);
}
_main proc near push bp mov bp,sp sub sp,6 ; Platz für lokale Variable mov word ptr [bp-2],23 ; lokale Variable a mov word ptr [bp-4],47 ; lokale Variable b push word ptr [bp-4] ; Parameter b (z2) --> Stack push word ptr [bp-2] ; Parameter a (z1) --> Stack call near ptr _add pop cx ; Entfernung Parameter pop cx ; vom Stack mov word ptr [bp-6],ax ; Funktionswert --> c push word ptr [bp-6] ; 2. Par. für printf (c) --> Stack mov ax,offset DGROUP:s@ push ax ; 1. Par. für printf --> Stack call near ptr _printf pop cx ; Entfernung Parameter pop cx ; vom Stack mov sp,bp pop bp ret _main endp _add proc near push bp mov bp,sp sub sp,2 ; Platz für lokale Variable z3 mov ax,word ptr [bp+4] ; Zugriff zu Parameter z1 add ax,word ptr [bp+6] ; Zugriff zu Parameter z2 mov word ptr [bp-2],ax ; Additionsergebnis --> z3 mov ax,word ptr [bp-2] ; Funktionswert --> AX mov sp,bp pop bp ret _add endp
#include <stdio.h>
void main(void)
{ int a=23,b=47,c;
int pascal add(int, int);
c=add(a,b);
printf("\n%d\n",c);
}
int pascal add(int z1, int z2)
{ int z3;
z3=z1+z2;
return (z3);
}
_main proc near push bp mov bp,sp sub sp,6 ; Platz für lokale Variable mov word ptr [bp-2],23 ; lokale Variable a mov word ptr [bp-4],47 ; lokale Variable b push word ptr [bp-2] ; Parameter a (z1) --> Stack push word ptr [bp-4] ; Parameter b (z2) --> Stack call near ptr ADD ; keine Parameterentfernung ! mov word ptr [bp-6],ax ; Funktionswert --> c push word ptr [bp-6] ; 2. Par. für printf (c) --> Stack mov ax,offset DGROUP:s@ push ax ; 1. Par. für printf --> Stack call near ptr _printf pop cx ; Entfernung Parameter pop cx ; vom Stack mov sp,bp pop bp ret _main endp ADD proc near push bp mov bp,sp sub sp,2 ; Platz für lokale Variable z3 mov ax,word ptr [bp+6] ; Zugriff zu Parameter z1 add ax,word ptr [bp+4] ; Zugriff zu Parameter z2 mov word ptr [bp-2],ax ; Additionsergebnis --> z3 mov ax,word ptr [bp-2] ; Funktionswert --> AX mov sp,bp pop bp ret 4 ; Rückspr. u. Parameterentfernung ADD endp
void pr_reverse(char s[])
{ int i;
for (i=strlen(s)-1; i>=0; i--) putchar(s[i]);
}
/* ------------------------------------------------------------------ */
/* Programm AUFADD */
/* ------------------------------------------------------------------ */
/* Einfacher "Taschenrechner" */
/* Addition zeilenweise eingegebener u.U. negativer Realzahlen, */
/* Ausgabe der jeweiligen Teilsumme nach jeder Eingabe, */
/* Ende bei leerer Eingabe */
/* ------------------------------------------------------------------ */
#include <stdio.h>
#define MAXCHAR 136
void main(void)
{ double AzuF(char []);
int GetLine(char [], int);
double dSumme=0;
char acZeile[MAXCHAR+1];
while (printf("? "), GetLine(acZeile,MAXCHAR)>0)
printf("= %f\n",dSumme+=AzuF(acZeile));
}
int GetLine(char acZl[],int iMax) /* Einlesen einer zeile von stdin */
/* nach acStr (ohne NL) */
{ int iNextZeich, i=0; /* Funktionswert=Zeilenlaenge */
while(--iMax>=0 && (iNextZeich=getchar())!=EOF && iNextZeich!='\n')
acZl[i++]=iNextZeich;
acZl[i]='\0';
if (i==0 && iNextZeich==EOF) return(-1);
else return (i);
}
double AzuF(char acStr[]) /* string s --> double */
{ double dWert, dBruch=0, dSkalFakt=1;
int iSign=1, i;
for (i=0; acStr[i]==' ' || acStr[i]=='\t'; i++);
if (acStr[i]=='-')
{ iSign=-1; i++; }
else
if (acStr[i]=='+') i++;
for (dWert=0; acStr[i]>='0' && acStr[i]<='9'; i++)
dWert=10*dWert+acStr[i]-'0';
if (acStr[i]=='.') i++;
for ( ; acStr[i]>='0' && acStr[i]<='9'; i++)
{ dBruch=dBruch*10+acStr[i]-'0';
dSkalFakt*=10;
}
return iSign*(dWert + dBruch/dSkalFakt);
}
/* ------------------------------------------------------------------ */
Bildschirmausgabe :
E:\RT\C\VORL>aufadd? 23.5 = 23.500000 ? +12.3 = 35.800000 -5.9 = 29.900000 ?
|
|
Lokales Objekt :
Globale Objekte - also damit auch alle Funktionen - "leben" grundsätzlich
während der gesamten Programmlaufzeit.
Lokale Objekte (immer Variable !) können sowohl eine Programmlaufzeit-
Lebensdauer als auch eine auf die Block-Ausführungszeit begrenzte
Lebensdauer haben.
*) nur mit Initialisierung
| Verfügbarkeitsbereich | : | gesamtes Programm |
| Lebensdauer | : | Programmlaufzeit |
| Speicherort | : | normaler Arbeitsspeicher
(für Variable : Datensegment) |
| Default-Initialisierung | : | mit 0 |
| explizite Initialisierung | : | mit konstantem Ausdruck (durch Compiler) |
| Verfügbarkeitsbereich | : | Block, in dem definiert |
| Lebensdauer | : | Block-Ausführungszeit |
| Speicherort | : | Stack |
/* ----------------------------------------------------------------- */
/* Programm EXTDEM */
/* ----------------------------------------------------------------- */
/* Demonstrationsprogramm zur Extern-Deklaration von Variablen und */
/* Funktionen */
/* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */
/* Source-File #1 */
/* ----------------------------------------------------------------- */
#include <stdio.h>
void main(void)
{ extern int i; /* Extern-Deklaration von i */
void next(void); /* Vorwärts-Deklaration von next() */
printf("\n%d\n",++i);
next();
}
int i=3; /* Definition von i mit Initialisierung */
void next(void)
{ /* Extern-Deklaration von i nicht notwendig */
extern void other(void); /* Extern-Deklaration von other() */
printf("%d\n",++i);
other();
}
/* ----------------------------------------------------------------- */
/* ----------------------------------------------------------------- */
/* Source-File #2 */
/* ----------------------------------------------------------------- */
#include <stdio.h>
extern int i; /* Extern-Deklaration von i */
void other(void)
{ /* Extern-Deklaration von i koennte auch
hier stehen */
printf("%d\n",++i);
}
/* ----------------------------------------------------------------- */
Bildschirmausgabe :
E:\RT\C\VORL>extdem 4 5 6
| Verfügbarkeitsbereich | : | Block, in dem definiert; wenn statisch-lokal
Modul,in dem definiert; wenn statisch-global |
| Lebensdauer | : | Programmlaufzeit |
| Speicherort | : | normaler Arbeitsspeicher (Datensegment) |
/* ------------------------------------------------------------------ */
/* Programm LSTATDEM */
/* ------------------------------------------------------------------ */
/* Demonstrationsprogramm zu statisch-lokalen Variablen */
/* ------------------------------------------------------------------ */
#include <stdio.h>
void IncStatic(void)
{
static int i=0;
printf("%d\n",++i);
}
void IncAuto(void)
{
int i=0;
printf("%d\n",++i);
}
void main(void)
{
printf("\nIncrement statisch-lokale Variable:\n\n");
IncStatic();
IncStatic();
IncStatic();
printf("\nIncrement auto-Variable:\n\n");
IncAuto();
IncAuto();
IncAuto();
}
/* ------------------------------------------------------------------ */
Bildschirmausgabe :
E:\RT\C\VORL>lstatdem Increment statisch-lokale Variable: 1 2 3 Increment auto-Variable: 1 1 1
/*--------------------------------------------------------------------*/
/* Source-File #1 */
/*--------------------------------------------------------------------*/
/* Modul ZAHLFOLG */
/*--------------------------------------------------------------------*/
/* Initialisierung und Erzeugung von Werten einer Zahlenfolge */
/*--------------------------------------------------------------------*/
#define OFFSET 23
static int zahl;
int zahl_next(void) /* Erzeugung des naechsten Wertes der Folge */
{
zahl=zahl+OFFSET;
return zahl;
}
void zahl_init(int start) /* Festlegung des Startwerts der Folge */
{
zahl=start-OFFSET;
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Source-File #2 */
/*--------------------------------------------------------------------*/
/* Program GSTATDEM */
/* -------------------------------------------------------------------*/
/* Demonstrationsprogramm zu statisch-globalen Variablen */
/* Erzeugung einer Zahlenfolge */
/* Verwendung des Moduls ZAHLFOLG */
/* -------------------------------------------------------------------*/
#include <stdio.h>
void main(void)
{
extern void zahl_init(int);
extern int zahl_next(void);
int start, anzahl;
printf("\nErzeugung einer Zahlenfolge\n");
printf("\nStartwert und Anzahl ? ");
scanf("%d%d", &start, &anzahl);
zahl_init(start);
for (;anzahl>0;anzahl--)
printf("\n%d",zahl_next());
putchar('\n');
}
/*--------------------------------------------------------------------*/
| Verfügbarkeitsbereich | : | Block, in dem definiert |
| Lebensdauer | : | Block-Ausführungszeit |
| Speicherort | : | CPU-Register (wenn möglich) |
/* Programm RVTEST1 */
/* Schleifenvariable hat die */
/* Speicherklasse register */
#include <stdio.h>
void main(void)
{ int r1=75;
int r2=25;
int a=0, b=r1+r2;
register int i;
for (i=1;i<=b;i++)
a+=i;
printf("\nErgebnis : %d\n",a);
}
_main proc near
push bp
mov bp,sp
sub sp,8
push si
mov word ptr [bp-2],75 ;r1
mov word ptr [bp-4],25 ;r2
mov word ptr [bp-6],0 ;a
mov ax,word ptr [bp-2]
add ax,word ptr [bp-4]
mov word ptr [bp-8],ax ;b
mov si,1 ;i
jmp short @1@114
@1@58:
add word ptr [bp-6],si
inc si
@1@114:
cmp si,word ptr [bp-8]
jle short @1@58
push word ptr [bp-6]
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
pop cx
pop si
mov sp,bp
pop bp
ret
_main endp
|
/* Programm RVTEST2 */
/* Schleifenvariable hat die */
/* Speicherklasse auto */
#include <stdio.h>
void main(void)
{ int r1=75;
int r2=25;
int a=0, b=r1+r2;
int i;
for (i=1;i<=b;i++)
a+=i;
printf("\nErgebnis : %d\n",a);
}
_main proc near
push bp
mov bp,sp
sub sp,10
mov word ptr [bp-2],75 ;r1
mov word ptr [bp-4],25 ;r2
mov word ptr [bp-6],0 ;a
mov ax,word ptr [bp-2]
add ax,word ptr [bp-4]
mov word ptr [bp-8],ax ;b
jmp short @1@114
@1@58:
mov ax,word ptr [bp-10]
add word ptr [bp-6],ax
inc word ptr [bp-10]
@1@114:
mov ax,word ptr [bp-10]
cmp ax,word ptr [bp-8]
jle short @1@58
push word ptr [bp-6]
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
pop cx
mov sp,bp
pop bp
ret
_main endp
|
keine Blockschachtelung
(Funktionen können nicht innerhalb von Funktionen definiert werden)
nur nebeneinanderliegende gleichberechtigte Blöcke.
Da zu Beginn jeder Verbundanweisung
(=Block) und damit auch zu Beginn jedes Funktionsrumpfes Variablendefinitionen
stehen können ist eine beliebige Blockschachtelung möglich.
Namenskonflikte (= gleiche Namen) zwischen Variablen in ineinandergeschachtelten Blöcken werden folgendermaßen gelöst:
/* ------------------------------------------------------------------ */
/* Programm BLOCKDEM */
/* ------------------------------------------------------------------ */
/* Beispiel zur Blockstruktur */
/* ------------------------------------------------------------------ */
#include <stdio.h>
int x=10;
void main(void)
{
int x=20, i;
void weiter(void);
printf("\nmain : x = %d\n\n",x);
for (i=0; i<4; i++)
{ int x=30;
static int y=30;
printf("for : x = %d y = %d\n",x++,y++);
}
weiter();
}
void weiter(void)
{
int y=40;
printf("\nweiter : x = %d y = %d\n",x,y);
}
/* ------------------------------------------------------------------ */
Bildschirmausgabe :
E:\RT\C\VORL>blockdem main : x = 20 for : x = 30 y = 30 for : x = 30 y = 31 for : x = 30 y = 32 for : x = 30 y = 33 weiter : x = 10 y = 40
Statisch-lokale Variable werden dagegen nicht jedesmal
neu angelegt.
Sie existieren nur einmal und sind in allen Inkarnationen zugänglich.
Die Abbruchbedingung muß durch wenigstens eine Variable gesteuert
werden, mit der Information von einer Funktionsinkarnation zur nächsten
übergeben wird.
Hierfür läßt sich eine lokale statische Variable
oder ein Parameter ein- setzen.
unsigned fac(unsigned n)
{
if (n==0) /* Abbruchbedingung */
return(1);
else
return(n*fac(n-1));
}
/* ------------------------------------------------------------------ */
/* Programm DEZDUAL2 */
/* ------------------------------------------------------------------ */
/* Modifikation des Programms DEZDUAL zur Dezimal-Dualwandlung */
/* positiver ganzer Zahlen */
/* */
/* Ausgabe einer positiven Integerzahl als Dualzahl ohne Zwischen- */
/* speicherung der ermittelten Dualziffern */
/* Einsatz einer rekursiven Funktion */
/* ------------------------------------------------------------------ */
#include <stdio.h>
#define BASIS 2
void printdual(unsigned i)
{
unsigned zahl;
if ((zahl=i/BASIS) != 0)
printdual(zahl);
putchar(i%BASIS + '0');
return;
}
void main(void)
{
unsigned zahl;
printf("\npositive ganze Dezimalzahl ? ");
scanf("%d",&zahl);
printf("\numgewandelt in Dualzahl : ");
printdual(zahl);
putchar('\n');
}
/* ------------------------------------------------------------------ */
Bildschirmanzeige :
E:\RT\C\VORL>dezdual2 positive ganze Dezimalzahl ? 135 umgewandelt in Dualzahl : 10000111
Mit ANSIISO-C wurde nicht nur die Sprache C selbst sondern auch
eine Standard-Bibliothek genormt.
Eine ausschließliche Verwendung von Standard-Bibliotheks-Funktionen
erleichert stark die Portabilität eines C-Programms.
| <assert.h> | Deklaration einer Diagnose-Funktion bzw. Definition eines die Funktion ersetzenden Makros |
| <ctype.h> | Deklaration von Funktionen zum Zeichenklassentest bzw. Definition ersetzender Makros |
| <errno.h> | Deklaration der System-Fehlervariablen und Definition von System-Fehlercodes |
| <float.h> | Definition gleitkommaarithmetikbezogener Konstanten |
| <iso646.h> | Definition von Ersatzdarstellungen einiger Operatorsymbole |
| <limits.h> | Definition von Konstanten zur Beschreibung des Wertebereichs der Ganzzahl-Typen |
| <locale.h> | Definition von Konstanten und eines Typs sowie Deklaration von Funktionen zur Auswahl länderspezifischer Darstellungen |
| <math.h> | Deklaration mathematischer Funktionen |
| <setjmp.h> | Deklaration von Funktionen zur Ermöglichung nicht-lokaler Sprünge |
| <signal.h> | Definition von Konstanten und Deklaration von Funktionen zur Exception-Behandlung |
| <stdarg.h> | Definition von Typen und Makros zum Zugriff zu einer variablen Parameterliste |
| <stddef.h> | Definition einiger Typen und der Konstanten NULL, sowie Deklaration der System-Fehlervariablen errno |
| <stdio.h> | Definition von Konstanten und Typen, sowie Deklaration von Funktionen zur Ein- und Ausgabe |
| <stdlib.h> | Definition von Konstanten und Typen, sowie Deklaration diverser Utility-Funktionen
(z.B. String-Konvertierungsfunktionen, Speicherverwaltungsfunktionen, Environment-Funktionen, Such- und Sortier-Funktionen, Integer-Arithmetik-Funktionen, Multibyte-Zeichen-Funktionen) |
| <string.h> | Deklaration von Funktionen zur Stringbearbeitung und Speicherbearbeitung |
| <time.h> | Definition von Konstanten und Typen, sowie Deklaration von Zeit- und Datums-Funktionen |
| <wchar.h> | Definition von Konstanten und Makros sowie Deklaration von Funktionen zur Bearbeitung von "wide characters" (Ein-/Ausgabe, Stringbearbeitung) |
| <wctype.h> | Deklaration von Funktionen zum Test und Klassifizieren von "wide characters" |
| int fclose(FILE *fp); | Schließen einer Datei | |
| int fflush(FILE *fp); | Herausschreiben eines Dateipuffers | |
| int fgetpos(FILE *fp, fpos_t *ptr); | Ermitteln der aktuellen Bearbeitungsposition | |
| FILE *fopen(char *path, char *mode); | Öffnen einer Datei | |
| FILE *freopen(char *path, char *mode, FILE *fp); | Erneutes Öffnen einer offenen Datei | |
| int fseek(FILE *fp, long offs, int org); | Verändern der Bearbeitungsposition | |
| int fsetpos(FILE *fp, fpos_t *ptr); | Verändern der Berabeitungsposition | |
| long ftell(FILE *fp); | Ermitteln der aktuellen Bearbeitungsposition | |
| void rewind(FILE *fp); | Zurücksetzen auf den Dateianfang | |
| void setbuf(FILE *fp, char *buf); | Bereitstellen eines benutzerdefinierten Dateipuffers | |
| int setvbuf(FILE *fp, char *buf, int mode, size_t size); | Bereitstellen eines benutzerdefinierten Dateipuffers |
| int remove(char *path); | Löschen einer Datei |
| int rename(char *oldpath, char *newpath); | Umbenennen einer Datei |
| FILE *tmpfile(void); | Erzeugen und Öffnen einer temporären Datei |
| char *tmpnam(char s[L_tmpnam]); | Erzeugen eines noch nicht vorhandenen Dateinamens |
| void clearerr(FILE *fp); | Rücksetzen des Fehler- und des EOF-Flags |
| int feof(FILE *fp); | Überprüfung des EOF-Flags |
| int ferror(FILE *fp); | Überprüfung des Fehler-Flags |
| void perror(char *s); | Ausgabe von Fehlermeldungen nach stderr |
| int getchar(void); | zeichenweise Eingabe von stdin |
| char *gets(char *s); | zeilenweise Eingabe von stdin |
| int printf(char *ctrl, ...); | formatierte Ausgabe nach stdout |
| int putchar(int c); | zeichenweise Ausgabe nach stdout |
| int puts(char *s); | zeilenweise Ausgabe nach stdout |
| int scanf(char *ctrl, ...); | formatierte Eingabe von stdin |
| int vprintf(char *ctrl, va_list arg); | formatierte Ausgabe nach stdout |
| int fgetc(FILE *fp); | zeichenweise Eingabe |
| char *fgets(char *s, int n, FILE *fp); | zeilenweise Eingabe |
| int fprintf(FILE *fp, char *ctrl, ...); | formatierte Ausgabe |
| int fputc(int c, FILE *fp); | zeichenweise Ausgabe |
| int fputs(char *s, FILE *fp); | stringweise Ausgabe |
| size_t fread(void *ptr, size_t size, size_t count, FILE *fp); | datenobjektorientierte Eingabe |
| int fscanf(FILE *fp, char *ctrl, ...); | formatierte Eingabe |
| size_t fwrite(void *ptr, size_t size, size_t count, FILE *fp); | datenobjektorientierte Ausgabe |
| int getc(FILE *fp); | zeichenweise Eingabe |
| int putc(int c, FILE *fp); | zeichenweise Ausgabe |
| int ungetc(int c, FILE *fp); | Rückgabe eines Zeichens in Eingabepuffer |
| int vfprintf(FILE * fp, char *ctrl, va_list arg); |
| int sprintf(char *s, char *ctrl, ...); | format. Ausgabe in einen String |
| int sscanf(char *s, char *ctrl, ...); | format. Eingabe aus einem String |
| int vsprintf(char *s, char *ctrl, va_list arg); | format. Ausgabe in einen String |
in das Quellmodul eingebunden werden.
| int isalnum(int c); | Überprüfung auf Buchstabe (Groß- oder Klein-) der (Dezimal-)Ziffer |
| int isalpha(int c); | Überprüfung auf Buchstabe (Groß- oder Klein-) |
| int iscntrl(int c); | Überprüfung auf Steuerzeichen |
| int isdigit(int c); | Überprüfung auf (Dezimal-)Ziffer |
| int isgraph(int c); | Überprüfung auf darstellbare Zeichen, ausgenommen BLANK (SPACE) |
| int islower(int c); | Überprüfung auf Klein-Buchstaben |
| int isprint(int c); | Überprüfung auf darstellbare Zeichen, einschließlich BLANK (SPACE) |
| int ispunct(int c); | Überprüfung auf darstellbare Zeichen, ausgenommen BLANK, Buchstaben und (Dezimal-)Ziffern |
| int isspace(int c); | Überprüfung auf BLANK (SPACE), FF, NEWLINE, CR, HT und VT |
| int isupper(int c); | Überprüfung auf Groß-Buchstaben |
| int isxdigit(int c); | Überprüfung auf Seddezimal-Ziffer |
| int tolower(int c); | Umwandlung von Groß- in Klein-Buchstaben |
| int toupper(int c); | Umwandlung von Klein- in Groß-Buchstaben |
| void *memcpy(void *s1, const void *s2, size_t n); | Kopieren von n Zeichen vom Array s2 in das Array s1 |
| void *memmove(void *s1, const void *s2, size_t n); | Kopieren von n Zeichen vom Array s2 in das Array s1
(Überlappung ist zulässig) |
| char *strcpy(char *s1, const char *s2); | Kopieren des Strings s2 in den String s1. |
| char *strncpy(char *s1, const char *s2, size_t n); | Kopieren von maximal n Zeichen vom String s2 in den String s1
(ggfls kein Abschluß mit '\0') |
| char *strcat(char *s1, const char *s2); | Anhängen von String s2 an den String s1 |
| char *strncat(char *s1, const char *s2, size_t n); | Anhängen von maximal n Zeichen des Strings s2 an den Str. s1
(Abschluß immer mit '\0') |
| int memcmp(const void *s1, const void *s2, size_t n); | zeichenweiser Vergleich der Arrays s1 und s2 (max. n Zeichen) |
| int strcmp(const char *s1, const char *s2); | Vergleich der Strings s1 und s2 |
| int strncmp(const char *s1, const char *s2, size_t n); | Vergleich der Strings s1 und s2 (max. n Zeichen) |
| int strcoll(const char *s1, const char *s2); | Vergleich der Strings s1 und s2 gemäß dem mit setlocale() festgelegten länderspezifischen Zeichencode |
| size_t strxfrm(char *s1, const char *s2, size_t n); | Code-Transformation von maximal n Zeichen des Strings s2 in den String
s1
(Quellcode : länderspezifisch Zielcode : der von strcmp() verwendete Zeichencode) |
| void *memchr(const void *s, int c, size_t n); | Durchsuchen von max n Zeichen des Arrays s nach dem ersten Auftritt des Zeichens c |
| char *strchr(const char *s, int c); | Durchsuchen des Strings s nach dem ersten Auftreten des Zeichens c |
| char *strrchr(const char *s, int c); | Durchsuchen des Strings s nach dem letzten Auftreten des Zeichens c |
| char *strpbrk(const char *s1, const char *s2); | Durchsuchen des Strings s1 nach dem ersten Auftreten irgendeines der im String s2 enthaltenen Zeichen |
| char *strstr(const char *s1, const char *s2); | Durchsuchen des Strings s1 nach dem ersten Auftreten des Strings s2 |
| size_t strspn(const char *s1, const char *s2); | Ermittlung der Länge des Teilstrings von s1, der nur aus in s2 enthaltenen Zeichen besteht |
| size_t strcspn(const char *s1, const char *s2); | Ermittlung der Länge des Teilstrings von s1, der nur aus in s2 nicht enthaltenen Zeichen besteht |
| char *strtok(char *s1, const char *s2); | Zerlegen des Strings s1 in die Teilstrings, die durch im String s2 enthaltene Zeichen getrennt werden |
| void *memset(void *s, int c, size_t n); | Ablage des Zeichens c in n aufeinanderfolgende Elemente des (char-) Arrays s |
| size_t strlen(const char *s); | Ermittlung der Länge des Strings s |
| char *strerror(int errnum); | Ermittlung der Fehlermeldung, die zur Fehlernummer errnum gehört |
/* -------------------------------------------------------------------- */ /* strtok - Zerlegung eines Strings in Teilstrings */ /* -------------------------------------------------------------------- */ #include <string.h> /* enthaelt Funktionsdeklaration */ char *strtok(char *str1, const char *str2); /* str1 zu zerlegender String */ /* str2 String, der die für die Zerlegung maßgeblichen Trennzeichen enthält */"strtok" wird üblicherweise mehrfach aufgerufen.
Beim ersten Aufruf durchsucht "strtok" den String "str1" nach dem ersten
nicht im String "str2" enthaltenen Zeichen.
Dieses Zeichen ist der Beginn des ersten Teilstrings ("token").
Besteht "str1" nur aus Zeichen, die auch in "str2" enthalten sind, so gibt es keinen Teilstring und die Funktion wird mit dem NULL-Pointer als Funktionswert beendet.
Wird jedoch ein nicht in "str2" enthaltenes Zeichen gefunden, so sucht
die Funktion in "str1" das nächste in "str2" enthaltene Zeichen (d.h.
das nächste Trennzeichen).
Dieses wird durch den NULL-Character ersetzt (der String "str1" wird
also verändert !), womit der Teilstring abgeschlossen ist.
In einer lokalen statischen Variablen merkt sich die Funktion dann
einen Pointer auf das nächste Zeichen in "str1".
Anschließend wird die Funktion mit dem Pointer auf den Beginn
des Teil- strings als Funktionswert beendet.
Bei jedem folgenden Aufruf, mit dem der nächste Teilstring ermittelt
werden soll, muß der Funktion der NULL-Pointer als aktueller Parameter
für "str1" übergeben werden.
Die Funktion durchsucht dann den "str1" ab der intern gemerkten Position
nach dem nächsten Teilstring.
Wird ein derartiger Teilstring gefunden, so gibt die Funktion wiederum
einen Pointer auf seinen Beginn als Funktionswert zurück.
Wird kein weiterer Teilstring mehr gefunden, so kehrt die Funktion
mit dem NULL-Pointer als Funktionswert zurück.
/*---------------------------------------------------------------*/
/* Programm TOKTEST */
/*---------------------------------------------------------------*/
/* Demonstrationsprogramm zur Funktion strtok() */
/* Zerlegung eines einzugebenden Satzes in einzelne Worte */
#include <string.h>
#include <stdio.h>
#define MAX 132
#define TRENNER " ,.;:!?-\n"
void main(void)
{
char satz[MAX];
char *token;
printf("\nSatz ? ");
gets(satz);
token=strtok(satz,TRENNER);
while (token != NULL)
{ printf("\n%s",token);
token=strtok(NULL,TRENNER);
}
putchar('\n');
}
Bildschirmausgabe :
E:\RT\C>toktest Satz ? Frage: Was soll das, wenn Du nicht magst ? Frage Was soll das wenn Du nicht magst
/* -------------------------------------------------------------------- */ /* memcpy - Kopieren einer Zeichenfolge bestimmter Länge */ /* -------------------------------------------------------------------- */ #include <string.h> /* enthält Funktionsdeklaration */ void *memcpy(void *s1, const void *s2, size_t n); /* s1 Pointer auf Ziel-Datenobjekt (Zielzeichenfolge) */ /* (Speicherbereich in den kopiert wird) */ /* s2 Pointer auf Quell-Datenobjekt (Quellzeichenfolge) */ /* (Speicherbereich aus dem kopiert wird) */ /* n Anzahl der zu kopierenden Zeichen */"memcpy" kopiert "n" Zeichen aus dem durch "s2" referierten - als Zeichenfolge aufgefaßten - Datenobjekt (Quell-Speicherbereich) in das durch "s1" referierte - als Zeichenfolge aufgefaßte - Datenobjekt (Ziel-Speicherbereich).
/* -------------------------------------------------------------------- */ /* memcmp - Vergleich zweier Zeichenfolgen bestimmter Länge */ /* -------------------------------------------------------------------- */ #include <string.h> /* enthält Funktionsdeklaration */ int *memcmp(const void *s1, const void *s2, size_t n); /* s1 Pointer auf erstes zu vergleichendes Datenobjekt */ /* (erste Zeichenfolge) */ /* s2 Pointer auf zweites zu vergleichendes Datenobjekt */ /* (zweite Zeichenfolge) */ /* n Anzahl der zu vergleichenden Zeichen */"memcmp" vergleicht die ersten n Zeichen des durch "s1" referierten - als Zeichenfolge aufgefaßten - Datenobjekts lexikographisch mit dem durch "s2" referierten - als Zeichenfolge aufgefaßten - Datenobjekts.
/* -------------------------------------------------------------------- */ /* memchr - Suchen eines Zeichens in einer Zeichenfolge best. Länge */ /* -------------------------------------------------------------------- */ #include <string.h> /* enthält Funktionsdeklaration */ void *memchr(const void *s, int c, size_t n); /* s Pointer auf zu durchsuchendes Datenobjekt */ /* (zu durchsuchende Zeichenfolge) */ /* ( = Speicherbereich, der durchsucht wird) */ /* c Zeichen, nach dem gesucht wird */ /* n Anz. der bei der Suche zu berücksichtigen Zeichen */ /* ( = Länge der zu durchsuchenden Zeichenfolge) */"memchr" durchsucht die ersten "n" Zeichen des durch "s%quot; referierten - als Zeichenfolge aufgefaßten - Datenobjekts nach dem ersten Auftritt des - in unsigned char umgewandelten - Zeichens "c".
/* -------------------------------------------------------------------- */ /* memset - Füllen eines Speicherbereichs mit einem Zeichen */ /* -------------------------------------------------------------------- */ #include <string.h> /* enthält Funktionsdeklaration */ void *memset(void *s, int c, size_t n); /* s Pointer auf den zu füllenden Speicherbereich */ /* c Zeichen, mit dem der Speicherbereich gefüllt wird */ /* n Anzahl der Zeichen des zu füllenden Speicherber. */"memset" setzt die ersten "n" Zeichen des durch "s" referierten Speicherbereichs auf den Wert des - in unsigned char umgewandelten - Zeichens c
In dieser sind weiterhin die folgenden Typen und Konstanten definiert:
| Typ | div_t | ein Structure-Typ für den Funktionswert von div() |
| Typ | ldiv_t | ein Structure-Typ für den Funktionswert von ldiv() |
| Typ | size_t | der "natürliche" unsigned-Typ, d.h. der Typ, den der sizeof-Operator liefert |
| Typ | wchar_t | ein ganzzahliger Typ, dessen Wertebereich den größten vom
Compiler unterstützten Zeichensatz darstellen kann
(nur definiert, wenn die Funktionen zur Verarbeitung erweiterter Zeichensätze implementiert sind) |
| Konstante | EXIT_FAILURE | ein ganzzahliger Wert zur Kennzeichnung einer fehlerhaften Programmbeendigung
(Rückgabewert von exit()) |
| Konstante | EXIT_SUCCESS | ein ganzzahliger Wert zur Kennzeichnung einer erfolgreichen Programmbeendigung
(Rückgabewert von exit()) |
| Konstante | MB_CUR_MAX | ein positiver gannzahliger Wert, der angibt aus wieviel Bytes ein Multi-Byte-Character
maximal bestehen kann
(nur definiert, wenn die Funktionen zur Verarbeitung erweiterter Zeichensätze implementiert sind) |
| Konstante | RAND_MAX | der größte von rand() erzeugte Zufallswert (ganzzahlig) |
| double atof(const char *s); | Umwandlung des Strings s in einen double-Wert |
| int atoi(const char *s); | Umwandlung des Strings s in einen int-Wert |
| long atol(const char *s); | Umwandlung des Strings s in einen long-Wert |
| double strtod(const char *s, char **endp); | Umwandlung des Strings s in einen double-Wert,
Speicherung eines Pointers auf das erste nicht umgewandelte Zeichen von s in *endp (nur wenn endp != NULL) |
| long strtol(const char *s, char **endp, int base); | Umwandlung des Strings s in einen long-Wert mit der Basis base,
Speicherung eines Pointers auf das erste nicht umgewandelte Zeichen von s in *endp (nur wenn endp != NULL) |
| unsigned long strtoul(char *s, char **endp, int base); | Umwandlung des Strings s in einen unsigned long-Wert mit der Basis
base,
Speicherung eines Pointers auf das erste nicht umgewandelte Zeichen von s in *endp (nur wenn endp != NULL) |
| int rand(void); | Erzeugung einer ganzzahligen Pseudo-Zufallszahl im Bereich 0 .. RAND_MAX |
| void srand(unsigned int seed); | Setzen des Initialisierungswertes für die durch rand() erzeugte Zufallszahlenfolge (default : 1) |
| void *calloc(size_t nobj, size_t size); | Allokation eines Speicherblocks für nobj-Objekte jeder
Länge size,
Initialisierung aller Speicherplätze mit 0 |
| void free(void *p); | Freigabe des Speicherbereichs auf den p zeigt |
| void *malloc(size_t size); | Allokation eines Speicherblocks der Länge size (keine Initialisierung) |
| void *realloc(void *p, size_t size); | Änderung der Größe eines bereits vorher allokierten - durch p referierten Speicherblocks - auf den neuen Wert size |
| void abort(void); | Anormale Beendigung eines Programms |
| int atexit(void (*fcn)(void)); | Registrierung der Funktion (*fcn)() als eine Funktion, die bei Programmbeendigung mittels exit() aufgerufen wird |
| void exit(int status); | Normale Beendigung eines Programms |
| char *getenv(const char *name); | Ermittlung des zur Environment-Variablen name gehörenden Strings
(Wertder Environment-Variablen)
(implementierungsabhängig) |
| int system(const char *s); | Übergabe des - ein Kommando bedeutenden - Strings s an die Betriebssystem-Umgebung zur Ausführung |
| void *bsearch(const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)); | Durchsuchen eines in aufsteigender Ordnung sortierten -
durch base referierten - Feldes von n Objekten der Länge
size
auf Übereinstimmung mit dem Suchschlüssel *key.
Der Vergleich erfolgt mittels der Funktion (*cmp)() |
|
| void qsort(void *base, size_t n, size_t size, int (*cmp)(const void *, const void *)); | Sortieren des - durch base referierten - Feldes von n Objekten der Länge size in aufsteigender Ordnung mittels der Vergleichsfunktion (*cmp)() |
| int abs(int i); | Ermittlung des Absolutwertes von i (int-Wert) |
| div_t div(int dend, int disor); | Ermittlung des ganzzahligen Quotienten und des Restes der Division von dend durch disor (int-Werte) |
| long labs(long n); | Ermittlung des Absolutwertes von n (long-Wert) |
| ldiv_t ldiv(long dend, long disor); | Ermittlung des gannzahligen Quotienten und des Restes der Division von dend durch disor (long-Werte) |
/* -------------------------------------------------------------------- */ /* exit - Beendigung des Programms */ /* -------------------------------------------------------------------- */ #include <stdlib.h> /* enthält Funktionsdeklaration */ void exit(int status); /* status Rückgabewert des Programms (Return Code) */exit() beendet das laufende Programm (normale Beendigung).
/* -------------------------------------------------------------------- */ /* system - Ausführ. eines Programms/Kommandos durch das Betriebssystem*/ /* -------------------------------------------------------------------- */ #include <stdlib.h> /* enthält Funktionsdeklaration */ int system(const char *s); /* s String, der die Kommandozeile (Kommando einschließlich */ /* Parameter) darstellt */ /* (genauer : Pointer auf die Kommandozeile) */system() ruft den Kommandoprozessor des Betriebssystems auf und übergibt diesem die durch "s" referierte Kommandozeile zur Ausführung.
Funktionswert :
In <math.h> ist außerdem definiert :
| Makro | HUGE_VAL | double-Wert, der zur Kennzeichnung des Überschreitens des darstellbaren Wertebereichs dient (kann "unendlich" repräsentieren). |
/* -------------------------------------------------------------------- */ /* Trigonometrische und hyperbolische Funktionen */ /* -------------------------------------------------------------------- */ #include <math.h> /* enthält Funktionsdeklarationen */
| double acos(double x); | Arcus-Cosinus von x
-1 <= x <= 1 Funktionswert: [0 .. π] |
| double asin(double x); | Arcus-Sinus von x
-1 <= x <= 1 Funktionswert : [-π/2 .. π/2] Ý |
| double atan(double x); | Arcus-Tangens von x
Funktionswert : [-π/2 .. π/2] |
| double atan2(double y, double x); | Arcus-Tangens von y/x
Funktionswert : [-π .. π] Die Ermittlung des Quadranten,in dem der Funktionswert liegt, erfolgt unter Berücksichtigung des Vorzeichens beider Parameter |
| double cos(double x); | Cosinus von x |
| double cosh(double x); | Cosinus Hyperbolicus von x |
| double sin(double x); | Sinus von x |
| double sinh(double x); | Sinus Hyperbolicus von x |
| double tan(double x); | Tangens von x |
| double tanh(double x); | Tangens Hyperbolicus von x |
/* --------------------------------------------------------------------- */ /* Exponential- und logarithmische Funktionen */ /* --------------------------------------------------------------------- */ #include <math.h> /* enthält Funktionsdeklarationen */
| double exp(double x); | Exponentialfunktion "e hoch x" |
| double frexp(double x, int *ex); | Zerlegung von x in die normalisierte Darstellung
x = m * (2 ** n) mit 0.5 <= m < 1 Für x=0 : m=0 und n=0 m --> Funktionswert n --> Ablage in *ex |
| double ldexp(double x, int n); | Funktion x*(2**n) |
| double log(double x); | natürlicher Logarithmus ln(x), x>0 |
| double log10(double x); | dekadischer Logarithmus lg(x), x>0 |
| double modf(double x, int *ip); | Zerlegung von x in einen ganzzahligen und einen gebrochenen Teil
gebrochener Teil --> Funktionswert ganzzahl. Teil --> Ablage in *ip |
| double pow(double x, double y); | "x hoch y" |
| double sqrt(double x); | Positive Qaudratwurzel von x, x>=0 |
/* --------------------------------------------------------------------- */ /* Sonstige mathematische Funktionen */ /* --------------------------------------------------------------------- */ #include <math.h> /* enthält Funktionsdeklarationen */
| double ceil(double x); | kleinste ganze Zahl >= x |
| double fabs(double x); | Absolutwert von x |
| double floor(double x); | größte ganze Zahl <=x |
| double fmod(double x, double y); | Gleitpunkt-Rest der Division x/y
Funktionswert hat das Vorzeichen von x Falls y=0 --> Funktionswert implementierungsabhängig |
| Typ | va_list | Array-Typ geeignet zur Aufname der Informationen, die zur Beschaffung der Parameter benötigt werden |
| Macro | void va_start(va_list ap, last_parm); | Initialisierung der Variablen ap für die folgende Verwendung durch
va_arg()
und va_end().
last_parm ist der letzte feste Parameter der Funktion. Muß vor dem ersten Zugriff zur variablen Parameterliste aufgerufen werden |
| Macro | type va_arg(va_list ap, type); | Liefert als Wert den nächsten Parameter aus der Parameterliste,
für die ap initialisiert wurde.
Der angegebene Typ type muß der Typ des Parameters sein. |
| Function oder Macro | void va_end(va_list ap); | Abschluß des Zugriffs zu der variablen Parameterliste.
Durch den Aufruf von va_end() wird eine normale Funktionsbeendigung sichergestellt |
Bei den Funktionen printf() und scanf(), die beide mit einer variablen Parameterliste arbeiten, werden sowohl die Anzahl als auch der jeweilige Typ der folgenden Parameter durch die im ersten Parameter (Controlstring) enthaltenen Umwandlungsspezifikationen mitgeteilt.
next = va_arg(argp, int); /* int-Parameter angenommen */
va_end(argp);
/*--------------------------------------------------------------------*/
/* Programm VARPL */
/*--------------------------------------------------------------------*/
/* Beispiel für eine Funktion mit variabler Parameterliste */
#include <stdarg.h>
#include <stdio.h>
void main(void)
{ float a,b,c;
int d;
float m;
double vmax(int anz,...);
printf("\nGeben Sie 4 Zahlen ein (letzte int) : ");
scanf("%e%e%e%d",&a,&b,&c,&d);
m=vmax(2,a,b);
printf("\nMaximum der ersten beiden Zahlen : %f",m);
m=vmax(3,a,b,c);
printf("\nMaximum der ersten drei Zahlen : %f",m);
m=vmax(4,a,b,c,(float)d);
printf("\nMaximum aller vier Zahlen : %f",m);
putchar('\n');
}
/*--------------------------------------------------------------------*/
/* Funktion vmax() */
/*--------------------------------------------------------------------*/
/* Ermittlung des Maximums einer variablen Anzahl von double-Werten */
/* Variable Anzahl von Parametern */
/* Erster Parameter gibt die Anzahl der folgenden Parameter vom Typ */
/* double an */
/*--------------------------------------------------------------------*/
double vmax(int anz,...)
{
va_list argp; /* Definition von argp */
double wert,max=0;
if (anz>0)
{ va_start(argp,anz); /* Initialisierung von argp */
max=va_arg(argp,double); /* Zugriff zum 1. variablen Param. */
while (--anz > 0)
{ wert=va_arg(argp,double); /* Zugriff zu weiteren Parametern */
if (wert > max)
max=wert;
}
va_end(argp); /* Abschluß des Zugriffs */
}
return max;
}
Bildschirmausgabe :
E:\RT\C>varpl Geben Sie 4 Zahlen ein (letzte int) : 2.9 -4.7 8.1 3 Maximum der ersten beiden Zahlen: 2.900000 Maximum der ersten drei Zahlen : 8.100000 Maximum aller vier Zahlen : 8.100000
In <time.h> sind außerdem definiert :
| Konstante | CLK_TCK | Anzahl der Perioden (ticks) der Systemzeit pro Sekunde |
| Typ | clock_t | Arithmetischer Datentyp zur Darstellung der Zeit (bei TURBO-C : = long) |
| Typ | time_t | Arithmetischer Datentyp zur Darstellung der Zeit (bei TURBO-C : = long) |
| Typ | tm | Structure-Typ zur Darstellung der Kalenderzeit |
Der Typ tm muß wenigstens die folgenden Komponenten enthalten :
int tm_sec; /* Sekunden nach der Minute [0 .. 59] */ int tm_min; /* Minuten nach der Stunde [0 .. 59] */ int tm_hour; /* Stunden seit Mitternacht [0 .. 23] */ int tm_mday; /* Tag des Monats [0 .. 31] */ int tm_mon; /* Monate seit Januar [0 .. 11] */ int tm_year; /* Jahre seit 1900 */ int tm_wday; /* Tage seit Sonntag [0 .. 6] */ int tm_yday; /* Tage seit 1.Januar [0 ..365] */ int tm_isdst; /* Sommerzeit-Flag */Für den Wert des Sommerzeit-Flags tm_isdst gilt :
| struct tm *gmtime(const time_t *tp); | Umwandlung der in implementierungsspezifischer Darstellung vorliegenden
Kalenderzeit *tp in eine strukturierte Darstellung der Coordinated
Universal Time (UTC).
Falls die UTC nicht ermittelt werden kann, ist der Funktionswert = NULL |
| struct tm *localtime(const time_t *tp); | Umwandlung der in implementierungsspezifischer Darstellung vorliegenden Kalenderzeit *tp in eine strukturierte Darstellung der Ortszeit |
| time_t mktime(struct tm *tptr); | Umwandlung der in strukturierter Darstellung vorliegenden Ortszeit
*tptr
in die implementierungsspezifische Darstellung der Kalenderzeit.
Die Werte der einzelnen Strukturkomponenten müssen nicht normiert sein. Die Funktion führt zusätzlich ihre Normierung durch und berechnet die Werte für die Komponenten tm_wday und tm_yday. Falls keine darstellbare Kalenderzeit ermittelt werden kann erzeugt die Funktion den Wert (time_t)-1. |
| char *asctime(const struct tm *tptr); | Umwandlung der in strukturierter Darstellung vorliegenden Ortszeit
*tptr
in einen String der folgenden Form :
|
| char *ctime(const time_t *tp); | Umwandlung der in implementierungsspezifischer Darstellung vorliegen
den Kalenderzeit *tp in einen String der folgenden Form: Sun
Apr 14 11:23:22 1991\n\0 Funktionswert ist Pointer auf diesen String.
ctime(tp) ist äquivalent zu asctime(localtime(tp)). |
| size_t strftime(char *s, size_t smax, const char *fmt, const struct tm *tptr); | Ablage von in *tptr enthaltenen Zeit- und Datumsinformationen
in den String s gemäß den im String fmt enthaltenen
Formatspezifikationen.
Jeder sonstiger Text in fmt wird nach s übernommen. Der String s darf maximal smax Zeichen lang werden. Funktionswert :
Der Inhalt von s ist in diesem Fall undefiniert |
| Format-Spezifier für strftime() | %a abgekürzter Name des Wochentags
%A ausgeschriebener Name des Wochentags %b abgekürzter Name des Monats %B ausgeschriebener Name des Monats %c geeignete Darstellung der lokalen Zeit (Datum und Zeit) %d Tag des Monats als Dezimalzahl (01 .. 31) %H Stunde als Dezimalzahl (24-Std-Uhr) (00 .. 23) %I Stunde als Dezimalzahl (12-Std-Uhr) (01 .. 12) %j Tag des Jahres als Dezimalzahl (001 .. 386) %m Monat als Dezimalzahl (01 .. 12) %M Minute als Dezimalzahl (00 .. 59) %p PM oder AM (oder landesspezifisches Äquivalent) %S Sekunde als Dezimalzahl (00 .. 59) %U Woche des Jahres als Dezimalzahl (Sonntag ist der erste Tag der Woche) (00 .. 53) %w Wochentag als Dezimalzahl (Sonntag = 0) (0 .. 6) %W Woche des Jahres als Dezimalzahl (Montag ist der erste Tag der Woche) (00 .. 53) %x geeignete des lokalen Datums %X geeignete Darstellung der lokalen Zeit %y (Jahr - Jahrhundert) als Dezimalzahl (00 .. 99) %Y Jahr als Dezimalzahl (einschließlich Jahrhundert) %Z Name der Zeitzone, falls ein Name existiert %% Das Zeichen % |
/*--------------------------------------------------------------------*/
/* Programm TIMEDEMO */
/*--------------------------------------------------------------------*/
/* Demonstrationsprogramm zur Verwendung der Zeit- und Datumsfunk- */
/* tionen der ANSI-C-Standardbibliothek */
/*--------------------------------------------------------------------*/
#include <time.h>
#include <stdio.h>
void main(void)
{
time_t zeit1,zeit2;
clock_t clk;
double ctsec, ttdiff;
struct tm *lzeit;
char zeit_str[80];
void proc_cal_time_out(clock_t, time_t);
void warten(void);
void loc_zeit_aus(struct tm *);
clk=clock();
zeit1=time(NULL);
proc_cal_time_out(clk,zeit1);
warten();
clk=clock();
zeit2=time(NULL);
proc_cal_time_out(clk, zeit2);
ctsec=clk/CLK_TCK;
ttdiff=difftime(zeit2, zeit1);
printf("\nWartezeit : %f Sek. (ermittelt über Prozessorzeit)",ctsec);
printf("\n %f Sek. (ermittelt über Kalenderzeit)\n",ttdiff);
lzeit=localtime(&zeit2);
loc_zeit_aus(lzeit);
strcpy(zeit_str,asctime(lzeit));
printf("\nZeit-String : %s\n",zeit_str);
}
void proc_cal_time_out(clock_t ct, time_t tt)
{
printf("