atunci cand trebuie specificata precizia,modul de rotunjire etc.EXEMPLU
səhifə 52/55 tarix 07.05.2018 ölçüsü 4,6 Mb. #50260
atunci cand trebuie specificata precizia ,modul de rotunjire etc.EXEMPLU:
calculele astronomice,fizica cuantica etc.
FUNCTIA _fpreset()
-reinitializeaza registrul pentru virgula mobila
SINTAXA GENERALA este: void _fpreset(void);
Functia se utilizeaza pentru a reinitializa registrul de control al copro-
cesorului matematic,dupa revenirea dintr-o subrutina sau dintr-un program
secundar care este posibil sa fi alterat registrul.De obicei se utilizeaza
in conjunctie cu functiile system(),exec(),spawnle() sau dupa apelarea
unui salt cu longjmp.
Functia nu returneaza nici o valoare.
EXEMPLU: #include
#include
#include
#include
float x;
main()
{ x=3.14;
printf("Executam operatii in virgula mobila ! \n");
printf("x*x*7= %f \n",x*x*7);
sleep(3);
printf("Lansam un program secundar ! \n");
spawnlp(P_WAIT,"ceil1.exe",0);
printf("Resetam procesorul 8087 ! \n");
_fpreset();
printf(" x*x*x*7= %f \n",x*x*x*7);
sleep(3); }
-396- [ float.h - _status87 -CONSTANTE ]
FUNCTIA _status87()
-citeste statusul procesorului 8087 (coprocesorul matematic)
SINTAXA GENERALA este: unsigned int _status87(void);
Functia citeste statusul coprocesorului matematic.Valoarea rezultata este
o combinatie dintre valoarea din registrul virgulei mobile(1 word=2 bytes)
si diferite alte condii detectate de controlerul pentru exceptii.
Functia returneaza valoarea registrului care este de tip unsigned int si
este reprezentata pe 2 bytes adica pe 16 biti.
EXEMPLU: vezi _clear87()
CONSTANTE,TIPURI DE DATE si VARIABILE GLOBALE (vezi fila float.h )
CW_DEFAULT -este constanta pentru valoarea registrului 8087 (statusul
virgulei mobile sau al coprocesorului matematic)
este declarata:
RC_NEAR+PC_64+IC_AFFINE+EM_UNDERFLOW+EM_INEXACT
unde:
RC_NEAR este 0x0000
IC_AFFINE este 0x1000
EM_UNDERFLOW este 0x0010
EM_INEXACT este 0x0020
SIGxxxx -sunt constante utilizate de cate functiile raise() si
signal() pentru a transmite un mesaj software in timpul
executiei unui program,sau pentru a semnaliza diferite
operatii si actiuni.Pot fi:
SIGABRT Abnormal termination Apeleaza functia _exit(3)
SIGFPE Bad floating point operation Apeleaza functia _exit(1)
SIGILL Ilegall operation Apeleaza functia _exit(1)
SIGINT Control_C interrupt Apeleaza INT 23h
SIGSEGV Invalid acces to storage Apeleaza functia _exit(1)
SIGTERM Request program termination Apeleaza functia _exit(1)
FPE_EXPLITIGEN -este declarata 140 si se utilizeaza atunci cand functia
raise apeleaza SIGFPE
FPE_INEXACT -este declarata 134 specifica pierderea preciziei 8087
FPE_INDIV0 -este declarata 127 specifica unintreg impartit la zero
FPE_INTOVFLOW -este declarata 126 specifica "interrupt on overflow"
FPE_INVALID -este declarata 129 specifica o operatie invalida
FPE_OVERFLOW -este declarata 132 inseamna "arithmetic overflow"
FPE_UNDERFLOW -este declarata 133 inseamna "arithmetic underflow"
FPE_ZERODIVIDE -este declarata 131 insemana impartire prin zero
ILL_EXECUTION -este declarata 20 inseamna exceptie de operatie ilegala
ILL_EXPLICITOGEN -este declarata 21 apare cand raise() apeleaza SIGILL
SEGV_BOUND -este declarata 10 specifica o violare BOUND (SIGSEGV)
SEGV_EXPLICITOGEN-este declarata 11 apare cand raise() apeleaza SIGSEGV
Pentru resetarea preciziei se utilizeaza:
MCW_PC 0x0300 cu variantele: PC_24 0x0000 24 de biti
PC_53 0x0200 53 de biti
PC_64 0x0300 64 de biti
Rotunjirea se poate face prin majorare,micsorare,amputare sau aproximare.
-397- [ limits.h si mem.h CONSTANTE ]
BIBLIOTECA C fila antet
-contine parametrii pentru mediul de operare(enviroment),informatii pentru
limitarile din timpul operatiilor de compilare(copiere) si domenii de
valori pentru datele de tip int
CONSTANTE,TIPURI DE DATE si VARIABILE GLOBALE
CHAR_xxx -sunt constante definite pentru tipul de date char.Pot fi:
CHAR_BIT -specifica numarul de biti/caracter = 8
CHAR_MAX -specifica valoarea maxima =0xFFU
CHAR_MIN -specifica valaorea minima =0x00
Valorile sunt aceleasi indiferent daca tipul char a fost
definit ca signed sau unsigned char.
INT_xxx -sunt constante definite pentru tipul de date int.Pot fi:
INT_MAX -specifica valoarea maxima =0x7FFF
INT_MIN -specifica valoarea minima =0x8000
Reprezinta valoarea maxima si minima pentru tipul int.
LONG_xxx -sunt constante definite pentru tipul de date long.Pot fi:
LONG_MAX -specifica valoarea maxima long =0x7FFFFFFFL
LING_MIN -specifica valoarea minima long =0x80000000L
Reprezinta valoarea maxima si minima pentru tipul long.
SCHAR_XXX -sunt constante definite pentru tipul de date short char.Pot fi
SCHAR_MAX -specifica valoarea maxima =0x7F
SCHAR_MIN -specifica valoarea minima =-128
Reprezinta valoarea maxima si minima pentru short char.
SHRT_xxx -sunt constante definite pentru tipul de date short int.Pot fi:
SHRT_MAX -specifica valoarea maxima =0x7FFF
SHRT_MIN -specifica valoarea minima =0x8000
Uxxx_MAX -sunt constante definite pentru tiuprile de date unsigned:
UCHAR_MAX =valoarea maxima unsigned char =0x7FFU
USHRT_MAX =valoarea maxima unsigned short =0xFFFFU
UINT_MAX =valoarea maxima unsigned int =0xFFFFU
ULONG_MAX =valoarea maxima unsigned long =0xFFFFFFFFUL
Se utilizeaza pentru functiile care solicita valoarea tipului de date
respectiv.
BIBLIOTECA C fila antet
-declara o serie de functii utilizate pentru manipularea blocurilor de
memorie interna (pentru operatii cu siruri de caractere)
Functiile declarate sunt: memccpy(),memchr(),memcmp(),memcpy(),memicmp(),
memmove(),memset(),movedate(),movmem() si setmem() ,respectiv in versiunea
C++ sunt si versiunile cu pointer FAR spre memoria extinsa:_fmemccpy(),
_fmemchr(),_fmemcmp(),_fmemcpy(),_fmemicmp(),_fmemmove(),_fmemset() si
_fmovmem().Functiile au fost descrise pe larg,impreuna cu exemple,la fila
antet (vezi paginile 294-298 )
CONSTANTE,TIPURI DE DATE si VARIABILE GLOBALE
NULL -este definit 0 sau 0L Nu este compatibil cu pointerii de functii.
Este garantat ca nu pointeaza nici un obiect din program.
ptrdiff_t -este o constanta signed int=rezultatul scaderii a doi pointeri
size_t -este o constanta unsigned int returnata de operatorul sizeof
-398- [ setjmp.h - longjmp() ]
BIBLIOTECA C fila antet
-declara functii si tipuri de date pentru salt (deplasare) in program
FUNCTIA longjmp()
-permite un salt in program
SINTAXA GENERALA este: void longjmp(jmp_buf jmpb,int retval);
Functia utilizeaza o structura de tip jmp_buf(vezi tipurile de date)
pentru a reinstala mediul de operare salvat anterior cu setjmp() si apoi
returneaza functiei setjmp() valoarea specificata prin retval.Executia
programului este reluata de la nivelul la care a fost apelata functia
setjmp() (care a preluat valoarea retval).
Functia poate fi apelata doar dupa un apel al functiei setjmp() (face
salt in program la functia setjpm()) si este necesar ca rutina in care a
fost declarata setjmp() sa fie inca activa (nu se poate face saltul int-un
subprogram inactiv).Functia nu accepta valoarea 0.Daca se specifica 0
pentru retval,acesta va fi substituit automat cu 1.
La reluarea executiei,functia reinstaleaza toti registrii salvati cu
setjmp(),astfel incat executia este reluata cu acelasi mediu de operare
ca si la prima executie (spre deosebire de goto la care mediul de operare
poate fi schimbat inainte de reluarea executiei).
Functia nu ppoate fi utilizata pentru a face salt spre rutine care se
deruleaza in background (chiar daca sunt active).
Functia nu returneaza nici o valoare.
EXEMPLU: #include
#include
#include
jmp_buf tampon;
int valoare,y;
main()
{ valoare=setjmp(tampon);
printf("valoare= %d \n",valoare);
for (y=1;y<10;y++)
{ printf("nr=%d \n",y);
sleep(1);
}
if (valoare==7)
exit(0);
longjmp(tampon,7);
}
Observati ca functia executa un salt si reia executia de la nivelul la
care a fost declarata functia setjmp() si transfera acesteia valoarea
specificata prin retval (7).Daca nu introducem o conditie de iesire din
bucla,operatia se repeta la infint formand o bucla infinita.Procedeul se
utilizeaza in programare atunci cand o secventa de comenzi trebuie repe-
tata pana cand se obtine o anumita valoare sau se identifica o anumita
data care determina iesirea din bucla.
Functia este utila doar atunci cand repetarea secventei de operatii
sa se faca cu acelasi mediu de operare,la fiecare repetare a ciclului de
comenzi.Pentru situatiile in care mediul de operare se schimba de la o
executie la alta,se vor utiliza alte procedee.Atentie sa nu declansati
accidental bucle infinite (se pot intrerupe cu Ctrl+Break).
-399- [ setjmp.h - setjmp() ]
FUNCTIA setjmp()
-salveaza registrii si seteaza punctul de salt pentru longjmp()
SINTAXA GENERALA este: int setjmp(jmp_buf jmpb);
Functia se utilizeaza pentru a executa salturi in program (impreuna cu
longjmp()).Pentru a salva statusul actual al mediului de operare,functia
utilizeaza o structura de tip jmp_buf in care salveaza valorile registri-
lor,pointerii de stiva si cadru,flag-urile si variabilele etc. dupa cum
urmeaza:
WIN16 WIN32
Toti registri de segmente Nu se salveaza registrii de segmente
CS,DS,ES,SS
Registrii variabili Registrii variabili
DI si SI EBX,EDI,ESI
Stack pointer SP Stack pointer ESP (pointerul de arhiva)
Frame pointer BP Frame pointer EBP (pointerul de tampon)
Flags nu se salveaza flags
Functia longjmp() va reinstala valorile salvate in jmp_buf si va transfera
functiei setjmp o valoare pozitiva.Bucla setjmp()/longjmp() poate fi
utilizata cu succes pentru tratarea erorilor generate de subrutinele unui
program (in caz de eroare se reia executia de la un anumit nivel dar cu
o valoare modificata-cea specificata prin retval din longjmp).
Setjmp() trebuie declarata intotdeauna inainte de longjmp(),altfel rezul-
tatul obtinut este impredictibil.In versiunea DOS (cu sistem de operare
DOS),nu se poate utiliza bucla setjmp/longjmp pentru a implementa corutine
suprapuse deoarece corutinele utilizeaza fie stive diferite,fie aceeasi
stiva dar cu partititii diferite,iar programul manager nu poate opera
decat cu o singura stiva(Windows poate procesa in paralel mai multe stive
de tip DOS).Deasemenea,bucla setjmp/longjmp nu poate fi utilizata pentru
a face salturi intre procesul actual si rutine care se desfasoara in
background.In general,sistemul de operare DOS nu permite operatii de gen
multitasking simultan (exista o forma similara de multitasking dar toate
operatile se desfasoara secvential,cu timp de asteptare intre doua ope-
ratii succesive si avand ca baza de memorie o singura stiva ).
Pot exista in background mai multe stive cu arhive de date,dar executia
lor se poate face doar secvential(una cate una).
Functia returneaza zero la prima apelare si apoi valoarea transferata de
longjmp (o valoare obligatoriu pozitiva)
EXEMPLU: vezi longjmp()
CONSTANTE,TIPURI DE DATE si VARIABILE GLOBALE
jmp_buf -este un tampon de tip structura utilizat de setjmp si longjmp.
Este utilizat pentru salvarea si reinstalarea registrolor.Are
forma generala:
typedef struct { unsigned j_sp, j_ss;
unsigned j_flag, j_cs;
unsigned j_ip, j_bp;
unsigned j_di, j_es;
unsigned j_si j_ds;
} jmp_buf[1];
-400- [ share.h si signal.h-raise() ]
BIBLIOTECA C fila antet
-defineste parametrii pentru functiile care opereaza file partajate
CONSTANTE,TIPURI DE DATE si VARIABILE GLOBALE
SH_xxx -sunt constante utilizate de DOS pentru a deschide file partajate
cu ajutorul functiilor _dos_open() si sopen().Pot fi:
SH_COMPAT -definita 0x0000 -seteaza modul compatibilitatii.Permite
deschidera filelor cu SH_COMPAT.Apelul esueaza daca
fila a fost deja deschisa in alt mod.
SH_DENYNO -definita 0x0040 -permite accesul la scriere si citire
SH_DENYNONE -definita 0x0040 -permite accesul la scriere si citire
SH_DENYRD -definita 0x0030 -NU PERMITE accesul pentru citire (dar
permite scrierea in fila)
SH_DENYRW -definita 0x0010 -NU PERMITE accesul la scriere si citire
SH_DENYWR -definita 0x0020 _NU PERMITE accesul la scriere (dar
permite citirea datelor din fila)
BIBLIOTECA C fila antet
-defineste functii si constante utilizate pentru semnalizarea si tratarea
exceptiilor (functiile raise() si signal() )
FUNCTIA raise()
-transmite un mesaj software catre programul aflat in executie
SINTAXA GENERALA este: int raise(int sig);
Functia transmite programului un mesaj specificat prin sig.Daca exista in
program un semnal de manipulare a mesajului respectiv intr-un anumit fel
(o functie sau o rutina de tratare a exceptiei),atunci programul va exe-
cuta rutina respectiva.Daca nu exista nici o specificatie definita de
catre utilizator,atunci functia va executa operatia implicita asociata cu
mesajul respectiv.Cele mai frecvente mesaje declarate in fila
sunt urmatoarele (pot exista si altele):
SIGABRT Abnormal termination -apeleaza functia _exit(3)
SIGFPE Bad floating point operation -apeleaza functia _exit(1)
SIGILL Illegal instruction -apeleaza functia _exit(1)
SIGINT Ctrl-C interrupt -apeleaza INT 23h
SIGSEGV Invalid acces to storage -apeleaza functia _exit(1)
SIGTERM Request for program termination -apeleaza functia _exit(1)
SIGUSR1 User-defined signal -nu are valoare implicita
SIGUSR2 User-defined signal idem
SIGUSR3 User-defined signal idem
SIGBREAK Ctrl-Break interrupt -intrerupere generala
In cazul apelului functiei cu SIGUSRx,functia va executa comanda sau
sirul de comenzi asociat de catre utilizator cu mesajul respectiv,sau nu
va executa nimic,daca nu exista nici o declaratie care sa asocieze o
functie cu mesajul respectiv.In acest mod se pot introduce diverse rutine
de tratare a erorilor de executie scontate.
Pentru a asocia diferite rutine unui mesaj oarecare,utilizati #define.
Atunci cand functia de tratare a erorii nu executa si o iesire fortata
din program,este bine sa asociati si un semnal de avertizare(optic/sonor).
Functia returneaza 0 in caz de succes sau nonzero in caz de eroare.
-401- [ signal.h -signal() ]
EXEMPLU: #include
#include
#include
int x;
main()
{ for (x=1;x<9;x++)
{ printf("x=%d \n",x);
sleep(1);
if (x==7)
{ sound(500);
delay(700);
nosound();
printf("OPERATIE ILEGALA ! \n");
sleep(1);
raise(SIGILL);
};
};
exit(1);
}
FUNCTIA signal()
-specifica o actiune determinata de un mesaj (transmis de raise() )
SINTAXA GENERALA este: typedef(*sigfun)(int subcode);
int signal(int sig,sigfun fname); sau:
void(_USERENTRY *signal(int sig,void(_USERENTRY *func)(int sig)))(int);
Functia determina modul in care va fi tratata eroarea semnalata prin
mesajul specificat prin sig,respectiv desemneaza o functie ce urmeaza sa
fie executata la aparitia mesajului in programul aflat in executie (de
exemplu transmis de raise() ).Se pot utiliza functii definite de catre
utilizator,special pentru tratarea erorilor,sau se pot utiliza functii
predefinite gen exit(),abort() etc.Codurile de manipulare a erorii(handle)
pot fi definite de catre utilizator,sau se pot utiliza cele predefinite
in fila (SIG_DFL,SIG_ERR sau SIG_IGN).Pentru apelarea functiei
se va utiliza un pointer de functie.In fila sunt definiti
urmatorii pointeri:
SIG_DFL =0 -actiune implicita termina programul
SIG_ERR =-1 -returneaza eroare indica error return
SIG_IGN =1 -ignora actiunea semnalul este ignorat
Tipurile de mesaj pot fi urmatoarele (cele declarate in signal.h):
SIGABRT =22 abnormal termination apeleaza _exit(3)
SIGFPE =8 floating point trap apeleaza _exit(1)
SIGILL =4 illegal instruction apeleaza _exit(1)
SIGINT =2 apeleaza INT 23h
SIGSEGV =11 memory access violation apeleaza _exit(1)
SIGTERM =15 program termination apeleaza _exit(1)
daca sistemul de operare este OS2 compatibil (WIN32) atunci sunt accesi-
bile si mesajele:
SIGUSR1 =16 OS/2 process flag A definte de utilizator
SIGUSR2 =17 OS/2 process flag B
SIGUSR3 =20 OS/2 process flag C
SIGBREAK =21 OS/2 Ctrl+break signal
-402- [ signal.h - signal() ]
Functiile definite de catre utilizator pentru tratarea erorii pot termina
executia prin apelarea unei functii de genul _exit(),exit(),abort() sau
longjmp(),sau in cazul in care se sconteaza ca vor receptiona noi mesaje
este necesar sa fie reapelate de catre functia signal().
Versiunea C++,accepta si urmatoarele mesaje: FPE_EXPLICITOGEN=SIGFPE,
SEGV_EXPLICITOGEN=SIGSEGV si ILL_EXPLICITOGEN=SIGILL.
Pointerul utilizat pentru apelarea functiei,pointeaza lista de registrii
a procesorului care au fost salvati in momentul in care a intervenit
eroarea.Registrii pointati sunt in aceeasi ordine cu parametrii functiei
de intrerupere,adica: BP,DI,SI,DS,ES,DX,CX,BX,AX,IP,CS,FLAGS.
Operatiile ilegale semnalate prin mesaje de acest gen,difera in functie
de tipul de procesor.Prezentarea completa a acestor diferente nu face
obiectul prezentului manual,dar este bine de inteles modul in care pot
fi utilizate pentru depanarea aplicatiilor si programelor.
Atentie deosebita trebuie acordata functiei signal atunci cand este ape-
lata intr-un program multithread(ramificat).In acest caz,mesajele SIGINT,
SIGTERM si SIGBREAK pot fi apelate doar din programul principal,in timp
ce celelalte tipuri pot fi apelata si din ramificatii.
Nu este bine ca functia de tratare a erorii sa contina functii obisnuite,
deoarece incarca memoria inutil si pot apare blocaje in executie.Se
recomanda doar semnalizarea erorii si returnarea imediata a comenzii.
Functia returneaza un pointer spre functia de tratare a erorii,sau in caz
de eroare returneaza SIG_ERR si seteaza variabila errno la EINVAL.
EXEMPLU: #include
#include
#include
typedef void (*fptr)();
int x;
main()
{ for (x=1;x<12;x++)
{ printf("x=%d \n",x);
sleep(1);
if (x==7)
{ sound(500);
delay(700);
Dostları ilə paylaş: