Jazyk C: P6
.. slide lib.1 rev 6.10.1995
Standardní ANSI C knihovny
soubor | co obsahuje
----------------------------------------------------------------
assert.h | Makro assert pro ladění.
ctype.h | Makra pro klasifikaci znaků.
errno.h | Definuje pojmenování konstant-chybových kódů.
float.h | Parametry pro floating-point funkce.
limits.h | Parametry prostředí, rozsahy celých čísel.
locale.h | Funkce pro národní/jazykovou podporu.
math.h | Matematické funkce.
setjmp.h | Typy pro funkce longjmp a setjmp.
signal.h | Konstanty a deklarace pro funkce signal a raise
stdarg.h | Makra pro práci s proměnným počtem argumentů.
stddef.h | Některá makra a datové typy.
stdio.h | Typy,makra a funkce pro standardní vstup/výstup
stdlib.h | Obecně použitelné funkce (konverze, sort, ...).
string.h | Funkce pro práci s řetězci a pamětí.
time.h | Typy a funkce pro práci s časem.
Dovezení rozhraní:
#include
.. slide lib.2 rev 5.10.1995
assert.h - makro assert pro ladění
- diagnostika - testování podmínek (precondition,postcondition)
- při nesplnění podmínky vypíše:
text "Assertion failed:"
text podmínky x < 0
jméno souboru __FILE__
číslo řádku __LINE__
- lze vypnout definováním makra NDEBUG
#define NDEBUG
Použití:
double logarithm(const double x) {
assert( x > 0.0 );
/* zde platí podmínka */
....
}
.. slide lib.3 rev 5.10.1995
ctype.h - makra pro klasifikaci znaků
int isalnum(int c) - písmeno nebo číslice A-Za-z0-9
int isalpha(int c) - písmeno A-Za-z
int iscntrl(int c) - řídicí znak
int isdigit(int c) - číslice 0-9
int isgraph(int c) - tisknutelný znak bez mezery
int islower(int c) - malé písmeno a-z
int isprint(int c) - tisknutelný znak včetně mezery
int ispunct(int c) - tisknutelný znak bez alnum a mezery
int isspace(int c) - oddělovač
int isupper(int c) - velké písmeno A-Z
int isxdigit(int c) - šestnáctková číslice 0-9A-Fa-f
int tolower(int c) - převod znaku na velké písmeno
int toupper(int c) - převod znaku na malé písmeno
parametr: všechny hodnoty unsigned char a hodnota EOF
.. slide lib.4 rev 5.10.1995
errno.h - pojmenování konstant-chybových kódů
int errno - proměnná nastavovaná std. funkcemi, na začátku
programu je nulová
Hodnoty:
EDOM - doménová chyba
ERANGE - přetečení nebo podtečení
float.h - charakteristiky floating-point typů
- zaokrouhlování
- základ
- přesnost
- minimum, maximum
limits.h - rozsahy celočíselných typů
CHAR_BIT
SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, CHAR_MIN, CHAR_MAX
SHRT_MIN, SHRT_MAX, USHRT_MAX
INT_MIN, INT_MAX, UINT_MAX
LONG_MIN, LONG_MAX, ULONG_MAX
locale.h - funkce pro národní/jazykovou podporu
- konvence pro formáty: datum, čas, měna
math.h - matematické funkce
- běžné matematické funkce
- fabs, floor, ceil, fmod
.. slide lib.5 rev 5.10.1995
setjmp.h - nelokální skoky
funkce:
setjmp - příprava pro nelokální skok
longjmp - provede nelokální skok
deklarace:
int setjmp(jmp_buf jmpb);
void longjmp(jmp_buf jmpb, int retval);
Poznámka: setjmp MUSÍ být voláno před longjmp
- volání longjmp s jmpb obnoví stav programu tak, jakoby setjmp
skončil s návratovou hodnotou retval.
Poznámka: longjmp nemůže předat hodnotu 0 v retval, v takovém
případě longjmp změní retval na 1.
- longjmp může být voláno pouze z funkce, která je vyvolána
z funkce, která volala příslušný setjmp.
- setjmp je použitelné pro ošetření chyb a výjimek
Návratové hodnoty:
- setjmp vrací 0 když je volán. Když dojde k návratu z setjmp
po volání 2ongjmp, setjmp vrací nenulovou hodnotu.
- longjmp se nikdy nevrací
--------------------------------------------------------------
.. slide lib.6 rev 4.10.1995
Příklad: - použití setjmp(), longjmp()
#include
#include
#include
void subroutine(jmp_buf);
int main() {
int value;
jmp_buf jumper;
value = setjmp(jumper);
if (value != 0) {
printf("Byl volán longjmp s hodnotou %d\n", value);
exit(value);
}
printf("Volání podprogramu ... \n");
subroutine(jumper);
return 0;
}
void subroutine(jmp_buf jumper) {
longjmp(jumper,1);
}
--------------------------------------------------------------
.. slide lib.7 rev 5.10.1995
signal.h - zpracování signálů
Signály jsou vysílány pomocí raise nebo při výskytu mimořádné
události.
funkce:
raise - vyšle signál typu sig do programu
signal - určuje jak bude přijatý signál zpracován
void (*signal(int sig, void (*func) (int sig)))(int);
int raise(int sig);
- je možné instalovat funkce, které se provedou při příjmu
odpovídajícího signálu
- předdefinovány jsou SIG_DFL a SIG_IGN (v signal.h)
SIG_DFL - ukončí program
SIG_ERR - indikuje chybu při návratu z funkce signal
SIG_IGN - ignoruje signál
Uživatelem specifikované obslužné funkce mohou končit return
nebo voláním abort, _exit, exit, nebo longjmp.
Typy signálů:
SIGABRT - abnormální ukončení
SIGFPE - chyba operace v plovoucí čárce (dělení nulou)
SIGILL - nelegální operace
SIGINT - ctrl-C
SIGSEGV - chyba přístupu k paměti
SIGTERM - požadavek ukončení programu
--------------------------------------------------------------
.. slide lib.8 rev 5.10.1995
stdarg.h - makra pro funkce s proměnným počtem argumentů
typ:
va_list
makra:
void va_start(va_list ap, lastfix);
type va_arg(va_list ap, type);
void va_end(va_list ap);
Makra va_arg, va_end, a va_start poskytují prostředky pro
přenositelný přístup k proměnnému počtu argumentů
- va_start nastaví ap tak, aby ukazoval na první z volitelných
argumentů funkce. Například:
void f(int i, char *lastfix, ...);
- va_arg expanduje na výraz, který má hodnotu typu type (druhý
parametr makra) a představuje jeden z volitelných argumentů
Z důvodu implicitních konverzí nelze použít typy char,
unsigned char, nebo float jako druhý parametr va_arg.
- va_end ukončuje zpracování proměnného počtu parametrů
Pořadí volání: Makro va_start musí být voláno před va_arg nebo
va_end. Makro va_end má být voláno až po přečtení všech
parametrů pomocí va_arg.
První použití va_arg vrací první volitelný parametr. Každé další
volání va_arg vrací další parametr v seznamu parametrů.
--------------------------------------------------------------
.. slide lib.9 rev 5.10.1995
Příklad: - funkce s proměnným počtem argumentů
#include
#include
/* tisk součtu seznamu čísel ukončeného nulou */
void sum(char *msg, ...) {
int total = 0;
va_list ap;
int arg;
va_start(ap, msg);
while ((arg = va_arg(ap,int)) != 0) {
total += arg;
}
printf(msg, total);
va_end(ap);
}
int main() {
sum(" Součet 1+2+3+4 je %d\n", 1, 2, 3, 4, 0);
return 0;
}
--------------------------------------------------------------
.. slide lib.10 rev 6.10.1995
stddef.h - některá makra a datové typy
typy:
ptrdiff_t
size_t
wchar_t
makra:
NULL
offsetof( typ, označení_člena )
Příklady:
struct xx {
int a, b;
} x;
static size_t off = offsetof( struct xx, b );
static size_t sz = sizeof( struct xx );
static void *ptr = NULL;
static int p[10];
static ptrdiff_t dif = (char*)&p[10] - (char*)&p[0];
static wchar_t c = L'H';
.. slide lib.11 rev 6.10.1995
stdio.h - standardní vstup/výstup
typy:
size_t velikost objektů v paměti
FILE soubor
fpos_t pozice v souboru
makra:
NULL, EOF
FOPEN_MAX, FILENAME_MAX
SEEK_CUR, SEEK_END, SEEK_SET
stdin, stdout, stderr
funkce:
remove, rename
tmpfile
fopen, freopen, fread, fwrite, fclose
fprintf, fscanf, printf, scanf, sprintf, sscanf
vfprintf, vprintf, vsprintf,
fgetc, fgets, fputc, fputs,
getc, getchar, putc, putchar, gets, puts
ungetc,
fgetpos, fseek, fsetpos, ftell, rewind
clearerr, feof, ferror, perror
.. slide lib.12 rev 6.10.1995
funkce getchar
int getchar(void);
čte jeden znak stdin. Narazí-li na konec souboru, vrací
hodnotu EOF. Ekvivalent getc(stdin).
funkce putchar
int putchar(char c);
zapisuje jeden znak do stdout. Nelze-li zapsat, vrací EOF,
jinak vrací c. Ekvivalent putc(stdin).
Příklad: konverze na malá písmena (filtr)
#include
#include
int main() {
int c;
while((c=getchar())!=EOF)
putchar(isupper(c)?tolower(c):c);
}
funkce gets
int gets(char *s);
čte řádek ze stdin. Vrací s při úspěšném čtení, NULL při EOF.
Znak '\n' přečte, ale do s ho neuloží (na rozdíl od fgets).
funkce puts
int puts(const char *s);
zapíše řetězec do stdout a přejde na nový řádek (na rozdíl od
fputs). Vrací EOF při chybě, jinak vrací nezápornou hodnotu.
.. slide lib.13 rev 6.10.1995
funkce printf - formátovaný výstup do stdout
int printf(const char *fmt, ...);
fmt: řetězec obsahující formát tisku
% - prefix formátu %-5.2lf float
|| |\-- long
d - desítkově celé číslo || \--- počet des. míst
o - oktalově celé číslo |\----- min. délka
x - šestnáctkově celé číslo \------ zarovnání doleva
u - desítkově bez znaménka
c - znak
s - řetězec
e - pohyblivá čárka s exponentem
f - pohyblivá čárka bez exponentu
g - kratší z %e nebo %f
Příklad: printf("%d %-5d \n", i, j);
%10s min. délka 10
%-10s zarovnání doleva
%10.5s délka 10, tiskne pouze 5 znaků, zprava mezery
%.10s tisk řetězce, je-li delší max. 10 znaků
% d znaménko '-' nebo ' ' na začátku čísla
%#g vždy desetinná tečka, ponechá koncové nuly
%06x ponechá úvodní nuly: -00001
.. slide lib.14 rev 6.10.1995
funkce scanf - formátovaný vstup ze stdin
int scanf(const char *fmt, ...);
- vrací počet úspěšně načtených formátů
fmt: formátová specifikace
- znaky ' ', '\t', '\n' se ignorují
- jiné znaky se musí shodovat se vstupním textem
% - prefix
* - potlačí přiřazení
šířka_pole
znak_konverze vstup argument je typu ukazatel
d, ld desítkové číslo int*, long*
o, lo osmičkové číslo int*, long*
x, lx šestnáctkové číslo int*, long*
h short short*
c jediný znak char*
s řetězec char[], char*
f, lf reálné číslo float*, double*
Příklad:
int i;
float x;
char name[50];
scanf("%2d %f %*d %2s", &i, &x, name); /* ukazatele! */
vstup: 56789 0123 45a72
výsledek: i = 56; x = 789.0; name = "45"
.. slide lib.15 rev 6.10.1995
fprintf, fscanf - tisk a čtení ze souboru
int fprintf(FILE *f, const char *fmt, ...);
int fscanf(FILE *f, const char *fmt, ...);
sprintf, sscanf - formátové konverze v paměti
int sprintf(char *s, const char *fmt, ...);
int sscanf(const char *s, const char *fmt, ...);
Poznámky:
- konzistenci parametrů a formátu zajišťuje programátor
- scanf vyžaduje ukazatele jako parametry
- scanf - je nebezpečí přepsání paměti
- implicitní konverze
Příklad:
int i;
char c;
scanf(" %i ", i ); /* pozor - chyba! */
scanf(" %i ", &c ); /* pozor - chyba! */
.. slide lib.16 rev 6.10.1995
Práce se soubory
funkce fopen - otevření souboru
FILE *fopen(const char *name, const char *mode);
name: jméno souboru
mode: způsob práce se souborem:
"r" "rb" čtení, čtení binárního souboru
"w" "wb" zápis
"a" "ab" přidávání na konec
různé kombinace "rw", "r+", "w+b" atd...
- při chybě vrací NULL
Příklad:
const char *name = "test.txt";
FILE *fp;
fp = fopen( name, "r" );
if( fp == NULL )
error("soubor %s nelze otevřít pro čtení", name)
funkce fclose - uzavření souboru
int fclose(FILE *f);
- vrací EOF v případě chyby, jinak nulu
.. slide lib.17 rev 6.10.1995
Příklad: - zřetězení souborů na stdout (cat)
#include
void filecopy(FILE *fp);
int main(int argc, char *argv[]) {
FILE *fp;
if( argc==1 )
filecopy(stdin);
else
while( --argc > 0 )
if( (fp=fopen(*++argv,"r")) == NULL ) {
printf("cat: can't open %s \n", *argv);
continue; /* bude pokračovat s dalšími soubory */
}
else {
filecopy(fp);
fclose(fp);
}
return 0;
}
void filecopy(FILE *fp) {
int c;
while( (c=getc(fp)) != EOF )
putc( c, stdout );
}
--------------------------------------------------------------
.. slide lib.18 rev 6.10.1995
stdlib.h - obecně použitelné funkce
typy:
div_t, ldiv_t
makra:
EXIT_FAILURE, EXIT_SUCCESS - parametry exit()
RAND_MAX - maximum rand()
MB_CUR_MAX - max. počet bajtů v 'xxx'
funkce:
- abs, div, labs, ldiv
- bsearch, qsort, rand, srand
- atof, atoi, atol, strtod, strtol, strtoul
- mblen, mbstowcs, mbtowc, wcstombs, wctomb
- calloc, free, malloc, realloc
- abort, atexit, exit, getenv, system
atof, atoi, atol - převod řetězce na číslo
double atof( const char * s);
int atoi( const char * s );
long atol( const char * s );
double strtod( const char *s, char **endptr);
long int strtol( const char *s, char **endptr, int base);
unsigned long int strtoul( const char *s, char **endptr, int base);
endptr - ukazatel do řetězce po konverzi (není-li NULL)
base - základ číselné soustavy
--------------------------------------------------------------
.. slide lib.19 rev 6.10.1995
funkce atexit - volání funkcí na konci programu
int atexit( void (*func)(void) );
- registruje funkci pro zavolání na konci programu (pořadí)
- dovoluje registraci min. 32 funkcí
- vrací nulu v případě úspěchu
funkce exit - zpracování chyb
void exit(int e);
- ukončí program s návratovým kódem e
Příklad:
#include
#include
int main(int argc, char **argv) {
FILE *fp;
if( (fp=fopen(argv[1],"r")) == NULL ) {
fprintf(stderr, "can't open %s \n", argv[1]);
exit(1); /* ukončení s chybou */
} else {
DoSomething();
}
exit(0); /* ukončení bez chyby - program vrací nulu */
}
--------------------------------------------------------------
.. slide lib.20 rev 6.10.1995
Dynamické přidělování paměti
funkce malloc - přidělí paměť o zadané velikosti
funkce free - uvolní přidělenou paměť
prototypy:
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
void *calloc(size_t memb, size_t size);
void free(void *ptr);
Příklad:
#include
typedef struct prvek {
int data;
struct prvek *dalsi;
} prvek;
prvek *novy_prvek(void) {
prvek *p = malloc(sizeof(prvek));
if( p == NULL ) /* musí se testovat!!! */
error("chyba: málo paměti");
return p;
}
void zrus_prvek(prvek *ptr) {
free(ptr);
}
--------------------------------------------------------------
.. slide lib.21 rev 6.10.1995
string.h - funkce pro práci s řetězci a pamětí
size_t, NULL
řetězcové operace:
strlen - délka řetězce
strcpy - kopie řetězce
strncpy - kopie řetězce (max. n znaků)
strcat - připojení řetězce
strncat - připojení řetězce (max. n znaků)
strcmp - porovnání dvou řetězců
strncmp - porovnání dvou řetězců (max. n znaků)
strcoll - porovnání podle národní abecedy (LC_COLLATE)
strchr - vyhledání znaku
strrchr - vyhledání znaku od konce
strstr - vyhledání podřetězce
práce s pamětí - musí se explicitně určit délka
memcpy, memmove, memcmp, memchr, memset, ...
Příklad:
int pole[SIZE];
int pole2[SIZE];
memset(pole, 0, SIZE * sizeof(int) ); /* nulování pole */
memcpy(pole2, pole, SIZE * sizeof(int) ); /* kopie */
--------------------------------------------------------------
.. slide lib.22 rev 6.10.1995
time.h - typy a funkce pro práci s časem
CLOCKS_PER_SEC - počet tiků za sekundu
clock_t - systémový čas
time_t - čas
struct tm - tm_sec, tm_mday, ...
funkce:
clock_t clock(void); /* čas od začátku programu */
double difftime(time_t t1, time_t t0); /* rozdíl v sec */
time_t mktime(struct tm *timeptr); /* převod na interní
reprezentaci času */
time_t time(time_t *timer); /* současná hodnota času */
asctime, ctime, gmtime, localtime, strftime
Příklad:
struct tm t;
t.tm_year = 1995 - 1900; /* rok od 1900 */
t.tm_mon = 10 - 1; /* měsíc od ledna 0..11 */
t.tm_mday = 6; /* den v měsíci 1..31 */
t.tm_hour = 12;
t.tm_min = 0;
t.tm_sec = 1;
t.tm_isdst = -1; /* letní čas */
if( mktime(&t) != -1 ) /* OK */
if(t.tm_wday == 5)
puts("pátek");
Poslední modifikace:
2. října 1997
Pokud naleznete na této stránce chybu, oznamte to dopisem na adresu
peringer@dcse.fee.vutbr.cz.
[ Kursy | Ústav |
Fakulta | VUT | WWW server |
Language/Jazyk ]