Tipul de date

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Un tip de date , în informatică , indică setul de valori pe care o variabilă sau rezultatul unei expresii le poate asuma și operațiunile care pot fi efectuate asupra acestor valori. De exemplu, a spune că variabila X este de tip „întreg” înseamnă a afirma că X poate presupune ca valori numai numere întregi (aparținând unui anumit interval) și că numai anumite operații sunt permise pe aceste valori (pentru exemplu operații aritmetice elementare).

Fiecare limbaj de programare vă permite să utilizați, mai mult sau mai puțin explicit, o serie de tipuri de date predefinite de uz general și, de obicei, oferă instrumente pentru definirea de noi tipuri pe baza nevoilor specifice ale unui program .

De asemenea, se poate întâmpla, în timp ce scrieți un program, să fie util sau necesar să „traduceți” o variabilă de un anumit tip într-o variabilă de alt tip (operația se numește casting tip ): unele limbi oferă construcții sintactice pentru acest lucru se face, dar în alte cazuri este necesar să se scrie o funcție care leagă valorile unui tip de cele ale celuilalt.

Tastare statică și dinamică

Vorbim de „ tastare statică ” atunci când o variabilă este asociată rigid cu un tip care rămâne același pe tot parcursul programului și de „ tastare dinamică ” atunci când o variabilă poate schimba tipul în timpul executării programului.

De exemplu, C este un limbaj tipizat static; C ++ și Java permit atât tastarea statică, cât și dinamica; Lisp , Visual Basic și Python sunt limbaje tastate dinamic.

Pentru a vedea cum funcționează verificarea de tip, luați în considerare următorul exemplu de pseudocod :

 var x; // (1)
 x: = 5; // (2)
 x: = "salut"; // (3)

În acest exemplu: (1) declară variabila x, (2) asociază x cu valoarea întreagă 5, (3) asociază x cu valoarea șirului „salut” (aici se presupune că „întreg” și „șir” sunt două tipuri). În majoritatea limbajelor de tip static, un astfel de cod ar fi ilegal, deoarece (2) și (3) asociază valori de diferite tipuri cu variabila x; dimpotrivă, un limbaj cu tastare total dinamică ar găsi acest cod perfect legal. În acest din urmă caz, evident, declarația inițială din (1) ar fi trebuit să specifice, cu o anumită sintaxă, tipul de asociat cu x. Un exemplu în Java ar putea fi după cum urmează:

 int x; // (1)
 x = 5; // (2)
 x = "salut"; // (3) → respins de compilator

Un limbaj tastat dinamic vă permite să capturați „erori de tip” (adică erori datorate utilizării incorecte a valorilor pe care o variabilă le poate asuma) numai în timpul executării programului.

De exemplu, luați în considerare următorul pseudocod:

 var x = 5; // (1)
 var y = "salut"; // (2)
 var z = x + y; // (3)

În acest exemplu: (1) asociază x cu valoarea 5, (2) asociază cu y valoarea "salut" și (3) încearcă să adauge x și y. Într-un limbaj tastat dinamic, în timpul executării fragmentului de pseudocod indicat, variabila x ar fi (în acel moment) de tip întreg cu valoarea 5, în timp ce variabila y ar fi de tip șir cu valoarea „salut” (aici se presupune că „întreg” și „șir” sunt două tipuri). Dacă definiția limbajului nu permite operația de adăugare între un întreg și un șir, va fi raportată o eroare în timpul executării programului.

Tipuri de date

Tipurile de date pot fi clasificate în funcție de structură în tipuri atomice sau primitive și tipuri derivate . Tipurile primitive sunt tipuri simple care nu pot fi descompuse, precum numerele întregi sau booleenii; fiecare limbă tastată le are. Tipurile derivate sunt obținute din tipuri atomice prin intermediul operatorilor corespunzători furnizați de limbă: includ tipuri structurate ( înregistrări ) sau tablouri , dar și indicatori de tip fix (în limbi precum C ), tipuri de funcții (în special în limbi funcțional ), clase de limbaje orientate obiect și așa mai departe.

