Do sada smo naučili šta su promenljive, kako se deklarišu, kako se inicijalizuju i koje tipove podataka možemo koristiti.

Sada prelazimo na jednu veoma važnu temu koju početnici često zanemare, a koja je ključna za ozbiljno razumevanje programiranja:

memorija i opseg promenljivih

Kada napišemo:

int broj = 10;

naizgled deluje jednostavno.

Ali u pozadini se dešava mnogo toga:

  • rezerviše se memorija,
  • promenljiva dobija lokaciju u memoriji,
  • dodeljuje joj se vrednost,
  • i program definiše gde ta promenljiva može da se koristi.

Ako ovo ne razumemo, kasnije će biti veoma teško razumeti:

  • funkcije,
  • nizove,
  • pokazivače,
  • reference,
  • dinamičku memoriju,
  • objektno orijentisano programiranje.

Ova lekcija predstavlja jednu od najvažnijih osnova ozbiljnog C++ programiranja.

U ovoj lekciji naučićemo:

  • šta je memorija u kontekstu programa,
  • gde se čuvaju promenljive,
  • šta je opseg promenljive (scope),
  • lokalne i globalne promenljive,
  • životni vek promenljive,
  • i najčešće greške početnika.

Šta je memorija?

Računar koristi memoriju za čuvanje podataka tokom rada programa.

Kada program radi, sve informacije moraju negde biti sačuvane:

  • brojevi
  • tekst
  • korisnički unos
  • rezultati izračunavanja
  • privremeni podaci
  • objekti

Memoriju možemo zamisliti kao veliki skup malih kutija.

Svaka kutija ima adresu.

Primer:

Adresa      Vrednost
1001        10
1002        25
1003        99

Kada napravimo promenljivu:

int broj = 10;

program rezerviše deo memorije i tamo smešta vrednost:

10

Promenljiva kao memorijska lokacija

Promenljiva nije sama vrednost.

Promenljiva je ime koje koristimo da pristupimo memorijskoj lokaciji.

Primer:

int godine = 21;

Programer vidi:

godine

Računar vidi nešto poput:

adresa 0x61FF10

na kojoj je sačuvano:

21

Dakle:

ime promenljive je oznaka.

Stvarna vrednost je u memoriji.

Koliko memorije zauzimaju tipovi?

Različiti tipovi koriste različitu količinu memorije.

Tipično:

char    → 1 bajt
bool    → 1 bajt
int     → 4 bajta
float   → 4 bajta
double  → 8 bajtova

Napomena:

Tačne veličine mogu zavisiti od sistema i kompajlera.

Ali za početnike je ovo dobar model.

Primer:

char slovo = 'A';

zauzima manje memorije nego:

double pi = 3.1415926535;

Šta je opseg promenljive?

Opseg (scope) određuje:

gde promenljiva postoji i gde joj možemo pristupiti

Ako promenljiva postoji samo unutar jednog bloka koda:

ne možemo joj pristupiti van tog bloka.

Ovo je veoma važan koncept.

Lokalna promenljiva

Primer:

#include <iostream>
using namespace std;

int main() {
    int broj = 10;

    cout << broj;

    return 0;
}

Ovde promenljiva:

broj

postoji samo unutar:

main()

Ako pokušamo van:

cout << broj;

program neće raditi.

Zašto?

Jer promenljiva više nije vidljiva.

To je:

lokalni opseg

Scope i vitičaste zagrade

Vitičaste zagrade:

{
}

definišu blok.

Promenljiva deklarisana unutar bloka postoji samo tamo.

Primer:

if (true) {
    int x = 5;
}

Ovde:

x

postoji samo unutar if bloka.

Pogrešno:

cout << x;

van bloka.

Primer greške

#include <iostream>
using namespace std;

int main() {
    if (true) {
        int broj = 100;
    }

    cout << broj;

    return 0;
}

Greška:

broj

nije dostupan.

Zašto je ovo korisno?

Zato što sprečava haos.

Zamisli veliki program sa stotinama promenljivih.

Ako bi svaka bila dostupna svuda:

nastao bi potpuni haos.

Scope omogućava organizaciju i bezbednost.

Globalne promenljive

Promenljiva deklarisana van svih funkcija je:

globalna promenljiva

Primer:

#include <iostream>
using namespace std;

int broj = 50;

int main() {
    cout << broj;

    return 0;
}

Ovde:

broj

je dostupan svuda u programu.

Lokalna vs globalna promenljiva

Lokalna:

int main() {
    int x = 10;
}

Postoji samo u funkciji.

Globalna:

int x = 10;

int main() {
}

Postoji u celom programu.

Šta je shadowing?

