Tip podatka (računarstvo)

svojstvo varijabli

U računarstvu i računalnom programiranju tip podatka svojstvo je podatka (često varijabli) koje kompilatoru ili interpreteru pruža informaciju o tome što će se s navedenim podatkom raditi, kakve će operacije biti dopušteno vršiti nad podatkom, na koji će se način podatak spremati i što podatak predstavlja.

Tipovi podataka dijele se na primitivne i složene.

Primitivni tipovi podataka uredi

Primitivni su tipovi podataka oni koje programski jezik zadano podržava. U većini jezika takvi se tipovi ne mogu proširivati ni redefinirati, a njihovi se operatori ne mogu preopterećivati.

Klasični primitivni tipovi podatka obično su:

  • boolean - sadrži vrijednost računalne točnosti ili pogrešnosti (obično bitovi 1 ili 0)
  • cijeli broj (integer) - sadrži brojeve bez decimala obično unutar vrijednosnih ograničenja
  • decimalni broj s pomičnom točkom (float) - sadrži decimalni broj jednostruke preciznosti koji obično ima stalan broj ukupnih znamenki
  • znak - sadrži jedan grafem ili simbol
  • string - sadrži niz znakova, obično ograničen maks. duljinom ili znakom \0

Primitivni tipovi podataka mogu uključivati i složene (kompozitne) tipove za koje jezik zadano pruža podršku. Kao primjer, C ne poznaje tip podatka string, i nema definirane operacije sa stringovima.[1] C# pruža ugrađenu podršku za tip string, no sam tip je definiran kao kompozitni tip sastavljen od niza znakova (tip char).[2] JavaScript zadano podržava tip string i operacije sa stringovima, i smatra stringove primitivnim tipom podatka.[3]

Boolean uredi

Tip podatka boolean ili bool je logički tip koji obično sadrži vrijednosti true ili false (obično predstavljen brojčanim zapisom 1 ili 0, respektivno). Iako je za zapis boolean vrijednosti dovoljan jedan bit memorije, neki programski jezici koriste više od toga.[4] Npr. u JavaScriptu, boolean često zauzima 4 bajta na 32-bitnim platformama, i 8 bajtova na 64-bitnim platformama, zbog načina alokacije memorije na takvim sustavima.[5]

Neki jezici također dopuštaju implicitno pretvaranje boolean tipa u cijeli broj. Rane implementacije jezika C nisu imale zasebno definiran tip boolean, već se brojčana vrijednost 0 uzimala kao logička laž (false), a bilo koja druga brojčana vrijednost kao logička istina (true).[6] Standard jezika C imena C99 uvodi boolean kao zaseban tip podatka i dio biblioteke stdbool.h.[7] Jezik C++ podržava bool kao ugrađeni tip podatka, a riječi "true" i "false" su rezervirane i mogu se koristiti samo u te svrhe.[8]

Brojevni tipovi podataka uredi

Svaki numerički tip podatka ima definiranu gornju i donju vrijednosnu granicu, odnosno raspon brojeva koje može prikazati. Spremanje ili prikaz brojeva van tog raspona može dovesti do pogreške pri kompilaciji, ili do neispravnog spremanja ili obrade podatka, ovisno o programskome jeziku. Vrijednosna granica je obično određena veličinom memorije koja je odvojena za spremanje tog tipa podatka (obično je gornja granica 2n gdje je n broj bitova korišten za spremanje tog podatka). Neki jezici također rezerviraju jedan bit za predznak broja, što smanjuje raspon vrijednosti takvog tipa podatka. Decimalni tipovi podataka uvelike se razlikuju u načinu spremanja vrijednosti i preciznosti istih, koje najčešće ovise o definiciji samog programskog jezika.

Niže je primjer brojevnih tipova i njihovih raspona u jeziku C++:

Tip podataka Vrsta Predznak Duljina (broj bajtova)[9] Opseg[9]
1 int short signed 2 -32.768 do 32.767
unsigned 2 0 do 65.535
long signed 4 –2.147.483.648 do 2.147.483.647
unsigned 4 0 do 4.294.967.295
long long signed 8 –9.223.372.036.854.775.808 do 9.223.372.036.854.775.807
unsigned 8 0 do 18.446.744.073.709.551.615
2 float 4 -3.4·10−38 do 3.4·1038
3 double 8 -1.7·10−308 do 1.7·10308

Kompozitni tipovi uredi

Znak uredi

Znak (char) je tip podatka koji može sadržavati jedno slovo, broj, simbol, interpunkcijski znak, kontrolni znak ili kakav drugi specijalizirani znak. Jezik C definira znak kao najmanji dodjeljivi dio memorije, obično veličine 8 bitova (1 bajt). Neki jezici imaju dodatnu podjelu znakova po veličini bajtova koje zauzimaju: jednobajtni tipovi prihvaćaju sve znakove u ASCII tablici, dok dvobajtni tipovi prihvaćaju sve Unicode znakove. Neki jezici visoke razine (Python, Ruby) nemaju zaseban tip podatka za char, već koriste stringove veličine 1.[10][11]

Znak može sadržavati broj, no znak neće imati istu numeričku vrijednost kao broj. Numerička vrijednost broja 5 je 5, dok je numerička vrijednost znaka "5" jednaka broju 53 (jer je znak za broj 5 u ASCII tablici 53. po redu). Operacija "5"+5 (nakon implicitne pretvorbe znaka "5" u broj 53) vratit će rezultat 58. Ovakva je pretvorba tipova podataka (cast) u jezicima poput C-a prihvatljiva, dok će u drugima izazvati pogrešku.

JavaScript ovakve konverzije prihvaća, ali rezultat operacija su ponekad neočekivani:

> 2+2
4

>"2" + "2"
22

>2+2-2
2

>"2"+"2"-"2"
20

>("2"+"2")-"2"
20

>"2"+("2"-"2")
20

String uredi

Više slijednih znakova čini string. Stringovi se obično koriste kao podatkovna reprezentacija riječi ili teksta. Programski jezici koji nemaju podršku za stringove, umjesto istih koriste nizove (polja) znakova. Takva su polja često imutabilna. Stringovi se često delimitiraju navodnicima ili jednostrukim apostrofima.

Stringovi također mogu sadržavati brojeve (čime čine brojčani string, npr. "1234"), no takvi stringovi nisu jednaki broju koji string predstavlja, a matematičke operacije između brojčanih stringova i brojeva (npr. "12"+28) izazvat će pogrešku (neće doći do implicitne pretvorbe tipova podataka).

Među programskim jezicima postoje razlike u implementaciji i obradi stringova. Najjednostavniji način je stvaranje niza (polja) znakova (ponekad ograničenih fiksnom veličinom), i označavanje kraja stringa posebnim delimiterom, često znakom znakom NUL (\0). Ovakav se string naziva "null-terminated string", ponegdje i C string (ovakav način rada koristi jezik C). Problem s ovakvom implementacijom javlja se ako string prekorači veličinu svog spremnika (ako je isti fiksne veličine):

Primjer spremnika
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
o v o j e s t r i n g ! ! ! \0
o v o j e v e ć i s t r i n

Ako se dogodi prekoračenje veličine (buffer overflow), program će nastaviti čitati susjednu memoriju dok ne naiđe na znak \0, što može dovesti do pogrešaka u radu, naročito ako program pokuša pristupiti memoriji koju nema pravo čitati. Operacijski sustav takve programe može srušiti kao mjeru prevencije štete.

Neki programski jezici (C++ i Java) koriste \0 za kraj stringova, no unutar standardnih biblioteka imaju definirane zasebne klase za obradu i spremanje stringova koji sprječavaju problem prekoračenja veličine (obično alokacijom dodatne memorije po potrebi). C++ za tu svrhu koristi klasu std::string, dok Java koristi Java.lang.String.

Među jezicima također postoji razlika u mogućnosti naknadne promjene sadržaja varijabli tipa string. Stringovi kojima nije moguće promijeniti veličinu ni sadržaj zovu se imutabilni (immutable). Za promjenu sadržaja imutabilnog stringa potrebno je direktno mijenjati računalnu memoriju (npr. C funkcijom memcpy, pri čemu treba iznimno paziti na problem prekoračenja veličine i prepisivanja susjedne memorije ako je novi string veći od spremnika). Sigurniji način rada s imutabilnim stringovima je deklaracija nove varijable ili objekta koji sadrži vrijednost novog stringa. Jezici poput JavaScripta,[12] Lue[13] i Pythona[14] koriste konstante (imutabilne) stringove. Promjenjive stringove koriste npr. C++,[15] Perl[16] i Ruby.[17]

