Predstavljanje podataka i operacije nad njima (C)
#fax #cs/prog/c [deo jezika C]
Promenljive
- moraju biti deklarisane pre korišćenja.
- pridružen prostor u memoriji
- ime: prvi simbol _ ili slovo, ostale _, slova ili cifre
Deklaracija:
int a, b;
Deklaracija sa inicijalizacijom:
int a = 3;
Konstanta:
const double G = 9.81;
double const G = 9.81;
Tipovi podataka
Celobrojne tipovi u rastućem poretku prema dužine:
short
int //standardni tip
long
long long
Dodatno pre tima moguće napisati:
signed //označeni - isto kao što ne pisati ništa
unsigned //neoznačeni
Tip za karaktere, ali u suštini jednobitni celobrojni tip:
(signed/unsigned) char
Pokretan zarez (IEEE754 standard - uklj.
float
double //standardni tip
long double
Druge tipovi
bool //logički tip - true/false
void //ništa
Konstante i konstantne izrazi
Na primer: 2, 207, 3.14, 1.4e6, '9', 034
Celobrojne:
12345 - int (-> long -> unsigned long)
// u zavisnosti od veličine broja
12345l - long
12345L - long long
12345u - unsigned int
12345ul - unsigned long
U oktalnom i heksadekadnom sistemu (moguće kombinovati sa l, L, u, ... )
056 - oktalni (int)
0x1f - heksadekadni (int)
Negativne konstante ne postoje: koristi se unitarni operator -.
Na primer -678
U pokretnom zarezu:
13.45 - double
1e-2 - double // = 0.01
1.45e6 - double // = 1450000.0
.3 - double // = 0.3
2. - double // = 2.0
13.45f - float // (f ili F)
13.45l - long double // (l ili L)
Mogu biti i pozitivne i negativne .
Simboli (karakteri)
'a' - int // = 97
'A' - int // = 65
'0' - int // = 48
Specijalni simboli:
'\n' — new line
'\t' — horizontal tab
'\v' — vertical tab
'\\' — \
'\?' — ?
'\'' — '
'\"' — "
'\012' — oktalni broj
'\x12' — heksadekadni broj
'\0' — vrednost
Konstantne izrazi
Na primer: 4 + 3 * 5
Konstantne izrazi izračunavaju se tokom prevođenja programa.
Operatori i izrazi
Arnost operatora — broj operanada na koje se pimenjuje.
- unarni
- prefiksni (
-x) - postfiksni (
x++)
- prefiksni (
- binarni (
x + y) - ternarni (
x ? y : z)
Operatori nad brojevima:
- aritmetičke
- logičke
- relacijske
- Unarni postfiksni pa unarni prefiksni pa binarni
- Aritmetički pa relacijski pa logički
- Kao u matematici:
( ),*i/i%,+i- <i<=i>i>=pa==i!=- Najmanji prioritet:
? :pa dodele pa,
Asocijativnost operatora:
- leva:
- desna:
- neasocijativan: zabranjeno uzastopnost ponavljanje.
Operator dodele =
x = ...; //x je izmenjiva l-vrednost (promenljiva)
promena vrednosti objekata na levoj strani je sporedni efekat (side effect).
Ima desnu asocijativnost.
Dodela ima vrednost:
x = y = 3; //y = 3 ima vrednost 3 koja se dodeljuje x-u
int a;
double b = a = 3.5;
Prvo a-u se dodeljuje vrednost 3;
a = 3.5 ima vrednost 3;
Posle b-u se dodeljuje vrednost a = 3.5 tj. 3;
Rezultat: a = 3; b = 3.0
Aritmetičke operatori
+ — binarni operator sabiranja;
- — binarni operator oduzimanja;
* — binarni operator množenja;
% — binarni operator ostatka pri deljenju (oba operanda celi);
/ — binarni operator:
- celobrojnog deljenja, ako su oba operanda celi;
- deljena, ako je bar jedan operand broj u pokretnom zarezu;
+ — unarni operator;
- — unarni operator promene znaka;
Svi aritmetički operatori gore imaju levu asocijativnost, dole — desnu.
++ — prefiksno ili postfiksno inkrementiranje;
-- — prefiksno ili postfiksno dekrementiranje;
i = 5;
I slučaj II slučaj
x = i++; x = ++i;
Rezultat
i == 6 i == 6
x == 5 x == 6
i++ ima vrednost i do inkr.; i-- ima vrednost i do dekr.;
++i ima vrednost i posle inkr.; --i ima vrednost i posle dekr.
Relacijski operatori
== — jednako;
!= — različito;
< — manje;
<= — manje ili jednako;
> — veće;
>= — veće ili jednako;
Imaju levu asocijativnost.
Ako je tačno ima vrednost 1 (int).
Ako nije tačno ima vrednost 0 (int).
Na primer:
Logički operatori
! — logičko ne;
&& — logičko i;
|| — logičko ili;
Svaka ne-nula vrednost se računa kao1
Na primer:
!0je1;!1je0;!9.2je0;5 && 4.3je1;3.1 && 0je0;10 || 0je1;0 || 0je0.
Lenjo izračunavanja
Sleva nadesno:
U operatorima&&i||prvo se računa leva strana i ako rezultat ne zavisi od desne strane, desna strana i ne računa se.Na primer:
( neće biti uvršeno) ( sigurno će biti uvršeno) (slično neće biti uvršeno)
Bitovski operatori
~ — bitovska negacija;
& — bitovsko i;
| — bitovsko ili;
^ — bitovski XOR;
<< — pomeranje bitova ulevo;
>> — pomeranje bitova udesno;
x << k — pomeranje bitova broja x sa k mesta ulevo.
x >> k — pomeranje bitova broja x sa k mesta udesno:
- ako je
xtipaintaritmetičko — na viši (oslobođeni) bitovi stavlja se bit znaka. - ako je
xtipaunsignedlogičko — na viši (oslobođeni) bitovi stavlja se0.
x može biti konstanta ili promenljiva. << i >> ne menjaju x.
Složeni operatori dodele +=, -=, *=, %=, /=, &=, |=, <<=, >>=
izraz1 op= izraz2 isto što i izraz1 = izraz1 op ipraz2
Operator uslova izraz1 ? izraz2 : izraz3
Prvo se izračunava izraz1.
Ako je ne-nula, onda se izračunava izraz2 i to je vrednost operatora.
Inače se izračunava izraz3 i to je vrednost operatora.
Operator zarez , (u deklaraciji nije operator)
for (i = 10, j = 0; i < j; i++, j--) { ...; }
ima najniži prioritet;
računaju se i leva i desna strana;
vrednost operatora je vrednost desne strane.
x = 1, 2; je isto što i x = 2;
x = 3, y = 5; je isto što i x = 3; y = 5;
Operator sizeof
veličina tipa ili promenljive u bajtovima;
vrača vrednost tipa size_t (sličan sa unsigned).
double a;
size_t x = sizeof(a);
size_t y = sizeof(int);
Konverzije tipova
— menja se tip izraza, ne menja se tip promenljivih.
- Eksplicitna konverzija (na zahtev programera)
Operator kastovanja:(tip) izraz
— prefiksni unarni operator
- Implicitna konverzija (izvršava se automatski po potrebi)
- konverzija u tip leve strane:
int a = 46;
double b;
b = a;
// pre upisivanja vrednost a se konvertuje u double.
- aritmetičke operatori se ne primenjuju na
charishort
char a = 2, b = 3, c;
c = a + b;
// vrednost a se konvertuje u int, vrednost b se konvertuje u int, računa se zbir, vrednost zbira se konvertuje u char i upisuje se u c.
- aritmetički i logički operatori zahtevaju operandi u istom tipu, tako jedan od operanada se konvertuje u tip drugog, koji ima "bogatiji" tip.
char a = 2; double b = 7.9;
b = (a + 5.6f) / b;
// vrednost a se konvertuje u float, računa se zbir, vrednost zbira se konvertuje u double, računa se količnik i rezultat se upisuje u b.
Promocija — konverzija u "bogatiji" tip — obično ne dolazi do gubitka.
Na primer može doći do gubitka pri konverziji velikog broja tipa long u tip double;
Democija — konverzija u "siromašniji" tip — često dolazi do gubitka.
Na primer pri konverziji broja tipa double ili float u tip int odsecaju se decimale: int a = 8.31f — a će dobiti vrednost 8.
Nizovi i niske
Nizovi
Deklaracija niza:
tip ime_niza[dimenzija];
dimenzija mora da bude konstantan ceo broj;
na primer: a[10], tada su elementi niza a[0], a[1], ..., a[9],
ili
tip ime_niza[] = {el0, el1, ..., elN};
moguće navesti svih N+1 elemenata u { };
na primer:
int b[] = {1, 3, 11, 4, 8};
sizeof(ime_niza); # veličina celog niza u bajtovima
Nemoguće dodeljivati/menjati nizove, ali moguće menjati svaki element niza.
ime_niza bez [ ] konvertuje se u pokazivač na nulti element niza.
Elementi niza su u memoriji uređeni uzastopno.
nulti element je na adresi ime_niza
prvi element je na adresi ime_niza + 1 * sizeof(tip)
drugi element je na adresi ime_niza + 2 * sizeof(tip)
...
n-ti element je na adresi ime_niza + n * sizeof(tip)
Treba paziti da ne pristupamo elementima van niza,
na primer b[-1] ili b[6]
Niske
Niska je niz karaktera koji se završava terminirajućem nulom '\0'.
Sledeće inicijalizacije niski su ekvivalentne:
char s1[] = "Zdravo";
char s2[] = {'Z', 'd', 'r', 'a', 'v', 'o', '\0'};
'x' = 120 je karakter;
"x" = {'x', '\0'} je niska;
'\0' = 0
printf("547", " + as"); je isto što i printf("547 + as");
biblioteka za rad sa niskama <string.h>:
dužina niske: strlen(a)
kopiranje niske a u nisku b: strcpy(b, a)
(duža b mora da bude dovoljna, inače će doći do greške ili do neočekivanog ponašanja)
Višedimenzioni nizovi
tip ime_niza[dim_1][dim2]...;
Na primer:
char a[2][3] = {
{1, 2, 3},
{4, 5, 6},
}
Poštuje se uzastopnost u memoriji.
Niz a u memoriji će biti predstavljen isto kao i sledeći niz
int b = {1, 2, 3, 4, 5, 6}
ali pristup elementima je različit.
a pokazuje na nulti element niza — niz od tri int-a.
Korisnički definisani tipovi
Strukture struct
— objedinjavaju jednu ili više promenljivih, ne nužno istog tipa.
Definicija strukture:
struct ime_structure {
//deklaracija promenljivih, nizova i drugih već definisanih struktura;
};
Primer:
struct razlomak {
int brojilac;
int imenilac;
};
posle toga postoji tip struct razlomak;
deklaracija promenjivih:
struct razlomak a = {1, 2}, b, c;
struct razlomak niz[100];
Istovremeno definisanje strukture i deklaracija promenljivih (važi za sve korisnički definisane tipove):
struct razlomak { int brojilac, imenilac; } a = {1, 2}, b, c;
Veličina strukture u bitovima:
sizeof(struct razlomak);
sizeof(b);
Operatori . i -> — pristupanje elementima strukture.
— najviši prioritet, leva asocijativnost.
a.imenilac = 6;
niz[45].brojilac = 90;
Ako je pa pokazivač na promenljivu a (pa = &a;).
Tada moguće pristupiti direktno:
pa->brojilac = 34;
isto što i:
(*pa).brojilac = 34;
Polja bitova
— struktura u kojoj za svaku promenljivu određen broj bitova.
struct nugaonik {
unsigned char br_strana : 4;
unsigned char boja : 2;
unsigned char popunjen : 1;
}
Promenljiva će zauzeti 4+2+1 = 7 bitova;
broj bajtova mora biti celi zato sizeof(struct nugaonik) će biti 1 (bajt).
Unije union
— istovremeno korišćenje istog prostora nekolikim promenljivima.
Primer definicije unije:
union student {
double plata;
char index[7];
};
deklaracija promenjivih:
union student a, matf[300];
Moguće koristiti samo jednu promenljivu u nekom trenutku;
a.plata = 3500.0
printf("%L\n", a.plata); // >> 3500.0
printf("%s\n", a.indeks); // odštampaće 3500.0 - broj u pokretnom zarezu kao niz od 7 char-ova
Često se koristi kao član strukture radi uštede prostora:
struct info {
long licni_broj;
char ime[31], prezime[31];
union {
double dug;
int broj_telefona;
} dodatno;
};
struct info niz[100];
niz[32].dodatno.dug = 89.32;
Nabrojivi tipovi enum
— tip sa malim brojem dopuštenih vrednosti;
Primer definicije:
enum znak_karte {
KARO, PIK, HERC, TREF
};
KARO ima vrednost 0, PIK — 1, HERC —2, TREF — 3.
Korišćenje:
enum znak_karte a, b = HERC;
a = TREF;
Vrednosti KARO, PIK, ... nemoguće promeniti, samo zadati u definiciji:
enum rimske_cifre {
I = 1, II, III, IV, V, X = 10, XI, XII
} c, niz[8];
U primeru I = 1, II = 2, III = 3, IV = 4, V = 5, X = 10, XI = 11, XII = 12.
Novo ime tipa typedef
Primeri definicije:
typedef int Length;
Length len, maxlen; // deklaracija promenljivih
typedef struct {
int x, y, z;
} Point;
Point a = {1, 0, 4}, b; // deklaracija promenljivih
b.z = 9;