O altă clasificare împarte tipurile de date în predefinite și definite de utilizator . S-ar putea crede că tipurile predefinite coincid cu tipurile atomice, în timp ce tipurile definite de utilizator sunt în esență cele derivate: în realitate cele două clasificări nu sunt perfect superpozabile - de exemplu, enumerările în limbi precum C sunt tipuri atomice definite de utilizator, în timp ce întotdeauna în C șirurile sunt tipuri derivate (din tipul de caracter ), dar predefinite de limbă. Pe de altă parte, este aproape întotdeauna adevărat că tipurile definite de programator sunt neapărat tipuri derivate.

Unele dintre cele mai comune tipuri de date în limbajele de programare sunt următoarele.

Booleeni

Tipul boolean are doar două valori: adevărat („adevărat”) și fals („fals”). Acestea sunt utilizate în special în expresiile condiționate pentru a controla fluxul de execuție și pot fi manipulate cu operatorii booleni AND, OR, NOT și așa mai departe.

Deși, teoretic, un singur bit ar fi suficient pentru a stoca o valoare booleană, din motive de eficiență, se folosește în general un cuvânt întreg de memorie , ca și pentru numere întregi „mici” (un cuvânt de memorie de 8 biți, de exemplu, poate stoca numere de la 0 la 255, dar tipul boolean utilizează doar valorile 0 și 1).

Numere

Tipurile de date numerice includ numere întregi și numere raționale în virgulă mobilă , care sunt abstracții ale seturilor de numere corespunzătoare din matematică. Aproape toate limbile includ tipuri de date numerice ca tipuri predefinite și oferă un număr de operatori aritmetici și de comparație pe ele.

Spre deosebire de seturile numerice de matematică, tipurile de date numerice sunt adesea limitate (adică includ un număr reprezentabil maxim și minim ), trebuind să fie conținute într-un singur cuvânt ( cuvânt ) de memorie.

Personaje și corzi

Tipul de caracter conține un caracter, de obicei ASCII , stocat într-un octet. Cu toate acestea, în ultimii ani apare noul standard Unicode pentru caractere, care oferă 16 biți (care corespund în general unui cuvânt de memorie) pentru reprezentarea unui singur caracter. Multe limbi tradiționale s-au adaptat la acest standard emergent introducând, pe lângă tipul „caracter pe 8 biți”, un nou tip „caracter pe 16 biți”, numit uneori caracter larg ( limbajul Java este în schimb un exemplu de limbaj modern care gestionează direct toate caracterele în format Unicode).

Șirurile sunt secvențe de caractere de lungime finită. Limbile pot oferi operațiuni pentru concatenarea siruri de caractere , selectarea subșirurile unui șir dat, etc.

Enumerări

Enumerațiile sunt seturi finite de identificatori , de obicei specificate de programator. În limbi precum C și C ++ este posibil să se definească tipuri de enumerare cu o sintaxă similară cu următoarea:

 enum Culoare {ROȘU, VERDE, ALBASTRU};

În acest caz, o variabilă de tipul „Culoare” poate presupune doar valorile „ROȘU”, „VERZ” și „ALBASTRU”. Comparativ cu tehnicile tradiționale de gestionare a unor tipuri similare de date, care pur și simplu prevedeau adoptarea unei convenții numerice implicite (de exemplu, scriu „1” pentru a însemna „roșu”, „2” pentru a însemna „verde” și așa mai departe), tipurile enumerate oferă o lizibilitate mai mare și o mai bună abstractizare a datelor .

Indicatori

Pictogramă lupă mgx2.svg Același subiect în detaliu: Pointer (programare) .

Valorile de tip pointer sunt adrese de memorie ale variabilelor , obiectelor (sau altor elemente ale programului). L ' operator cu care, dat un pointer, accesarea obiectului indicat este respectivul operator dereferențiere (dereferențiere). Multe limbi oferă, de asemenea, un operator „invers”, numit deseori adresa operatorului , care, dată fiind o variabilă, permite obținerea adresei. Un set extins de operații ale indicatorului este furnizat de limbile cu aritmetica indicatorului .