Ostali tipovi uredi

Pokazivači uredi

Pokazivač ili referenca je tip objekta koji sprema memorijsku adresu neke varijable, konstante ili objekta. U proceduralnom programiranju, pokazivači spremaju podatak o točki ulaska u potprogram. Također se koriste za povezivanje programa i vanjskih resursa, poput DLL biblioteka (tad se nazivaju handle). Pokazivači dopuštaju čitanje i promjenu varijable na koju pokazuju. Dodjela memorijske adrese pokazivaču naziva se referenciranje. Pristup ili promjena vrijednosti varijable na dodijeljenoj adresi naziva se dereferenciranje.

Neki programski jezici podržavaju više različitih tipova pokazivača. C++ u sklopu biblioteke memory pruža pristup različitim tipovima tzv. pametnih pokazivača, originalno osmišljenim kao zamjena za garbage collector kojim jezici poput C# i Jave automatski upravljaju memorijom i objektima. C++ podržava:

  • auto_ptr: svaki pametni pokazivač tog tipa isključivi je vlasnik jednog dinamički alociranog objekta. Drugi pokazivač ovog tipa referenciran na isti objekt semantikom kopiranja (pozivom kopirnog konstruktora) preuzima vlasništvo nad objektom, čime prvi pokazivač postaje nedefiniran (pokazuje na memorijsku lokaciju na kojoj se objekt više ne nalazi). Uvođenjem unique_ptr, ovaj tip pokazivača ulazi u zastaru i nije ga preporučljivo koristiti.[18]
  • unique_ptr: dopušta preuzimanje vlasništva nad objektom samo pomoću semantike prijenosa (pozivom prijenosnog konstruktora), čime se prvi pokazivač automatski postavlja na vrijednost NULL, što sprječava nedefinirana ponašanja.[19]
  • shared_ptr: stvaranjem ovog tipa pokazivača stvara se kontrolni objekt koji automatski prati koliko drugih shared_ptr i weak_ptr pokazivača koristi alocirani objekt. Nakon što svi shared_ptr pokazivači prestanu pokazivati na objekt, objekt se dealocira iz memorije (uništava). Kontrolni objekt postoji dok god postoji weak_ptr koji pokazuje na objekt (neovisno postoji li objekt ili je uništen). Kontrolni se objekt uništava tek kad brojač weak_ptr pokazivača padne na nulu.[20]
  • weak_ptr: ovaj tip pokazivača dopušta uništavanje objekta iako postoje pokazivači na njega. Koristi se za sprječavanje kružnih ovisnosti objekata (A->B->C->A).[21]

Funkcijski tip uredi

U novijim programskim jezicima koji teže modelu univerzalne obrade podataka, funkcije je moguće proslijediti kao argumente drugim funkcijama (jezici koji to podržavaju kažemo da podržavaju funkcije prve klase). Klasično se samo podatci mogu slati kao argumenti funkcijama, pa je u svrhe facilitacije prvoklasnih funkcija uveden funkcijski tip podatka koji omogućava ovakve interakcije.

Niže je dan prikaz sintakse funkcijskog tipa nekolicine programskih jezika, uz primjer deklaracije funkcije koja omogućuje matematičku kompoziciju: f(g(x)), gdje se rezultat funkcije g uzima kao argument pri izračunu funkcije f. Parametarski polimorfizam vrsta je ad-hoc polimorfizma, što je osnova generičkog programiranja, koje omogućava pisanje tzv. funkcijskih predložaka koje jednako rade neovisno o tipu podatka koji prime.

Jezik Zapis Funkcijski potpis (deklaracija)
S prvoklasnim funkcijama i

parametarskim polimorfizmom

C# Func<α1,α2,...,αn,ρ> Func<A,C> compose(Func<B,C> f, Func<A,B> g);
Haskell α -> ρ compose :: (b -> c) -> (a -> b) -> a -> c
OCaml α -> ρ compose : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c
Scala (α1,α2,...,αn) => ρ def compose[A, B, C](f: B => C, g: A => B): A => C
Standard ML α -> ρ compose : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c
Swift α -> ρ func compose<A,B,C>(f: B -> C, g: A -> B) -> A -> C
Rust fn(α1,α2,...,αn) -> ρ fn compose<A, B, C>(f: fn(A) -> B, g: fn(B) -> C) -> fn(A) -> C
S prvoklasnim funkcijama, bez

parametarskog polimorfizma

Go func(α1,α2,...,αn) ρ var compose func(func(int)int, func(int)int) func(int)int
C++, Objective-C,

s blokovima

ρ (^)(α1,α2,...,αn) int (^compose(int (^f)(int), int (^g)(int)))(int);
Bez prvoklasnih funkcija

i parametarskog polimorfizma

C ρ (*)(α1,α2,...,αn) int (*compose(int (*f)(int), int (*g)(int)))(int);
C++11 Nije jedinstven

std::function<ρ (α1,α2,...,αn)> je generalni oblik.

function<function<int(int)>(function<int(int)>, function<int(int)>)> compose;

Ako gledamo potpis funkcije u npr. jeziku C#, tip funkcije compose je zapravo Func<Func<A,B>,Func<B,C>,Func<A,C>>.

Nulabilni tip uredi

Nulabilni tipovi mogućnost su nekih programskih jezika koji dopuštaju da se vrijednost neke varijable postavi na posebnu vrijednost NULL umjesto dozvoljenih vrijednosti toga podatkovnog tipa. Vrijednost NULL obično predstavlja vrijednost koja nedostaje ili je neispravna (primjerice izvan očekivanog raspona). U određenim jezicima, primjerice C#, primitivni tipovi podataka obično ne mogu poprimiti NULL vrijednost, ali pripadajući nulabilni tip (primjerice Nullable Integer - int?) može. Znak ? nakon deklaracije tipa podatka čini tip nulabilnim, odnosno sposobnim poprimiti vrijednost NULL.

Varijabla tipa Boolean može imati vrijednost istina ili laž, dok nulabilni Boolean dodaje i mogućnost predodžbe neodlučene ili nedefinirane vrijednosti.

Pokazivači i reference smiju se uvijek postaviti na vrijednost NULL neovisno o tipu, što označava da referenca ne vodi nikamo, nema dodijeljenu memorijsku adresu i nije vezana uz objekt.

Pokušaj izvođenja matematičkih i logičkih operacija nad varijablama koje su postavljene na NULL rezultirat će pogreškom te izbacivanjem iznimke (obično vrste InvalidOperation) ili padom programa.

Pokušaj dereferenciranja pokazivača ili pristupanje vrijednostima ili svojstvima varijable ili objekta koji su postavljeni na NULL rezultirat će padom programa zbog pokušaja pristupa nedozvoljenoj ili nepostojećoj memoriji (segmentacijska pogreška).[22] Neki jezici, poput Jave, Lispa ili C# koriste sakupljanje smeća, što će izbjeći direktnu segmentacijsku pogrešku[23] ali će baciti iznimku klasnog tipa NullPointerException koja može dovesti do pada programa. Jezik C++ podržava eksplicitno bacanje ručno stvorenih iznimki, no pokušaj pristupa NULL vrijednosti smatra se neodređenim ponašanjem[24], pa će program pasti bez iznimke.