Veoma važna tema.

Primer:

int broj = 100;

int main() {
    int broj = 20;

    cout << broj;
}

Rezultat:

20

Zašto?

Lokalna promenljiva “prekriva” globalnu.

To se zove:

variable shadowing

Početnicima ovo često pravi konfuziju.

Životni vek promenljive

Promenljiva ne postoji zauvek.

Lokalna promenljiva:

nastaje kada program uđe u blok.

Nestaje kada izađe iz bloka.

Primer:

if (true) {
    int x = 5;
}

Nakon zatvaranja bloka:

x

više ne postoji.

Globalna promenljiva:

postoji od početka do kraja programa.

Memorija i funkcije

Primer:

void test() {
    int broj = 10;
}

Kada se funkcija završi:

broj

nestaje.

To je veoma važno.

Kasnije ćemo ovo povezati sa stack memorijom.

Privremene promenljive

Primer:

int zbir = a + b;

Program često koristi i privremene memorijske lokacije.

To se dešava automatski.

Programer ih ne vidi direktno.

Problem prevelikog korišćenja globalnih promenljivih

Početnici vole:

“Da bude dostupno svuda.”

Ali to je loša praksa.

Zašto?

Jer:

  • otežava debugovanje
  • povećava rizik grešaka
  • pravi zavisnosti
  • čini kod nepreglednim

Globalne promenljive treba koristiti pažljivo.

Prikaz memorijske adrese

Možemo videti adresu promenljive.

Primer:

#include <iostream>
using namespace std;

int main() {
    int broj = 25;

    cout << &broj;

    return 0;
}

Operator:

&

ovde znači:

adresa promenljive.

Rezultat može biti:

0x61FF10

To pokazuje gde je promenljiva u memoriji.

Najčešće greške početnika

1. Korišćenje promenljive van opsega

Pogrešno:

if (true) {
    int x = 5;
}

cout << x;

2. Nerazumevanje lokalne/globalne promenljive

Početnik očekuje da lokalna promenljiva bude dostupna svuda.

3. Shadowing konfuzija

int broj = 100;
int main() {
    int broj = 10;
}

4. Previše globalnih promenljivih

Loša praksa.

5. Pogrešno razumevanje memorije

Promenljiva nije sama vrednost.

Ona je ime za memorijsku lokaciju.

Praktičan primer

#include <iostream>
using namespace std;

int globalniBroj = 100;

int main() {
    int lokalniBroj = 20;

    cout << globalniBroj << endl;
    cout << lokalniBroj << endl;

    if (true) {
        int privremeniBroj = 5;
        cout << privremeniBroj << endl;
    }

    return 0;
}

Ovde imamo:

  • globalni opseg
  • lokalni opseg
  • blok opseg

Zašto je ova tema ključna?

Bez razumevanja memorije i scope-a biće teško razumeti:

  • funkcije
  • reference
  • pokazivače
  • objekatne instance
  • heap i stack
  • parametre funkcija

Ovo je temelj ozbiljnog C++.

Rezime

U ovoj lekciji naučili smo:

Promenljiva:

  • zauzima memoriju
  • ima adresu
  • ima opseg
  • ima životni vek

Vrste scope-a:

lokalni

vidljiv samo u bloku

globalni

vidljiv svuda

Ključne opasnosti:

  • scope greške
  • shadowing
  • loša upotreba globalnih promenljivih

Ovo je jedna od najvažnijih teorijskih osnova C++ jezika.

U narednoj lekciji prelazimo na:

„Konstante i const ključna reč”

Mini test

  1. Šta promenljiva zapravo predstavlja?
    a) Direktno vrednost
    b) Memorijsku lokaciju
  2. Šta je lokalna promenljiva?
    a) Dostupna svuda
    b) Samo u svom bloku
  3. Šta je globalna promenljiva?
    a) Samo u if bloku
    b) Dostupna u celom programu
  4. Šta radi:
cout << &broj;

a) Ispisuje vrednost
b) Ispisuje adresu

  1. Šta je shadowing?
    a) Brisanje promenljive
    b) Lokalna promenljiva prekriva globalnu

Zadaci za vežbu

  1. Napravi lokalnu promenljivu.
  2. Napravi globalnu promenljivu.
  3. Prikaži adresu promenljive.
  4. Napravi scope grešku namerno.
  5. Testiraj shadowing.

Domaći zadatak

Napravi program koji koristi:

  • jednu globalnu promenljivu
  • jednu lokalnu
  • jednu promenljivu u if bloku

Prikaži:

  • njihove vrednosti
  • adresu svake dostupne promenljive
  • i objasni koje postoje gde.

Pristupačnost