Utilizarea indicatoarelor este adesea necesară pentru a construi structuri de date complexe cu o formă imprevizibilă și / sau variabilă în timp, cum ar fi grafice , arbori , liste și așa mai departe; în plus, indicatorii pot fi utilizați pentru a realiza trecerea parametrilor prin referință în limbi care nu-l oferă ca mecanism nativ. Dacă sunt utilizate fără discriminare, totuși, indicatoarele pot duce la dezvoltarea de software foarte complexă și, mai important, pot duce la erori de programare greu de identificat . Din acest motiv, unele limbi, inclusiv Java, încearcă să limiteze utilizarea acestuia.

Referințe

Unele limbi oferă un mecanism de tip pointer, dar caracterizat prin dereferențierea implicită; variabilele de acest tip se numesc referințe .

Caracteristicile referințelor sunt diferite în diferite limbi, dar, în general, au o caracteristică comună: din punct de vedere sintactic, tipurile de referință nu necesită utilizarea unui operator de dereferențiere și nu au o „adresă a” operatorului; în consecință, aritmetica indicatorului nu este posibilă pe referințe.

Exemple de limbaje care îl utilizează, cu caracteristici diferite, sunt C ++ (vezi și referința (C ++) ) și Java .

Matrice

Pictogramă lupă mgx2.svg Același subiect în detaliu: Array .

O matrice este o secvență finită de elemente aparținând unui tip dat, indexate de un număr întreg.

Record

Pictogramă lupă mgx2.svg Același subiect în detaliu: Înregistrare (tip de date) .

Înregistrările , numite și tupluri sau structuri , sunt agregate de tipuri de date mai simple, a căror compoziție poate fi definită de utilizator. Este necesară o înregistrare pentru a menține informații eterogene conexe: de exemplu, acestea ar putea fi utilizate pentru a modela înregistrările arhivei unei biblioteci, care trebuie să conțină șiruri pentru titlul unei cărți și numele autorului acesteia, dar și o valoare numerică indicarea colocării; fiecare dintre aceste informații ( câmpuri de înregistrare) poate fi accesată independent prin specificarea numelui său: în multe limbi, în special în cele derivate din C , această operațiune este specificată folosind operatorul. (punct):

 cout << tab . autor ; // tipărește numele autorului
cout << tab . titlu ; // tipărește titlul cărții

Deoarece în multe cazuri este necesar să se impună consistența datelor conținute într-o înregistrare, anumite limbi vă permit să definiți tipuri de date abstracte , care sunt în esență înregistrări a căror structură fizică nu este vizibilă și care poate fi manipulată doar de anumite operațiuni de încredere (nu neapărat în niciun caz) specificat într-o interfață . Tipurile de clase tipice programării orientate pe obiecte se bazează, de asemenea, pe tipuri de date abstracte.

Tipuri de funcții

În multe limbi, o variabilă poate conține un pointer către o funcție . Prin dereferențierea variabilei va fi apoi posibil să invocăm o funcție definită la runtime.

Pentru a vă asigura că funcția este invocată cu argumente de tipul corect, tipul unei variabile de funcție este definit de semnătura funcției, adică de tipul valorii returnate și de tipul și ordinea argumentelor funcției.

În consecință, funcțiile pot returna funcții la fel ca alte tipuri de date și pot lua funcții ca argumente, ca și alte tipuri de date. Un exemplu în Perl :

 sub generează acumulator {
  acumulatorul meu $ = 0 ;
  returnează sub { 
      $ inc = schimb ;
      $ acumulator + = $ inc ;
      returnează $ acumulator ; 
  }
}

$ acumulator1 = generateAccumulator ();
$ acumulator2 = generateAccumulator ();
$ acumulator1 -> ( 4 );
imprima $ accumulator2 -> ( $ accumulator1 -> ( 1 )) . „și” . $ acumulator1 -> ( 3 );

Tipuri generice sau șabloane

Constructorii de tip văzuți până acum sunt construcții definite de limbajul de programare și pot fi utilizate de programator pentru a construi noi tipuri de date pe baza tipurilor existente.

