Cum să lucrați cu variabile, tipuri de date și expresii aritmetice în limbajul de programare C

C are o varietate bogată de operatori matematici pe care îi puteți folosi pentru a manipula datele dumneavoastră. În acest capitol din Programare în C, ediția a 4-a, Stephen G. Kochan tratează tipurile de date int, float, double, char și _Bool, modificarea tipurilor de date cu short, long și long long, regulile de numire a variabilelor, operatorii matematici de bază și expresiile aritmetice și turnarea tipurilor.

Adevărata putere a programelor pe care le creați este manipularea datelor. Pentru a profita cu adevărat de această putere, trebuie să înțelegeți mai bine diferitele tipuri de date pe care le puteți utiliza, precum și cum să creați și să denumiți variabilele. C dispune de o varietate bogată de operatori matematici pe care îi puteți utiliza pentru a manipula datele. În acest capitol veți acoperi:

  • Tipurile de date int, float, double, char și _Bool
  • Modificarea tipurilor de date cu short, long, și long long
  • Reguli de denumire a variabilelor
  • Operatori matematici de bază și expresii aritmetice
  • Casting de tip

Înțelegerea tipurilor de date și a constantelor

Ați fost deja familiarizat cu tipul de date de bază C int. După cum vă amintiți, o variabilă declarată a fi de tip int poate fi utilizată pentru a conține numai valori integrale – adică valori care nu conțin zecimale.

Limbajul de programare C oferă alte patru tipuri de date de bază: float, double, char și _Bool. O variabilă declarată a fi de tip float poate fi utilizată pentru a stoca numere în virgulă mobilă (valori care conțin zecimale). Tipul double este același cu tipul float, doar că are o precizie aproximativ dublă. Tipul de date char poate fi utilizat pentru a stoca un singur caracter, cum ar fi litera „a”, caracterul de cifră „6” sau un punct și virgulă („;”) (mai multe despre acest lucru mai târziu). În cele din urmă, tipul de date _Bool poate fi utilizat pentru a stoca doar valorile 0 sau 1. Variabilele de acest tip sunt utilizate pentru a indica o situație de tip „pornit/oprit”, „da/nu” sau „adevărat/fals”. Aceste alegeri de tipul „una sau alta” sunt cunoscute și sub denumirea de alegeri binare.

În C, orice număr, caracter unic sau șir de caractere este cunoscut ca o constantă. De exemplu, numărul 58 reprezintă o valoare întreagă constantă. Șirul de caractere „Programming in C is fun.\n” este un exemplu de șir de caractere constant. Expresiile formate în întregime din valori constante se numesc expresii constante. Astfel, expresia

128 + 7 - 17

este o expresie constantă, deoarece fiecare dintre termenii expresiei este o valoare constantă. Dar dacă i ar fi fost declarată ca fiind o variabilă întreagă, expresia

128 + 7 – i

nu ar reprezenta o expresie constantă, deoarece valoarea sa s-ar schimba în funcție de valoarea lui i. Dacă i este 10, expresia este egală cu 125, dar dacă i este 200, expresia este egală cu -65.

Tipul întreg int

În C, o constantă întreagă constă într-o secvență de una sau mai multe cifre. Un semn minus care precede secvența indică faptul că valoarea este negativă. Valorile 158, -10 și 0 sunt toate exemple valide de constante de numere întregi. Nu sunt permise spații încorporate între cifre, iar valorile mai mari de 999 nu pot fi exprimate cu ajutorul virgulelor. (Astfel, valoarea 12.000 nu este o constantă întreagă validă și trebuie scrisă ca 12000.)

Două formate speciale în C permit constantelor întregi să fie exprimate într-o altă bază decât cea zecimală (baza 10). Dacă prima cifră a valorii întregi este un 0, numărul întreg este considerat ca fiind exprimat în notație octală – adică în baza 8. În acest caz, cifrele rămase ale valorii trebuie să fie cifre valide în baza 8 și, prin urmare, trebuie să fie 0-7. Astfel, pentru a exprima valoarea 50 în baza 8 în C, care este echivalentă cu valoarea 40 în zecimal, se utilizează notația 050. În mod similar, constanta octală 0177 reprezintă valoarea zecimală 127 (1 × 64 + 7 × 8 + 7). O valoare întreagă poate fi afișată la terminal în notație octală prin utilizarea caracterelor de format %o în șirul de format al unei instrucțiuni printf(). În acest caz, valoarea este afișată în octal fără un zero de frunte. Caracterul de format %#o determină afișarea unui zero înainte de o valoare octală.

