четвртак, 13. август 2015.

Tipovi podataka u C programskom jeziku

U C programskom jeziku "object"objekat označava mesto u memoriji gde sadržaj može da predstavlja neku vrednost. Većina objekata ima imena i nazive tih objekata zovemo "variables"promenjive. Svaka promenjiva mora imati svoj tip podatka kako bi program znao kako da čuva i obrađuje različite vrednosti podataka. To radimo deklarisanjem promenjivih. Celi brojevi i brojevi sa pokretnim zarezom za čuvanje i obradu istih u memoriji su totalno različiti podaci; zauzimaju memoriju i obrađuju se drugačije. Vi možete čak deklarisati vašu promenjivu i na nivou "signed"pozitivnog i "unsigned"negativnog broja. Sve se to odražava na memoriju koju koristite. Tipove podataka u C programskom jeziku možete i da dodajete vašem programu uvođenjem raznih datoteka zaglavlja.


( Tipovi u C programskom jeziku )

Tipovi podataka u C programskom jeziku se dele na:

1. Osnovni tipovi
  •  Standardni i prošireni celobrojni tipovi
  •  Realni i kompleksni tipovi sa pokretnim zarezom
2. Nabrojivi tipovi

3. Tip void

4. Izvedeni tipovi
  •  Pokazivači
  •  Nizovi
  •  Strukture
  •  Unije
  •  Funkcije
Zapamtite da u C programskom jeziku se mora voditi više računa o tipovima podataka. To je opširna i kompleksna stvar kojoj su C programeri posvetili ogromnu važnost decenijama. Postoji čitava naučna oblast koja se bavi samo tipovima podataka i nju zovemo Tipologija. 

Koji su to celobrojni tipovi podataka? 

U C programskom jeziku u suštini postoji 5 celobrojnih tipova i to su:
  •  char
  •  int
  •  short
  •  long
  •  long long
Ali svaki od njih može biti i signed i unsigned i u zavisnosti na koji način ste deklarisali neku promenjivu zavisi i kako će biti njeno smeštanje u memoriji i koliko će zauzimati iste.

_Bool tip podatka se takođe tretira kao celobrojni tip podatka gde se vrednost "true" - tačno tretira kao 1 dok se "false" - netačno tretira kao 0. Ukoliko hoćete da koristite bool, true i false potrebno je da uključite datoteku zaglavlja stdbool.h

Kod tipa char vi odlučujete da li taj tip tumačite kao znakovni kod ili nešto drugo. Možete sa njim obavljati aritmetičke operacije.

Koji su to tipovi podataka sa pokretnim zarezom?

Tipove podataka sa pokretnim zarezom delimo na promenjive jednostruke, dvostruke i proširene preciznosti i to su:
  •  float
  •  double
  •  long double
Što se tiče kompleksnih tipova, oni potiču od uvedene datoteke zaglavlja complex.h koja pored tipova podataka sa pokretnim zarezom sadrže i aritmetičke funkcije. Tako dobijete:
  •  float _Complex
  •  double _Complex
  •  long double _Complex
Ovakvim kompleksnim tipovima podataka možete dodeliti i matematičke formule koje sadrže i trigonometrijske formule.

Šta su Nabrojivi tipovi?

Nabrojivi tipovi ili nabrajanjaenumerations, enumereted types su celobrojni tipovi koje programer definiše sam u programu. Nabrajanje počinje definisanjem ključne reči enum iza koga sledi identifikator tipa i lista mogućih vrednosti. Oni su u suštini konstantne celobrojne vrednosti tipa int. Npr.

enum dani { ponedeljak, utorak, sreda, četvrtak, petak, subota, nedelja }

Prva konstantna vrednost „ponedeljak“ ima vrednost 0, zatim „utorak“ ima vrednost 1 itd. zato što im nije dodeljena nikakva druga vrednost. 

Šta je tip void?

Specifikator tipa void označava da nema dostupnih vrednosti tog tipa. Ne možete deklarisati konstantu ili promenjivu tipa void. Međutim tip void se koristi kad funkcija ne vraća nikakvu vrednost ili nema parametre. Pokazivač vrednosti tipa void * predstavlja adresu objekta ali ne i njegov tip.