În unele limbi este de asemenea posibil să se specifice tipuri generice (numite și parametrice sau șablon ), care sunt în fapt constructori de tipul definit de programator. Nu pot fi utilizate direct în programe, ci trebuie aplicate unuia sau mai multor tipuri existente (care sunt, prin urmare, parametrii constructorului) pentru a genera noi tipuri de date. Relația dintre constructorul de tip și tipul concret poate fi deci văzută în analogie cu cea dintre clasă și obiect în programarea orientată pe obiecte.

Apoi va fi posibil să se definească șablonul de listă , care poate fi apoi instanțiat pe numere întregi pentru a obține tipul listei de numere întregi sau pe booleni pentru a obține o listă de booleeni .

Principalul beneficiu este acela de a nu fi obligat să dea o definiție diferită a listelor pentru fiecare tip de conținut posibil, pentru a reduce codul replicat.

În limbajele orientate obiect, șabloanele sunt constructori de clase parametrice cu privire la unul sau mai multe tipuri și, prin urmare, includ și codul pentru a opera clasele în sine. Ca atare, acestea sunt deosebit de potrivite pentru definirea tipurilor de "containere" (cum ar fi listă, set, copac), care includ atât structura de date pentru a reprezenta containerul în memorie, cât și operațiunile de accesare a membrilor acestuia.

În acest fel, codul pentru definirea și accesul la structurile de date se face ortogonal atât în ​​ceea ce privește tipurile de date stocate, cât și în ceea ce privește algoritmii care operează pe structurile de date. Această abordare a fost urmată organic de biblioteca STL , inclusă în limbajul C ++.

Tipuri de limbi

  • Untyped : Limbajele de programare mai simple, cum ar fi limbajele de mașină ale majorității computerelor sau calculul lambda pur sunt numite netipate deoarece nu oferă tipuri sau, conform unui alt punct de vedere, permit utilizarea singurului tip care conține toate valorile posibile. De exemplu, limbajele mașinilor manipulează configurații de biți , pentru care sarcina interpretării (adică stabilirea operațiunilor care au sens pe o valoare și care nu) revine în întregime programatorului: aceeași configurație a biților din memoria computerului ar putea indica valori diferite din punct de vedere conceptual după tip, cum ar fi numărul întreg 0, indicatorul nul sau instrucțiunea NOP goală ( fără operație ). În lambda, funcțiile de calcul sunt manipulate folosind aceleași funcții și același termen poate reprezenta valoarea întreagă 0, falsul boolean („fals”) sau funcția care, date două valori, le aruncă pe prima și o returnează pe a doua.
  • Tastat : În limbile tastate este necesar să asociați adnotări sau să declarați declarații variabilelor, expresiilor și mai general termenilor programului. Aceste adnotări de tip, în funcție de limbă, trebuie specificate în mod explicit de către programator sau pot fi generate automat de către interpret sau compilator . Atribuirea unui tip de date unei variabile vă permite să rezolvați ambiguitățile văzute pentru limbajele netipate: dacă ați încerca să utilizați o valoare întreagă unde este necesar un indicator, veți primi în mod normal o eroare de tip sau o încălcare a tipului .

Control tip: limbi puternic și slab tastate

Verificarea tipului ” este procedura care permite verificarea dacă sunt îndeplinite constrângerile impuse de tipuri. Această verificare poate avea loc atât în ​​timpul compilării, iar în acest caz vorbim de „verificare statică” (în engleză „static check”), cât și în timpul execuției programului, iar în acest caz vorbim de „verificare dinamică” ( în engleză engleză „dynamic check”). Unele limbi operează anumite verificări de tip la momentul compilării, iar altele în timpul executării.

Dacă o limbă impune reguli stricte asupra tipurilor, împiedicând orice utilizare a datelor neconforme cu tipul specificat în faza de declarație, se spune că este „ puternic tastat ”; în caz contrar, este „slab tastat”.

Elemente conexe

Alte proiecte

Controlul autorității LCCN (EN) sh2015001723 · GND (DE) 4011149-0
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT