- 1 1. Mis on globaalmuutuja?
- 2 2. Globaalmuutujate kasutamise näited
- 3 3. Globaalmuutujate jagamine mitme faili vahel
- 4 4. Globaalmuutujate eelised ja puudused
- 5 5. Parimad tavad
- 6 6. Alternatiivsed disainiviisid C keeles globaalmuutujate asemel
- 7 7. Millal kasutada globaalmuutujaid?
- 8 8. Muud tehnikad globaalmuutujatega töötamiseks
- 9 9. Alternatiivsed disainimustrid globaalmuutujatele
- 10 10. Kokkuvõte
1. Mis on globaalmuutuja?
Globaalmuutuja põhialused
Globaalmuutuja on muutuja, millele pääseb ligi kogu programmi ulatuses ning mis deklareeritakse funktsioonide väliselt. See eraldatakse mällu programmi käivitamisel ja säilitab oma väärtuse kuni programmi lõpuni. Seetõttu on see mugav andmete jagamiseks erinevate funktsioonide vahel.
Erinevus lokaalse muutujaga
Lokaalmuutuja on kättesaadav ainult selle funktsiooni sees ning vabastatakse mälust pärast funktsiooni lõppu. Seevastu globaalmuutuja kehtib kogu programmis ja sellele pääseb ligi kõikjal. Selline ulatus toob aga kaasa ka riski, et väärtust muudetakse kogemata.
Globaalmuutuja deklareerimine
Globaalmuutuja deklareeritakse funktsioonide väliselt. Järgnevas näites on globalVar
deklareeritud globaalse muutujana ja seda kasutatakse main
funktsioonis.
#include <stdio.h>
int globalVar = 10; // globaalmuutuja
int main() {
printf("%dn", globalVar); // globaalse muutujaga töötamine
return 0;
}
2. Globaalmuutujate kasutamise näited
Põhiline näidis-kood
Globaalmuutujate abil on mugav jagada andmeid mitme funktsiooni vahel. Näiteks kui soovite lugurit (counter) muuta erinevates funktsioonides, on globaalmuutuja kasutamine lihtne lahendus.
#include <stdio.h>
int counter = 0; // globaalmuutuja
void incrementCounter() {
counter++; // suurenda globaalse muutujat
}
int main() {
incrementCounter();
printf("Counter: %dn", counter); // Väljund: Counter: 1
return 0;
}
Praktilised kasutusnäited
Mänguarenduses kasutatakse globaalmuutujaid näiteks punktide või mängija elude hoidmiseks. Samuti sobivad need programmiülese seadistuste või silumisinfo (debug-flag) hoidmiseks.
3. Globaalmuutujate jagamine mitme faili vahel
Globaalmuutujate jagamine extern
võtmesõnaga
Suuremate programmide puhul jagatakse kood tihti mitme faili vahel. Kui soovite globaalmuutujat kasutada teises failis, tuleb kasutada extern
võtmesõna, mis näitab, et muutuja asub mõnes muus failis.
#include <stdio.h>
int globalVar = 100; // globaalse muutujana määratletud
int main() {
extern void printGlobalVar();
printGlobalVar(); // globaalse muutujaga töötava funktsiooni väljakutse
return 0;
}
#include <stdio.h>
extern int globalVar; // globaalse muutujana deklareeritud
void printGlobalVar() {
printf("Global Variable: %dn", globalVar);
}
Olulised märkused ja veavältus
Initsialiseerimine tuleks teha ainult põhilises failis; teistes failides kasutada ainult extern
-deklareerimist. Mitu initsialiseerimist võib põhjustada linkimise vea. Kui kasutatakse sama globaalmuutujat mitmes failis, on soovitatav deklareerida see päisefailis ja kaasata päis kõikidesse failidesse, kus muutujat kasutatakse.
4. Globaalmuutujate eelised ja puudused
Eelised
- Andmete jagamine: Globaalmuutujatega on lihtne jagada andmeid funktsioonide vahel. Argumentide edastamine pole vajalik, mistõttu kood on lihtsam.
- Mugavus: Väikestes programmides aitab globaalmuutujate kasutamine muuta koodi lihtsamaks ning arendus on kiirem.
Puudused
- Vigade risk: Kuna muutujale pääseb ligi kõikjalt, on oht, et selle väärtust muudetakse tahtmatult. Suuremates programmides võib see põhjustada vigu.
- Lugevuse langus: Kui globaalseid muutujaid on liiga palju, muutub koodi mõistmine raskemaks ja hooldus keerukamaks.
Õige kasutus ja piirangud
Globaalse muutujate kasutamist saab piirata static
võtmesõnaga, mis piirab muutuja ulatust vaid konkreetse failiga.
static int fileScopedVar = 5; // Kättesaadav ainult selles failis
5. Parimad tavad
Minimeeri globaalmuutujate kasutamist
Globaalmuutujaid tuleks kasutada vaid hädavajadusel. Andmeid võiks edastada funktsioonide argumentide või tagastusväärtuste kaudu, et vähendada globaalmuutujate vajadust.
Kasuta funktsioonide või failide ulatust
Kohalike muutujate ja failisiseste muutujate kasutamine piirab globaalse ulatusega muutujate vajadust. See muudab muutujate haldamise lihtsamaks ja suurendab koodi turvalisust.
Globaalmuutujate haldus ja jõudlus
Liiga palju globaalmuutujaid võib suurendada mälukasutust ning mõjutada programmi jõudlust. Suurtes projektides on oluline hallata globaalseid muutujaid hästi: deklareeri need päisefailis ning kasuta ühtseid nimetamise reegleid, et parandada loetavust ja hooldatavust.
Alternatiivid globaalmuutujatele
Soovitav on kasutada andmestruktuure või teisi disainiviise globaalse muutuja asemel. Näiteks võib andmeid kapseldada struktuuridesse ning edastada funktsioonide kaudu.
#include <stdio.h>
typedef struct {
int score;
int life;
} GameData;
void updateGameData(GameData* data) {
data->score += 10;
data->life--;
}
int main() {
GameData game = {0, 3};
updateGameData(&game);
printf("Score: %d, Life: %dn", game.score, game.life);
return 0;
}
6. Alternatiivsed disainiviisid C keeles globaalmuutujate asemel
Staatiliste muutujate kasutus
C keeles puudub otsene objektorienteeritud singleton-muster, kuid staatiliste muutujatega saab saavutada sarnast käitumist. Staatilise muutujaga saab hoida initsialiseeritud andmeid ainult ühes kohas ja jagada neid kogu programmi ulatuses.
#include <stdio.h>
typedef struct {
int configValue;
} Config;
Config* getConfigInstance() {
static Config instance = {0}; // staatiline muutuja, initsialiseeritakse üks kord
return &instance;
}
int main() {
Config* config = getConfigInstance();
config->configValue = 10;
printf("Config Value: %dn", getConfigInstance()->configValue);
return 0;
}
Teised alternatiivid
- Struktuuride ja funktsioonide kasutamine: Andmete jagamiseks võib andmed kapseldada struktuuridesse ning edastada neid funktsioonides. Nii on andmete haldus läbipaistvam.
- Funktsiooni argumendid ja tagastusväärtused: Andmete jagamiseks võib neid edastada funktsioonide argumentide kaudu või tagastada väärtusena. See suurendab funktsioonide iseseisvust ja taaskasutatavust.
7. Millal kasutada globaalmuutujaid?
Mugavus väikestes programmides
Väikestes programmides või ajutistes skriptides võib globaalmuutujate kasutamine muuta koodi lihtsamaks ja arenduse kiiremaks. Kuid see on õigustatud vaid siis, kui programm on väike ja muutujaid on vähe.
Jõudluse kaalutlused
Mõnel juhul parandab globaalse muutuja kasutamine ligipääsukiirust ja programmi jõudlust. Näiteks andmete puhul, millele pöördutakse tihti. Kuid tuleb leida tasakaal jõudluse ja loetavuse vahel.
8. Muud tehnikad globaalmuutujatega töötamiseks
Staatilised globaalsed muutujad
Failiulatuses staatilisi globaalseid muutujaid kasutades saab piirata nende nähtavust ainult selle failiga. See välistab soovimatu ligipääsu teistest failidest.
static int staticGlobalVar = 42; // staatiline muutuja ainult selles failis
static
võtmesõna abil saab muutuja ulatust piirata ainult failisisesele kasutusele, sobib, kui soovite jagada andmeid vaid programmi osas.
Kompileerimisjärgne optimeerimine
Kompilaator suudab optimeerida globaalse muutuja kasutamist. Kui andmetele tuleb tihti ligi pääseda, võib globaalse muutuja kasutamine olla optimaalseim valik. Näiteks tsüklites tihti kasutatavad andmed võivad globaalse muutujana anda jõudluseelise.
9. Alternatiivsed disainimustrid globaalmuutujatele
Modulariseerimine ja funktsioonipointerid
C keeles saab kasutada funktsioonipointereid ja mooduleid, et andmete jagamist ja töötlust kapseldada ilma globaalmuutujateta. Näiteks saab funktsioonipointerite abil dünaamiliselt funktsioone välja kutsuda ning luua paindlikke lahendusi.
#include <stdio.h>
void printHello() {
printf("Hello, World!n");
}
int main() {
void (*funcPtr)() = printHello; // funktsioonipointer
funcPtr(); // funktsiooni väljakutse pointeri kaudu
return 0;
}
10. Kokkuvõte
Globaalmuutujad on mugav viis jagada andmeid kogu programmis, kuid nende kasutamisel tuleb olla ettevaatlik. Valesti hallates võivad need põhjustada vigu ja muuta programmi raskesti loetavaks või hooldatavaks. C keeles on mitmeid tehnikaid ja alternatiivseid lahendusi, nagu staatilised muutujad, funktsioonipointerid ja struktuuride kapseldamine. Õigete meetodite valimisel on võimalik kirjutada turvalisi ja tõhusaid programme.