Šta su pokazivači?
 
U C programskom jeziku se najviše koriste "pointers" - pokazivači i to je osnova C programskog jezika. Međutim pokazivače je teško razumeti; najbolje će te ih shvatiti ako zamislite da je pokazivač promenjiva koja sadrži adresu memorije neke druge promenjive. Ali znajte da se pokazivač koristi i na objektima, funkcijama i na druge pokazivače. Na pokazivač gledajte kao na referencu. Npr. zašto bi ste ređali veliki broj zapisa kad je bolje sortirati listu pokazivača na njih umesto da premeštate sve zapise po memoriji? Upotreba pokazivača je raznovrsna i kompleksna. Ono što važi za pokazivač na promenjivu nije isto i za pokazivač na konstantu. Kod konstante ne možete da menjate vrednost pokazivača. Ali za početak istraživanja pokazivača pokušajte razumeti navedeni kod, jer će te pokazivače jedino naučiti kroz mnogobrojne primere u praksi.

#include <stdio.h>

int main()
        int* pc;

        int c;

        c = 22;

        printf("Memorijska adresa od c:%d\n",&c);

        printf("Vrednost c:%d\n\n",c);

        pc = &c;

        printf("Memorijska adresa od pokazivača pc:%d\n",pc);

        printf("Sadržaj pokazivača pc:%d\n\n",*pc);

        c = 11;

        printf("Memorijska adresa od pokazivača pc:%d\n",pc);

        printf("Sadržaj pokazivača pc:%d\n\n",*pc);

        *pc=2;

        printf("Memorijska adresa od c:%d\n",&c);

        printf("Vrednost c:%d\n\n",c);

        return 0;



Kad pokrenete program dobiće te ovo:

Memorijska adresa od c: 2686784
Vrednost c: 22

Memorijska adresa od pokazivača pc: 2686784
Sadržaj pokazivača pc: 22

Memorijska adresa od pokazivača pc: 2686784
Sadržaj pokazivača pc: 11

Memorijska adresa od c: 2686784
Vrednost c: 2
Šta su nizovi?

Niz"array" je skup objekata određenog tipa koji se čuvaju u susednim memorijskim lokacijama koje zovemo elementi niza. U C programskom jeziku se nizovi implementiraju preko pokazivača i ne podržavaju asocijativne nizove i u njemu je indeks prvog elementa 0. Primer upotrebe najjednostavnijeg niza pogledajte u kodu ovog programa ovde.

Šta su strukture?

Kad želite da grupišete podatke koje opisuju neki objekat i hoćete da ih smestite u jedan određen zapis, tada napravite strukturu. Struktura je jednostavno tip podatka koji predstavlja format zapisa sa svim imenima i tipovima njegovih članova. Kad definišete tip vaše strukture možete je koristiti kao bilo koji drugi tip podataka. Npr.

struct Pesma { 
        char pesma[64];

        char izvodjac[32];

        short trajanjePesme;

};


Šta je Unija?

Unija vam je slična strukturi samo što članovi unije dele istu memorijsku lokaciju; odnosno svi članovi unije počinju na istoj adresi. To u prevodu znači da možete definisati uniju sa mnogo članova ali samo jedan član može imati vrednost u datom trenutku. Unija vam omogućava da koristite memorijsku lokaciju na različite načine. Uniju definišete isto kao i strukturu, samo ključnu reč struct zamenite sa union. Npr. u ovom primeru unija može da sadrži ili ceo ili realan broj ali ne može oba.

typedef union ceo_ili_realan {

         int ceo;

        double realan;

} Ceo_ili_realan;


Šta su funkcije? 

C programski jezik nema klase i zato se sve instrukcije nalaze u funkcijama"functions". Funkcije shvatite kao delove programa koje definišete samo jednom dok ih možete izvršavati više puta u vašem programu. Svaka funkcija obavlja određeni zadatak. Glavna funkcija u svim vašim programima je funkcija Main() i ona se uvek izvršava prva na početku vašeg programa. Sve ostale funkcije su pod programi ili zavisne procedure. Funkcije mogu da vraćaju vrednost ili ne. Pogledajte kod najjednostavnijeg primera deklarisanja, pravljenja i korišćenja funkcije:

#include <stdio.h>

/* definicija funkcije koja sabire dva broja */

int zbir (int a, int b)

{

        return a + b;

}


int main()

{

/* poziv funkcije i prikaz zbira */

        printf("%d\n", zbir(3,5));

        return 0;

}


Koje su minimalne i maksimalne vrednosti numeričkih tipova u C programskom jeziku?

Za ovu svrhu najbolje je da isprogramiramo mali program koji će nam sam prikazati vrednosti, jer se vrednosti numeričkih tipova nisu uvek isti; što zavisi od računara, uređaja, memorije, ponekad i kompajlera. Prvo uvozimo nekoliko datoteka zaglavlja jer oni sadrže makroe koji nam mogu pokazati minimalne i maksimalne vrednosti od nekih numeričkih tipova.

/*    Data Types

       Manuel Radovanovic

       www.manuelradovanovic.com      */

#include <stdio.h>

#include <limits.h>

#include <float.h>

#include <sys/types.h>

#include <inttypes.h>


Zatim pravimo dva makroa, čisto da bi nam bar delimično vrednosti bile što preciznije.

#define MAX_OF(type) \

(((type)(~0LLU) > (type)((1LLU<<((sizeof(type)<<3)-1))-1LLU)) ? (long long unsigned int)(type)(~0LLU) : (long long unsigned int)(type)((1LLU<<((sizeof(type)<<3)-1))-1LLU))

#define MIN_OF(type) \

(((type)(1LLU<<((sizeof(type)<<3)-1)) < (type)1) ? (long long int)((~0LLU)-((1LLU<<((sizeof(type)<<3)-1))-1LLU)) : 0LL) 


U glavnu funkciju Main() unesite sledeći kod:

int main(void)
{
         system("clear");

         printf(" MINIMUM AND MAXIMUM VALUES OF NUMBER DATA TYPES IN C  PROGRAMMING LANGUAGE\n\n");

         printf("INTEGER DATA TYPES:\n\n");

         printf(" The number of bits in a byte %d\n\n", CHAR_BIT);

         printf("char data types:\n\n");

         printf(" char = from %lld to %llu\n", MIN_OF(char), MAX_OF(char));

         printf(" unsigned char = from %lld to %llu\n", MIN_OF(unsigned char), MAX_OF(unsigned char)); 
         printf(" signed char = from %lld to %llu\n\n", MIN_OF(signed char), MAX_OF(signed char));

         printf("short data types:\n\n");

         printf(" short = from %lld to %llu\n", MIN_OF(short), MAX_OF(short));

         printf(" unsigned short = from %lld to %llu\n", MIN_OF(unsigned short), MAX_OF(unsigned short));

         printf(" signed short = from %lld to %llu\n\n", MIN_OF(signed short), MAX_OF(signed short));

        
printf("int data types:\n\n");
         printf(" int8_t = from %lld to %llu\n", MIN_OF(int8_t), MAX_OF(int8_t));

         printf(" uint8_t = from %lld to %llu\n\n", MIN_OF(uint8_t), MAX_OF(uint8_t));

         printf(" int16_t = from %lld to %llu\n", MIN_OF(int16_t), MAX_OF(int16_t));

         printf(" uint16_t = from %lld to %llu\n\n", MIN_OF(uint16_t), MAX_OF(uint16_t));

         printf(" int32_t = from %lld to %llu\n", MIN_OF(int32_t), MAX_OF(int32_t));

         printf(" uint32_t = from %lld to %llu\n\n", MIN_OF(uint32_t), MAX_OF(uint32_t));

         printf(" int64_t = from %lld to %llu\n", MIN_OF(int64_t), MAX_OF(int64_t));
 
         printf(" uint64_t = from %lld to %llu\n\n", MIN_OF(uint64_t), MAX_OF(uint64_t));

        
printf(" int = from %lld to %llu\n", MIN_OF(int), MAX_OF(int));

         printf(" unsigned int = from %lld to %llu\n", MIN_OF(unsigned int), MAX_OF(unsigned int));

         printf(" signed int = from %lld to %llu\n\n", MIN_OF(signed int), MAX_OF(signed int));

        
printf("long data types:\n\n");

         printf(" long = from %li to %li\n", LONG_MIN, LONG_MAX);

         printf(" ulong_max = %li\n\n", ULONG_MAX);

        
printf(" llong = from %llu to %llu\n", LLONG_MIN, LLONG_MAX);

         printf(" ullong_max = %llu\n\n", ULLONG_MAX);

        
printf("time in seconds:\n\n");
         printf(" time_t = %lld..%llu\n\n", MIN_OF(time_t), MAX_OF(time_t));

        
printf("size of objects:\n\n");

        
printf(" size_t = %lld..%llu\n", MIN_OF(size_t), MAX_OF(size_t));

         printf(" ssize_t = %lld..%llu\n", MIN_OF(ssize_t), MAX_OF(ssize_t));

        
printf("proccess IDs:\n\n");

        
printf(" pid_t = %lld..%llu\n\n", MIN_OF(pid_t), MAX_OF(pid_t));

         printf("signed integer type that is big enough to hold a pointer:\n\n");

        
printf(" intptr_t = %lld..%llu\n\n", MIN_OF(intptr_t), MAX_OF(intptr_t));

         printf("REAL FLOATING POINT TYPES:\n\n");

        
printf(" float = from %E to %E\n", FLT_MIN, FLT_MAX);

         printf(" float - number of digits: %d\n\n", FLT_MANT_DIG);

         printf(" double = from %E to %E\n", DBL_MIN, DBL_MAX);

         printf(" double - number of digits: %d\n\n", DBL_MANT_DIG);

         printf(" long double = from %Le to %Le\n", LDBL_MIN, LDBL_MAX);
        
         printf(" long double - number of digits: %d\n\n", LDBL_MANT_DIG);

return 0;

}


I sad kad pokrene navedeni program, dobićete sledeće rezultate:

MINIMUM AND MAXIMUM VALUES OF NUMBER DATA TYPES IN C PROGRAMMING LANGUAGE

INTEGER DATA TYPES:


The number of bits in a byte 8

char data types:

char = from -128 to 127

unsigned char = from 0 to 255

signed char = from -128 to 127

short data types:

short = from -32768 to 32767

unsigned short = from 0 to 65535

signed short = from -32768 to 32767

int data types:

int8_t = from -128 to 127

uint8_t = from 0 to 255

int16_t = from -32768 to 32767

uint16_t = from 0 to 65535

int32_t = from -2147483648 to 2147483647

uint32_t = from 0 to 4294967295

int64_t = from -9223372036854775808 to 9223372036854775807

uint64_t = from 0 to 18446744073709551615

int = from -2147483648 to 2147483647

unsigned int = from 0 to 4294967295

signed int = from -2147483648 to 2147483647

long data types:

long = from -9223372036854775808 to 9223372036854775807

ulong_max = -1

llong = from 9223372036854775808 to 9223372036854775807

ullong_max = 18446744073709551615

time in seconds:

time_t = -9223372036854775808..9223372036854775807

size of objects:

size_t = 0..18446744073709551615

ssize_t = -9223372036854775808..9223372036854775807

proccess IDs:

pid_t = -2147483648..2147483647

signed integer type that is big enough to hold a pointer:

intptr_t = -9223372036854775808..9223372036854775807

REAL FLOATING POINT TYPES:

float = from 1.175494E-38 to 3.402823E+38

float - number of digits: 24

double = from 2.225074E-308 to 1.797693E+308

double - number of digits: 53

long double = from 3.362103e-4932 to 1.189731e+4932

long double - number of digits: 64

hacker@hacker:~/workspace/c$


Kako to sve izgleda možete pogledati i na video-u: 

  
( C - Tutorial - 4. Data Types )