Sunteți pe pagina 1din 9

APENDICELE C:

SUMARUL MODIFICARILOR

De la publicarea primei editii a acestei carti, definitia limbajului C a suferit modificari. Aproape toate au fost extensii ale limbajului original si au fost proiectate cu grija pentru a ramine compatibil cu practica existenta; unele inlatura ambiguitatile din descrierea originala iar altele reprezinta modificari care schimba practica existenta. Multe dintre noile facilitati au fost anuntate in documentele ce insotesc compilatoarele livrate de catre AT&T si care au fost adoptate ulterior de catre alti furnizori de compilatoare C. Mai tirziu comitetul ANSI de standardizare a limbajului a adoptat cele mai multe dintre aceste modificari si, de asemenea, a introdus alte modificari importante. Toate acestea au fost, in parte, anticipate de unele compilatoare comerciale chiar inainte de aparitia standardului formal C. Acest apendice recapituleaza diferentele dintre limbajul definit de catre prima editie a acestei carti si acela ce se asteapta sa fie definit prin standardul final. El trateaza numai limbajul insusi, nu si biblioteca si mediul sau; desi acestea constituie o parte importanta a standardului, putine comparatii sint de facut, deoarece prima editie n-a avut intentia sa prescrie o biblioteca sau un mediu. - Preprocesarea este definita in standard mai cu grija decit in prima editie si este extinsa; ea este explicit bazata pe token-uri; exista operatori noi pentru concatenarea tokenurilor (##) si crearea de siruri (#); exista noi linii de comanda precum #elif si #pragma; redeclararea macro-urilor prin aceeasi secventa de token-uri este permisa in mod explicit; parametrii din interiorul sirurilor nu mai sint inlocuiti. Unirea liniilor prin \ este permisa pretutindeni, nu numai in siruri si in definirea macrourilor. Vezi A12. - Numarul minim de caractere semnificative pentru toti identificatorii interni a crescut la 31; pentru identificatorii cu legatura externa acest numar a ramas la 6, iar literele trebuie sa fie toate mici sau toate mari. (Multe implementari prevad mai multe). - Secventeletrigrafintroduse prin ?? permit reprezentarea caracterelor lipsa din anumite seturi de caractere. Escapeurile pentru #, \, ^, [, ], {, }, |, ~ sint acum definite; vezi A12.1. De observat ca introducerea trigrafurilor poate modifica semnificatia sirurilor ce contin secventa ??. - Au fost introduse noi cuvinte cheie (void, const, volatile, signed, enum). Cuvintul cheie entry, nascut mort, a fost retras. - Au fost definite noi secvente escape, pentru utilizare in interiorul constantelor caracter si al literalelor sir. Efectul plasarii, dupa caracterul "\", a unui caracter ce nu face parte din secventele escape aprobate, este nedefinit. Vezi A2.5.2. - Modificare triviala: 8 si 9 nu sint cifre octale. - Standardul introduce un set mai mare de sufixe pentru a face explicit tipul constantelor; U sau L pentru intregi, F sau L pentru punct zecimal mobil. De asemenea, el rafineaza regulile tipurile constantelor fara sufixe (A2.5). - Literalele sir adiacente sint concatenate.

- Exista o notatie pentru literale sir si constante caracter pentru caracter larg. Vezi A2.6. - Caracterele, precum si alte tipuri, pot fi explicit declarate ca fiind cu semn sau fara semn folosind cuvintele cheie signed sau unsigned. Locutiunea long float, sinonima lui double, este retrasa, dar long double poate fi utilizata pentru a declara o marime cu punct zecimal mobil ca fiind cu precizie extinsa. - Pentru un timp, a fost valabil tipul unsigned char. Standardul introduce cuvintul cheie signed pentru a face explicita problema semnului atit pentru char cit si pentru alte obiecte integrale. - Tipul void a fost valabil, in cele mai multe implementari, de citiva ani. Standardul introduce utilizarea tipului void * ca un tip generic de pointer; anterior acest rol il juca char *. In acelasi timp, au fost anuntate reguli explicite impotriva amestecarii pointerelor cu intregi si a pointerelor de diferite tipuri fara utilizarea operatorului de conversie cast. - Standardulplaseaza, in mod explicit, minima in gamele tipurilor aritmetice si mandateaza headere (<limits.h> si <float.h>) pentru a da caracteristicile fiecarei implementari particulare. - Enumeratiile sint noi fata de prima editie a acestei carti. - Standardul adopta de la C++ notiunea de calificator de tip, de exemplu const (A8.2). - Sirurile nu mai sint modificabile asa ca ele pot fi plasate in ROM (Read-Only Memory), memorie ce poate fi numai citita. - "Conversiile aritmetice uzuale" sint modificate, in esenta, plecind de la "pentru intregi, unsigned cistiga intotdeauna; pentru punct zecimal mobil, totdeauna se utilizeaza double" se ajunge la "se promoveaza catre tipul cel mai mic care are capacitate suficienta". Vezi A6.5. - Vechii operatori de atribuire, precum =+, sint efectiv indepartati. De asemenea, operatorii de atribuire, acum sint token-uri singulare; in prima editie, ei erau perechi si puteau fi separati prin spatiu alb. - Licenta de compilator de a trata matematic operatorii asociativi ca si cind ar fi asociativi prin calcul, este revocata. - A fost introdus operatorul unar + pentru simetrie cu unarul -. - Un pointer catre o functie poate fi folosit ca un desenator de functie fara un operator * explicit. Vezi A7.3.2. - Structurile pot fi atribuite, pasate functiilor si returnate de catre functii. - Aplicarea operatorului de adresa tablourilor este permisa iar rezultatul este un pointer catre tablou. - Operatorul sizeof, in prima editie, producea tipul int; ca

urmare, multe implementari il faceau unsigned. Standardul face ca tipul sau sa fie dependent de implementare, dar reclama ca tipul size_t sa fie definit intr-un header standard (<stddef.h>). O modificare similara apare in tipul (ptrdiff_t) al diferentei dintre pointere. Vezi A7.4.8 si A7.7. - Operatorul de adresa & nu poate fi aplicat unui obiect declarat register, chiar daca implementarea face optiunea sa nu tina obiectul intr-un register. - Tipul unei expresii shift este acela al operandului din stinga; operandul din dreapta nu poate sa promoveze rezultatul. Vezi A7.8. - Standardul legalizeaza crearea unui pointer imediat dincolo de sfirsitul unui tablou si permite aritmetica si relatii asupra lui; vezi A7.7. - Standardul introduce notiunea de declaratie prototip de functie (imprumutata de la C++) care incorporeaza tipurile parametrilor si include o recunoastere explicita a functiilor variadic (cu lista cu numar variabil de argumente), impreuna cu un procedeu de lucru cu ele, aprobat. Vezi A7.3.2, A8.6.3, B7. Stilul vechi este acceptat inca, cu restrictii. - Declaratiile vide, care nu au nici un declarator si nu declara cel putin o structura, uniune sau enumeratie, sint interzise de standard. Pe de alta parte, o declaratie cu numai un tag de structura sau uniune redeclara acel tag chiar daca el a fost declarat in domeniul exterior. - Declaratiile externe fara nici un specificator sau calificator (adica un declarator gol) sint interzise. - Unele implementari, cind se prezinta o declaratie extern intrun bloc interior, exporta declaratia in restul fisierului. Standardul stabileste clar ca domeniul unei astfel de declaratii este numai blocul. - Domeniul parametrilor este injectat in interiorul instructiunii compuse ce constituie corpul functiei, astfel ca declaratiile de variabile facute la nivelul de virf al functiei nu pot ascunde parametrii. - Spatiile de nume ale identificatorilor sint intrucitva diferite. Standardul pune toate tagurile intr-un singur spatiu de nume si, de asemenea, introduce un spatiu de nume separat pentru etichete. Vezi A11.1. De asemenea, numele de membri sint asociate cu structura sau uniunea din care ei fac parte. (Aceasta a fost o practica obisnuita de citiva ani) - Uniunile pot fi initializate; initializatorul opereaza asupra primului membru. - Structurile, uniunile si tablourile automate pot fi initializate, desi intr-o maniera restrictiva. - Tablourile de caractere de o marime explicita pot fi initializate de un literal sir cu exact acel numar de caractere (caracterul \0 este impins, incet, in afara). - Expresia de control si etichetele case, ale unui switch, pot avea oricare tip integral.

B8.

Salturi non-locale: <setjmp.h>

Declaratiile din <setjmp.h> furnizeaza o cale pentru a evita secventa normala de apel si retur de functie, in mod tipic pentru a permite un retur imediat dintr-un apel de functie adinc cuibarit. int setjmp(jmp_buf env) Macro-ul setjmp salveaza informatia de stare in env pentru utilizare de catre longjmp. Returul este zero de la un apel direct al lui setjmp si non-zero de la un apel ulterior al lui longjmp. Un apel catre setjmp poate apare numai in anumite contexte, in esenta pentru teste ale lui if, switch si ciclari si numai in expresii relationale simple: if (setjmp(env) == 0) /* get here on direct call */ else /* get here by calling longjmp */ void longjmp(jmp_buf env, int val) longjmp restaureaza starea salvata prin cel mai recent apel al lui setjmp, folosind informatia salvata in env iar executia se reia ca si cind functia setjmp ar fi fost executata si ar fi returnat valoarea non-zero a lui val. Functia care contine pe setjmp trebuie neaparat sa nu-si fi incheiat activitatea. Obiectele accesibile au valorile pe care le-au avut in momentul apelarii lui longjmp; valorile nu sint salvate prin setjmp.

B9.

Semnale: <signal.h>

Header-ul <signal.h> asigura facilitati pentru manevrarea conditiilor exceptionale care apar pe timpul executiei, cum ar fi un semnal de intrerupere de la o sursa externa sau o eroare in executie. void (*signal(int sig, void (*handler)(int)))(int) signal determina modul cum semnalele ulterioare vor fi manevrate. Daca handler este SIG_DFL, atunci va fi utilizata comportarea implicita definita la implementare; daca el este SIG_IGN, semnalul este ignorat; altminteri va fi apelata functia catre care se trimite prin handler cu argument de tipul semnalului. Semnalele valide includ:

SIGABRT

terminare anormala, de ex: de la abort

SIGFPE depasire ilegala SIGILL

eroare aritmetica, de ex:impartire cu zero sau imagine ilegala de functie de ex:instructiune

SIGINT atentie interactiva, de ex: intrerupere SIGSEGV acces ilegal la memorie, de ex:acces in afara limitelor de memorie SIGTERM cerere de terminare trimisa catre acest program signal returneaza valoarea anterioara a handler-ului pentru semnalul specific sau SIG_ERR daca apare o eroare. Cind un semnal sig apare ulterior, semnalul este restaurat conform comportarii sale implicite; apoi este apelata functia signal-handler, ca si cum s-ar apela prin (*handler)(sig). Daca handler-ul returneaza, atunci executia va fi reluata de la punctul unde a fost in momentul aparitiei semnalului. Starea initiala a semnalelor este definita la implementare. int raise(int sig) raise trimite programului semnalul sig; el returneaza non-zero daca esueaza.

B10.

Functii pentru data si timp (ora): <time.h>

Header-ul <time.h> declara tipuri si functii pentru manipularea datei si timpului. Unele functii prelucreaza timpul local, care poate diferi de timpul calendar, de exemplu din cauza zonelor de timp (fus orar). clock_t si time_t sint tipuri aritmetice reprezentind timpuri iar struct tm tine componentele unui timp calendar: int int int int int int int int int tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year; tm_wday; tm_yday; tm_isdst; secunde dupa minut (0. 59) minute dupa ora (0. 59) ore incepind de la miezul noptii (0. 23) zile ale lunii (0. 31) luni incepind cu ianuarie (0. 11) ani incepind cu 1900 zile incepind cu duminica (0. 6) zile incepind cu 1 ianuarie (0. 365) Daylight Saving Time flag

tm_isdst este pozitiv daca semaforul Daylight Saving Time este in functie, zero daca nu este si negativ daca informatia nu este disponibila. clock_t clock(void) clock returneaza timpul procesorului folosit de catre program de la inceputul executiei sau -1 daca nu este disponibil. clock()/CLK_TCK este un timp in secunde. time_t time(time_t *tp) time returneaza timpul curent calendar sau -1 daca timpul nu este disponibil. Daca tp nu este NULL, valoarea returnata este, de asemenea, atribuita lui *tp. double difftime(time_t time2, time_t time1) difftime returneaza time2 - time1 exprimat in secunde time_t mktime(struct tm *tp)

mktime converteste timpul local din structura *tp in timp calendar in aceeasi reprezentare folosita de catre time. Componentele vor avea valori in gamele (ranges) aratate. mktime returneaza timpul calendar sau -1 daca el nu poate fi reprezentat. Urmatoarele patru functii returneaza pointere catre obiecte statice care pot fi suprascrise prin alte apeluri. char *asctime(const struct tm *tp) asctime converteste timpul din structura *tp intr-un sir de Sun Jan 3 15:14 1988\n\0 forma:

char *ctime(const time_t *tp) ctime converteste timpul calendar *tp in timp local; el este cu: asctime(localtime(tp)) struct tm *gmtime(const time_t *tp) gmtime converteste timpul calendar *tp in timpul coordonat universal (Coordinated Universal Time (UTC)). El returneaza NULL daca UTC nu este disponibil. Numele gmtime are semnificatie istorica. struct tm *localtime(const time_t *tp) localtime converteste timpul calendar *tp in timp local. size_t strftime(char *s, size_t smax, const char *fmt, const struct tm *tp) strftime formateaza informatia despre data si timp din *tp in s in conformitate cu fmt, care este analog cu un format al lui printf. Caracterele ordinare (inclusiv terminatorul '\0') sint copiate in s. Fiecare %c este inlocuit dupa cum se descrie mai jos, folosind valorile corespunzatoare pentru mediul local. Numarul maxim de caractere ce se plaseaza in s nu va fi mai mare decit smax. strftime returneaza numarul de caractere, exclusiv '\0', sau zero daca s-au produs mai multe caractere decit smax. %a %A %b %B %c %d %H %I %J %m %M %p %S %U %w %W %x %X %y %Y numele zilei din saptamina abreviat numele zilei din saptamina complet numele lunii abreviat numele lunii complet reprezentarea datei si timpului locale ziua din luna (01-31) ora (ceasul cu 24 ore) (00-23) ora (ceasul cu 12 ore) (01-12) ziua din an (001-366) luna (01-12) minutul (00-59) echivalentul local pentru AM sau PM secunda (00-59) numarul saptaminii din an (duminica fiind prima zi a saptaminii) (00-53) ziua din saptamina (0-6, duminica este 0) numarul saptaminii din an (luni fiind prima zi a saptaminii) (00-53) reprezentarea datei locale reprezentarea timpului local anul fara secole (00-99) anul cu secole echivalent

%Z %%

numele zonei de timp (fus orar), daca exista %

B11.

Limite definite la implementare: <limits.h> si <float.h>

Header-ul <limits.h> defineste constante pentru marimile tipurilor integrale. Valorile de mai jos sint valori minime, acceptabile. Pot fi utilizate valorile mai mari. CHAR_BIT CHAR_MAX CHAR_MIN INT_MAX INT_MIN LONG_MAX LONG_MIN SCHAR_MAX SCHAR_MIN SHRT_MAX SHRT_MIN UCHAR_MAX UINT_MAX ULONG_MAX USHRT_MAX 8 UCHAR_MAX sau SCHAR_MAX 0 sau SCHAR_MIN +32767 -32767 +2147483647L -2147483647L +127 -127 +32767 -32767 255U 65535U 4294967295UL 65535U biti intr-un char valoarea valoarea valoarea valoarea valoarea valoarea valoarea char valoarea char valoarea valoarea valoarea char valoarea int valoarea long valoarea short maxima minima maxima minima maxima minima maxima a a a a a a a lui lui lui lui lui lui lui char char int int long long signed

minima a lui signed maxima a lui short minima a lui short maxima a lui unsigned maxima a lui unsigned maxima a lui unsigned maxima a lui unsigned

Numele din tabelul de mai jos, o submultime din <float.h>, sint constante legate de aritmetica cu punct zecimal mobil. Cind este data o valoare, ea reprezinta marimea minima pentrucantitatea respectiva. Fiecare implementare defineste valori corespunzatoare. FLT_RADIX FLT_ROUNDS FLT_DIG FLT_EPSILON FLT_MANT_DIG FLT_MAX FLT_MAX_EXP FLT_MIN FLT_MIN_EXP DBL_DIG DBL_EPSILON DBL_MANT_DIG DBL_MAX DBL_MAX_EXP DBL_MIN DBL_MIN_EXP 2 6 1E-5 1E+37 1E-37 10 1E-9 1E+37 1E-37 baza reprezentarii exponentiale, de ex: 2, 16 modul de rotunjire pentru adunare cifre zecimale de precizie cel mai mic numar x astfel incit 1.0 + x != 1.0 numarul decifrein bazaFLT_RADIX, din mantisa numarul maxim in punct zecimal mobil n maxim astfel incit (FLT_RADIX la puterea n)-1 sa fie reprezentabil numarul minim in punct zecimal mobil normalizat n minim astfel incit 10 la puterea n sa fie un numar normalizat cifre zecimale de precizie cel mai mic numar x astfel incit 1.0 + x != 1.0 numarul de cifre in baza FLT_RADIX, din mantisa numarul maxim pentru double n maxim astfel incit (FLT_RADIX la puterea n)-1 sa fie reprezentabil numarul minim in double normalizat n minim astfel incit 10 la puterea n sa fie un numar normalizat

APENDICELE C:

SUMARUL MODIFICARILOR

De la publicarea primei editii a acestei carti, definitia limbajului C a suferit modificari. Aproape toate au fost extensii ale limbajului original si au fost proiectate cu griija pentru a ramine compatibil cu practica existenta; unele inlatura ambiguitatile din descrierea originala iar altele reprezinta modificari care schimba practica existenta. Multe dintre noile facilitati au fost anuntate in documentele ce insotesc compilatoarele livrate de catre AT&T si care au fost adoptate ulterior de catre alti furnizori de compilatoare C. Mai tirziu comitetul ANSI de standardizare a limbajului a adoptat cele mai multe dintre aceste modificari si, de asemenea, a introdus alte modificari importante. Toate acestea au fost, in parte, anticipate de unele compilatoare comerciale chiar inainte de aparitia standardului formal C. Acest apendice recapituleaza diferentele dintre limbajul definit de catre prima editie a acestei carti si acela ce se asteapta sa fie definit prin standardul final. El trateaza numai limbajul insusi, nu si biblioteca si mediul sau; desi acestea constituieo parte importanta a standardullui, putine comparatii sint de facut, deoarece prima editie n-a avut intentia sa prescrie o biblioteca sau un mediu. - Preprocesarea este definita in standard mai cu grija decit in prima editie si este extinsa; ea este explicit bazata pe token-uri; exista operatori noi pentru concatenarea token-urilor (##) si crearea de siruri (#); exista noi linii de control precum #elif si #pragma; redeclararea macro-urilor prin aceeasi secventa de token- uri este permisa in mod explicit; parametrii din interiorul sirurilor nu mai sint inlocuiti. Unirea liniilor prin \ este permisa pretutindeni, nu numai in siruri si in definirea macrourilor. Vezi A12.