Dacă o constantă întreagă este precedată de un zero și de litera x (fie minusculă, fie majusculă), valoarea este considerată ca fiind exprimată în notație hexazecimală (baza 16). Imediat după litera x se află cifrele valorii hexazecimale, care pot fi compuse din cifrele 0-9 și literele a-f (sau A-F). Literele reprezintă valorile 10-15, respectiv. Astfel, pentru a atribui valoarea hexazecimală FFEF0D unei variabile întregi numite rgbColor, se poate utiliza instrucțiunea

rgbColor = 0xFFEF0D;

. Caracterele de format %x afișează o valoare în format hexazecimal fără 0x de frunte și folosind literele minuscule a-f pentru cifrele hexazecimale. Pentru a afișa valoarea cu 0x de început, se folosesc caracterele de format %#x, ca în cele ce urmează:

printf ("Color is %#x\n", rgbColor);

Un x majuscul, ca în %X sau %#X, poate fi folosit pentru a afișa x de început și cifrele hexazecimale care urmează folosind litere majuscule.

Dimensiuni și intervale de stocare

Care valoare, fie că este un caracter, un număr întreg sau un număr în virgulă mobilă, are un interval de valori asociat cu ea. Acest interval are legătură cu cantitatea de stocare care este alocată pentru a stoca un anumit tip de date. În general, această cantitate nu este definită în limbaj. De obicei, depinde de computerul pe care îl utilizați și, prin urmare, se numește dependentă de implementare sau de mașină. De exemplu, un număr întreg poate ocupa 32 de biți pe computerul dumneavoastră sau poate fi stocat pe 64 de biți. Nu ar trebui să scrieți niciodată programe care să facă presupuneri cu privire la dimensiunea tipurilor de date. Cu toate acestea, vi se garantează că o cantitate minimă de stocare va fi rezervată pentru fiecare tip de date de bază. De exemplu, este garantat faptul că o valoare întreagă va fi stocată într-un minim de 32 de biți de stocare, care este dimensiunea unui „cuvânt” pe multe calculatoare.

Tipul numerelor flotante float

O variabilă declarată a fi de tip float poate fi utilizată pentru stocarea valorilor care conțin zecimale. O constantă în virgulă flotantă se distinge prin prezența unui punct zecimal. Puteți omite cifrele înainte de virgulă sau cifrele după virgulă, dar, evident, nu le puteți omite pe amândouă. Valorile 3., 125,8 și -.0001 sunt toate exemple valide de constante cu virgulă mobilă. Pentru a afișa o valoare în virgulă mobilă la terminal, se folosesc caracterele de conversie printf %f.

Constantele în virgulă mobilă pot fi exprimate și în notație științifică. Valoarea 1,7e4 este o valoare în virgulă mobilă exprimată în această notație și reprezintă valoarea 1,7 × 104. Valoarea de dinaintea literei e este cunoscută sub numele de mantisă, în timp ce valoarea care urmează se numește exponent. Acest exponent, care poate fi precedat de un semn plus sau minus opțional, reprezintă puterea de 10 cu care urmează să fie înmulțită mantisa. Astfel, în cazul constantei 2,25e-3, 2,25 este valoarea mantissei, iar -3 este valoarea exponentului. Această constantă reprezintă valoarea 2,25 × 10-3, sau 0,00225. De altfel, litera e, care separă mantisa de exponent, poate fi scrisă atât cu minusculă, cât și cu majusculă.

Pentru a afișa o valoare în notație științifică, caracterele de format %e trebuie specificate în șirul de format printf(). Caracterele de format printf() %g pot fi utilizate pentru a permite printf() să decidă dacă să afișeze valoarea în virgulă mobilă în notație normală în virgulă mobilă sau în notație științifică. Această decizie se bazează pe valoarea exponentului: Dacă este mai mică decât -4 sau mai mare decât 5, se folosește formatul %e (notație științifică); în caz contrar, se folosește formatul %f.

Utilizați caracterele de format %g pentru afișarea numerelor în virgulă mobilă – produce cea mai plăcută ieșire din punct de vedere estetic.

O constantă flotantă hexazecimală constă dintr-un 0x sau 0X de frunte, urmat de una sau mai multe cifre zecimale sau hexazecimale, urmat de un p sau P, urmat de un exponent binar cu semn opțional. De exemplu, 0x0.3p10 reprezintă valoarea 3/16 × 210 = 0,5.

Tipul de precizie extinsă double

Tipul double este foarte asemănător cu tipul float, dar este utilizat ori de câte ori intervalul oferit de o variabilă float nu este suficient. Variabilele declarate a fi de tip double pot stoca aproximativ de două ori mai multe cifre semnificative decât o variabilă de tip float. Majoritatea computerelor reprezintă valorile duble folosind 64 de biți.

Dacă nu li se spune altfel, toate constantele în virgulă mobilă sunt luate ca valori duble de către compilatorul C. Pentru a exprima în mod explicit o constantă float, adăugați fie un f, fie un F la sfârșitul numărului, după cum urmează:

12.5f

Pentru a afișa o valoare dublă, se pot utiliza caracterele de format %f, %e sau %g, care sunt aceleași caractere de format utilizate pentru a afișa o valoare float.

Tipul de caracter unic char

O variabilă char poate fi utilizată pentru a stoca un singur caracter.1 O constantă de caracter se formează prin includerea caracterului într-o pereche de ghilimele simple. Astfel, „a”, „;” și „0” sunt toate exemple valide de constante de caractere. Prima constantă reprezintă litera a, a doua este un punct și virgulă, iar a treia este caracterul zero – care nu este același lucru cu numărul zero. Nu confundați o constantă de caracter, care este un singur caracter închis între ghilimele simple, cu un șir de caractere, care este orice număr de caractere închis între ghilimele duble.

Constanta de caracter ‘\n’-caracterul newline-este o constantă de caracter validă, chiar dacă pare să contrazică regula citată anterior. Acest lucru se datorează faptului că caracterul backslash este un caracter special în sistemul C și nu contează de fapt ca un caracter. Cu alte cuvinte, compilatorul C tratează caracterul „\n” ca pe un singur caracter, chiar dacă acesta este de fapt format din două caractere. Există și alte caractere speciale care sunt inițiate cu caracterul backslash. Consultați Anexa A, „Rezumatul limbajului C”, pentru o listă completă.

Caracterele de format %c pot fi utilizate într-un apel printf() pentru a afișa valoarea unei variabile char la terminal.

Tipul de date boolean _Bool

O variabilă _Bool este definită în limbaj ca fiind suficient de mare pentru a stoca doar valorile 0 și 1. Cantitatea exactă de memorie care este utilizată nu este specificată. Variabilele _Bool sunt utilizate în programele care trebuie să indice o condiție booleană. De exemplu, o variabilă de acest tip poate fi utilizată pentru a indica dacă toate datele au fost citite dintr-un fișier.

Pe convenție, 0 este utilizat pentru a indica o valoare falsă, iar 1 indică o valoare adevărată. Atunci când se atribuie o valoare unei variabile _Bool, o valoare 0 este stocată ca 0 în interiorul variabilei, în timp ce orice valoare diferită de zero este stocată ca 1.

Pentru a facilita lucrul cu variabilele _Bool în programul dumneavoastră, fișierul header standard <stdbool.h> definește valorile bool, true și false. Un exemplu în acest sens este prezentat în programul 5.10A din capitolul 5, „Luarea deciziilor”.

În programul 3.1, sunt utilizate tipurile de date de bază din C.

Programul 3.1 Utilizarea tipurilor de date de bază

Programul 3.1 Ieșire

integerVar = 100floatingVar = 331.790009doubleVar = 8.440000e+11doubleVar = 8.44e+11charVar = WboolVar = 0;

Primul enunț al programului 3.1.1 declară variabila integerVar ca fiind o variabilă de tip întreg și, de asemenea, îi atribuie o valoare inițială de 100, ca și cum în loc de aceasta ar fi fost folosite următoarele două instrucțiuni:

int integerVar;integerVar = 100;

În a doua linie a ieșirii programului, observați că valoarea de 331,79, care este atribuită variabilei floatingVar, este de fapt afișată ca 331,790009. De fapt, valoarea reală afișată depinde de sistemul informatic specific pe care îl utilizați. Motivul acestei inexactități este modul special în care sunt reprezentate intern numerele în interiorul calculatorului. Probabil că ați întâlnit același tip de inexactitate atunci când ați avut de-a face cu numere pe calculatorul de buzunar. Dacă împărțiți 1 la 3 pe calculatorul dvs., veți obține rezultatul 0,3333333333, cu poate câțiva 3 suplimentari adăugați la sfârșit. Șirul de 3-uri este aproximarea calculatorului la o treime. Teoretic, ar trebui să existe un număr infinit de 3-uri. Dar calculatorul nu poate conține decât un număr limitat de cifre, de unde și inexactitatea inerentă a mașinii. Același tip de imprecizie se aplică și aici: Anumite valori în virgulă mobilă nu pot fi reprezentate cu exactitate în interiorul memoriei calculatorului.

Când afișați valorile variabilelor float sau double, aveți posibilitatea de a alege între trei formate diferite. Caracterele %f sunt utilizate pentru a afișa valorile într-o manieră standard. Dacă nu i se spune altfel, printf() afișează întotdeauna o valoare flotantă sau dublă cu șase zecimale rotunjite. Veți vedea mai târziu în acest capitol cum să selectați numărul de zecimale care sunt afișate.

Caracterele %e sunt utilizate pentru a afișa valoarea unei variabile float sau double în notație științifică. Din nou, sistemul afișează automat șase zecimale.

Cu caracterele %g, printf() alege între %f și %e și, de asemenea, elimină automat din afișare orice zerouri rămase. Dacă nicio cifră nu urmează virgula zecimală, nu afișează nici asta.

În penultima instrucțiune printf(), caracterele %c sunt folosite pentru a afișa caracterul unic „W” pe care l-ați atribuit lui charVar atunci când variabila a fost declarată. Amintiți-vă că, în timp ce un șir de caractere (cum ar fi primul argument pentru printf()) este închis într-o pereche de ghilimele duble, o constantă de caractere trebuie să fie întotdeauna închisă într-o pereche de ghilimele simple.

Ultimul printf() arată că o variabilă _Bool poate avea valoarea sa afișată folosind caracterele de format întreg %i.

Specificatori de tip: long, long long long, short, unsigned și signed

Dacă specificatorul long este plasat direct înaintea declarației int, variabila întreagă declarată are un interval extins pe unele sisteme informatice. Un exemplu de declarație long int ar putea fi

long int factorial;

Aceasta declară variabila factorial ca fiind o variabilă de tip long integer. Ca și în cazul variabilelor flotante și duble, precizia particulară a unei variabile long depinde de sistemul de calcul specific al computerului dumneavoastră. Pe multe sisteme, un int și un long int au același interval și ambele pot fi utilizate pentru a stoca valori întregi cu o lățime de până la 32 de biți (231 – 1, sau 2.147.483.647).

O valoare constantă de tip long int se formează prin adăugarea opțională a literei L (cu majuscule sau minuscule) la sfârșitul unei constante de tip întreg. Nu sunt permise spații între număr și L. Astfel, declarația

long int numberOfPoints = 131071100L;

declară variabila numberOfPoints ca fiind de tip long int cu o valoare inițială de 131,071,100.

Pentru a afișa valoarea unui long int folosind printf(), litera l este folosită ca modificator înaintea caracterelor de format întreg i, o și x. Aceasta înseamnă că caracterele de format %li pot fi utilizate pentru a afișa valoarea unui long int în format zecimal, caracterele %lo pot afișa valoarea în format octal, iar caracterele %lx pot afișa valoarea în format hexazecimal.

Există, de asemenea, un tip de date long long long integer, astfel încât

long long int maxAllowedStorage;

declară variabila indicată ca având precizia extinsă specificată, care este garantată a avea o lățime de cel puțin 64 de biți. În loc de o singură literă l, în șirul printf se folosesc două l-uri pentru a afișa numere întregi lungi lungi, ca în „%lli”.

Specificatorul long este, de asemenea, permis în fața unei declarații double, după cum urmează:

long double US_deficit_2004;

O constantă long double se scrie ca o constantă flotantă cu litera l sau L imediat după, cum ar fi

1.234e+7L

Pentru a afișa o constantă long double, se folosește modificatorul L. Astfel, %Lf afișează o valoare long double în notație în virgulă mobilă, %Le afișează aceeași valoare în notație științifică, iar %Lg îi spune lui printf() să aleagă între %Lf și %Le.

Specificatorul short, atunci când este plasat în fața declarației int, îi spune compilatorului C că variabila respectivă care este declarată este folosită pentru a stoca valori întregi destul de mici. Motivația pentru utilizarea variabilelor scurte este în primul rând una de conservare a spațiului de memorie, ceea ce poate fi o problemă în situațiile în care programul are nevoie de multă memorie, iar cantitatea de memorie disponibilă este limitată.

Pe unele mașini, un int scurt ocupă jumătate din cantitatea de stocare pe care o ocupă o variabilă int obișnuită. În orice caz, aveți garanția că volumul de spațiu alocat pentru un short int nu va fi mai mic de 16 biți.

Nu există nici o modalitate de a scrie explicit o constantă de tip short int în C. Pentru a afișa o variabilă short int, plasați litera h în fața oricăruia dintre caracterele normale de conversie a numerelor întregi: %hi, %ho, sau %hx. Alternativ, puteți utiliza, de asemenea, oricare dintre caracterele de conversie a numerelor întregi pentru a afișa short ints, datorită modului în care acestea pot fi convertite în numere întregi atunci când sunt trecute ca argumente la rutina printf().

Specificatorul final care poate fi plasat în fața unei variabile int este utilizat atunci când o variabilă întreagă va fi utilizată pentru a stoca numai numere pozitive. Declarația

unsigned int counter;

declară compilatorului că variabila contor este utilizată pentru a conține numai valori pozitive. Prin restricționarea utilizării unei variabile de numere întregi la stocarea exclusivă a numerelor întregi pozitive, precizia variabilei de numere întregi este extinsă.

O constantă int fără semn se formează prin plasarea literei u (sau U) după constantă, după cum urmează:

0x00ffU

Puteți combina literele u (sau U) și l (sau L) atunci când scrieți o constantă de numere întregi, astfel

20000UL

spune compilatorului să trateze constanta 20000 ca pe un long fără semn.

O constantă întreagă care nu este urmată de niciuna dintre literele u, U, l sau L și care este prea mare pentru a încăpea într-un int de dimensiuni normale este tratată de compilator ca un int fără semn. Dacă este prea mică pentru a încăpea într-un int fără semn, compilatorul o tratează ca un int lung. Dacă tot nu poate încăpea într-un long int, compilatorul îl transformă într-un long int fără semn. Dacă nu încape acolo, compilatorul o tratează ca un long long int dacă încape, și ca un unsigned long long int în caz contrar.

Când declarați variabile de tip long long long int, long int, short int sau unsigned int, puteți omite cuvântul cheie int. Prin urmare, variabila contor fără semn ar fi putut fi declarată în mod echivalent după cum urmează:

unsigned counter;

De asemenea, puteți declara variabilele de tip char ca fiind fără semn.

Calificatorul signed poate fi utilizat pentru a spune explicit compilatorului că o anumită variabilă este o cantitate cu semn. Utilizarea sa este în primul rând în fața declarației char, iar discuția ulterioară este amânată până la Capitolul 13, „Mai multe despre tipurile de date.”

Nu vă faceți griji dacă discuțiile despre acești specificatori vi se par puțin ezoterice în acest moment. În secțiunile ulterioare ale acestei cărți, multe dintre aceste tipuri diferite sunt ilustrate cu exemple reale de programe. Capitolul 13 intră în mai multe detalii despre tipurile de date și conversii.

Tabelul 3.1 rezumă tipurile de date de bază și calificatorii.

Tabelul 3.1 Tipuri de date de bază

.