Izvori uredi

  1. Data Types in C. GeeksforGeeks (engleski). 30. lipnja 2015. Inačica izvorne stranice arhivirana 20. prosinca 2020. Pristupljeno 31. prosinca 2020.
  2. dotnet-bot. String Class (System). docs.microsoft.com (engleski). Inačica izvorne stranice arhivirana 9. ožujka 2021. Pristupljeno 31. prosinca 2020.
  3. String - JavaScript | MDN. developer.mozilla.org. Inačica izvorne stranice arhivirana 4. siječnja 2021. Pristupljeno 31. prosinca 2020.
  4. [expr.sizeof]. eel.is. Inačica izvorne stranice arhivirana 15. siječnja 2021. Pristupljeno 31. prosinca 2020.
  5. Memory size of Javascript Boolean. DEV Community (engleski). Inačica izvorne stranice arhivirana 9. ožujka 2021. Pristupljeno 31. prosinca 2020.
  6. Brian W. Kernighan, Dennis M. Ritchie. str. 41.. The C Programming Language prvo izdanje izdanje. Prentice Hall. Englewood Cliffs, New Jersey. ISBN 0-13-110163-3
  7. Boolean type support library. devdocs.io. Inačica izvorne stranice arhivirana 2. veljače 2019. Pristupljeno 15. listopada 2020.
  8. Bool data type in C++. GeeksforGeeks. Inačica izvorne stranice arhivirana 18. rujna 2020. Pristupljeno 15. listopada 2020.
  9. a b corob-msft. Data Type Ranges. docs.microsoft.com (engleski). Inačica izvorne stranice arhivirana 9. ožujka 2021. Pristupljeno 31. prosinca 2020.
  10. Python Strings. w3schools.com. Inačica izvorne stranice arhivirana 2. siječnja 2021. Pristupljeno 1. siječnja 2021.
  11. Class: String (Ruby 2.5.3). ruby-doc.org. Inačica izvorne stranice arhivirana 12. studenoga 2020. Pristupljeno 1. siječnja 2021.
  12. Immutability in JavaScript - SitePoint. sitepoint.com (engleski). Inačica izvorne stranice arhivirana 24. siječnja 2021. Pristupljeno 1. siječnja 2021.
  13. Programming in Lua : 2.4. lua.org. Inačica izvorne stranice arhivirana 2. veljače 2021. Pristupljeno 1. siječnja 2021.
  14. Leung, Wendy. 9. lipnja 2019. Mutability and Immutability in Python — Let's Break It Down. Medium (engleski). Inačica izvorne stranice arhivirana 28. svibnja 2020. Pristupljeno 1. siječnja 2021.
  15. Lemire, Author Daniel. Are your strings immutable?. Daniel Lemire's blog (engleski). Inačica izvorne stranice arhivirana 28. veljače 2021. Pristupljeno 1. siječnja 2021.
  16. Are Perl strings immutable?. Stack Overflow. Inačica izvorne stranice arhivirana 29. srpnja 2015. Pristupljeno 1. siječnja 2021.
  17. Understanding Mutable Objects & Frozen Strings. RubyGuides (engleski). 3. siječnja 2016. Inačica izvorne stranice arhivirana 2. prosinca 2020. Pristupljeno 1. siječnja 2021.
  18. std::auto_ptr - cppreference.com. en.cppreference.com. Inačica izvorne stranice arhivirana 10. travnja 2021. Pristupljeno 1. siječnja 2021.
  19. std::unique_ptr - cppreference.com. en.cppreference.com. Inačica izvorne stranice arhivirana 12. studenoga 2020. Pristupljeno 1. siječnja 2021.
  20. std::shared_ptr - cppreference.com. en.cppreference.com. Inačica izvorne stranice arhivirana 28. prosinca 2020. Pristupljeno 1. siječnja 2021.
  21. std::weak_ptr - cppreference.com. en.cppreference.com. Inačica izvorne stranice arhivirana 16. siječnja 2021. Pristupljeno 1. siječnja 2021.
  22. Debugging Segmentation Faults and Pointer Problems - Cprogramming.com. www.cprogramming.com. Inačica izvorne stranice arhivirana 10. srpnja 2022. Pristupljeno 14. ožujka 2022.
  23. Dhurjati, Dinakar; Kowshik, Sumant; Adve, Vikram; Lattner, Chris. 2003. Memory safety without runtime checks or garbage collection. Proceedings of the 2003 ACM SIGPLAN conference on Language, compiler, and tool for embedded systems - LCTES '03 (engleski). ACM Press. San Diego, California, USA. : 69. doi:10.1145/780732.780743. ISBN 978-1-58113-647-0. Inačica izvorne stranice arhivirana 16. svibnja 2022. Pristupljeno 14. ožujka 2022.
  24. Undefined behavior - cppreference.com. en.cppreference.com. Inačica izvorne stranice arhivirana 1. travnja 2022. Pristupljeno 14. ožujka 2022.. undefined behavior - [...], null pointer dereference, [...]

Vanjske poveznice uredi

Sestrinski projekti uredi

 Zajednički poslužitelj ima još gradiva o temi tip podatka (računarstvo)