Aldagai (informatika)

thumb|Kode Bitarra
Programazioan, **aldagai** bat biltegiratze sistemako espazio batek (ordenagailuaren memoria nagusia) eta espazio horri lotutako izen sinboliko batek (identifikatzaile batek) osatzen dute. Beste modu batean esanda, **aldagai** bat bit multzo edo datu mota jakin baterako izena duen gordailu bat da(zenbaki osoa, koma higikorra, katea, etab...). Aldagai bat, azkenean, memoria-helbide batekin lotu edo identifikatu daiteke. Aldagaia programan objektu bat erreferentziatzen duen izen bat da. Objektua, berriz, memorian gordetzen den datu-egitura edo instantzia bat da. Ordenagailuaren iturburu-kodeko identifikatzailea balio bati lotu ahal izango da kodea exekutatzerakoan, eta, beraz, aldagaiaren balioa alda daiteke programa exekutatu ahala.

Programazioan, aldagaiaren kontzeptua ez dator beti bat matematikako aldagaien kontzeptuarekin. Matematikako aldagaiak abstraktuak dira, eta ez dute erreferentziarik objektu fisiko bati, hala nola biltegiratze leku bati. Programazioan, aldagai baten balioa ez da nahitaez ekuazio edo formula baten parte, matematiketan bezala. Ordenagailu-programazioan, aldagaiei maiz izen luzeak ematen zaizkie, erabilerarako deskriptiboagoak izan daitezen, matematikan aldiz, aldagaiek normalean izen laburrak izaten dituzte, karaktere bakar edo bikoitzekin, transkripzioa eta manipulazioa laburrago egiteko.

Konpiladoreek aldagaien izen sinbolikoak datuen kokapen errealekin ordezkatuko dituzte. Aldagai baten izena, mota eta kokalekua askotan finko mantentzen den arren, gordetako balioak programa exekutatzen ari den bitartean alda daitezke.

Aldagaiek ezin dituzte adierazpenak ("for" edo "if", esaterako) edo daturik itzultzen ez duten funtzioak gorde. Bestela, errorea itzuliko dute.

## Erazagupen eta hasierapen 
**Erazagutzea(Declaration)** aldagai bat programan existitzen dela adieraztea da, bere izena eta mota zehaztuz, baina baliorik esleitu gabe. Horrela, konpiladoreak aldagai horretarako memoria-eremu bat erreserbatzen du. eskuinera|frameless|290x290px

```java
int zenbakia; //"zenbakia" izeneko aldagai bat definitu da, baina baliorik ez zaio esleitu.
```
**Hasieratzea(Initialization)** aldagai erauzagutu bati lehen balio bat esleitzea da. 
```java
zenbakia = 10;  // "zenbakia" aldagaiari balioa eman(aldez aurretik erauzagutu).
```
Posible da bi akzioak aldi berean egitea ere. 
```java
int zenbakia = 10;  // Erazagutzea eta hasieratzea batera.
```

## Aldagai luzeera 
Aldagaiak bi luzeera mota izan ditzazkete:

*Finkoa: Programaren exekuzioan zehar ez da haren tamaina aldatuko. Aldagai gehienek luzeera finkoa dute, salbuespen batzuk izan ezik, hala nola aldagai bildumek (array-ak) edo kateek.

```java
int zenbaki = 42; double kopurua = 25.75;
```

*Aldagarria: Neurria exekuzioan zehar alda daitekeenean. Gehienetan datu-bildumak erabiltzen dira.

```java
// ArrayList batean balioak gehitu import java.util.ArrayList;
ArrayList zerrenda = new ArrayList<>();
zerrenda.add(10);
zerrenda.add(20);
zerrenda.add(30);
```

```java
// String aldagai bati testua gehitu
String testua = "Kaixo"; 
testua = testua + " Mundua";
```

## Aliasing 
Aldagaiaren biltegiratze lekua objektu desberdinek erreferentziatu dezakete, "aliasing" gisa ezagutzen den egoera. Identifikatzaileetako bat erabiliz aldagaiari balio bat esleitzeak beste identifikatzaileetatik eskuratzen den balioa aldatuko du. Hau da, balioa gordeta dagoen objektuak izen bat baino gehiago har dezake, eta, horietako izen bat erabiliz objektuaren barruko datu bat aldatzen bada, gainontzeko izenei ere aldatutako balioa agertuko zaie, objektu hori erreferentziatzen duten guztiak berdinak direlako. Horrela, objektuaren erreferentzia partekatua duten identifikatzaileek aldaketa berak erakutsiko dituzte.
```java
// Aliasing adibidea: objektu berdina bi identifikatzaile desberdinekin (suposatu implementatua:  class Pertsona { String izena; })
public class AliasingAdibidea {
    public static void main(String[] args) {
        Pertsona p1 = new Pertsona();
        p1.izena = "Ane"; // p1 objektuari balioa esleitu

        Pertsona p2 = p1; // p2-ri p1 objektuak erreferentziatzen duen objektu bera esleitu

        // p2-ri balioa aldatu
        p2.izena = "Jon";   

        // Bi identifikatzaileek balio bera erakutsiko dute  
        System.out.println("p1 izena: " + p1.izena); // p1 izenaren balioa: Jon  
        System.out.println("p2 izena: " + p2.izena); // p2 izenaren balioa: Jon  
    }
}
```

## Aldagaiaren ezaugarriak 
Aldagai baten **esparruak** programan aldagai hori non erabil daitekeen deskribatzen du, eta **iraupenak** programaren exekuzioan zein unetan duen aldagaiak balio (esanguratsu) bat. Aldagai baten esparruak bere iraupenean eragina du.

* **Esparrua** aldagaiaren **izena**-ren propietatea da.
* **Iraupena**, berriz, aldagaiaren **biltegiratze-kokalekua**-ren propietatea da.
Horrez gain, ikusgarritasuna (visibility) kontuan hartu behar da. Ikusgarritasunak zehazten du programako zein ataletan sar daitekeen aldagai batera. Esparruarekin lotuta dago, baina ez da gauza bera: ikusgarritasuna kontrolatu daiteke programazio-lengoaiaren mekanismo espezifikoekin, hala nola modifikadore pribatuak (`private`), publikoak (`public`) edo babestuak (`protected`) erabiliz, objektuetara bideratutako programazioan.

Termino hauek ez dira testuinguruarekin (edo *ingurunearekin*) nahastu behar. **Testuingurua** (context) edo **ingurunea** (environment) programaren exekuzioarekin lotuta dauden **faktoreak** dira, hala nola **exekuzio-ingurunea**, **funtzio deien kateak**, edo **sistema eragilearen baliabideak**. Aldiz, esparrua eta iraupena programaren **egitura logikoaren parte** dira, hau da, **nola definitzen** eta **erabiltzen** diren aldagaiak kodean. Gainera, esparrua eta iraupena alda daitezke programaren **kodea** edo **exekuzioa** aldatzean, adibidez funtzio bat gehitzen edo aldagai bat berriro definitzen bada.

### Esparrua 
Esparrua funtsezko kontzeptua da aldagai baten izena aukeratzeko garaian. Programazio-lengoai gehienek aldagai bakoitzari esparru zehatz bat esleitzen diete, programaren barruan aldatu daitekeena.

* **Aldagai baten esparrua** programaren zati bat da non aldagaiaren izenak esanahia duen, eta aldagai hori "ikusgai" dagoen.
* Esparru horretan sartzeak normalean aldagaiaren bizitza hastea dakar, eta esparrutatik irteteak bere bizitzaren amaiera.

#### Esparru Motak: 
**Esparru lexikala (lexical scope):**  Aldagai baten **esparru lexikala** (edo **esparru estatikoa** ere deitua) kodearen egituraren arabera zehazten da. Hau da, aldagai bat non definitzen den programaren testuan horrek determinatzen du aldagai hori non erabil daitekeen. Aldagaia esanguratsua izango da soilik bere definizioa dagoen funtzioan, azpiprograman edo adierazpen/bloke jakin batean, eta ez horretatik kanpo.  
eskuinera|307x307px
**Ezaugarri nagusiak:**

* **Ebazpen estatikoa:** Aldagai baten esparrua **sintaxi-analisiaren** edo **konpilazioaren garaian** zehazten da, eta ez programaren exekuzioan. Horrek esan nahi du aldagaien bilaketa (name resolution) programaren egitura finkoan oinarritzen dela.
* **Kodearen egituraren araberakoa:** Funtzio edo bloke baten barruan definitutako aldagai bat ezingo da erabili kanpoko inguruneetan, eta kanpoko aldagaiek ez dute automatikoki eraginik barruko aldagaien gainean.
* **Ulertzeko eta mantentzeko errazagoa:** Programatzaileek errazago uler dezakete aldagai baten balioa non eta nola definitzen den, horrek programaren iragarritasuna eta segurtasuna handitzen baititu.

**Esparru dinamikoa (dynamic scope):** Aldagaien balioak eta loturak exekuzio-denboran zehazten dira, programaren kontrol-fluxuaren arabera. Horretarako, lotura globalen pila bat erabiltzen da, non aldagaiak definitu diren inguruneak (environment) gordetzen diren. Honek esan nahi du aldagai baten balioa bilatzeko, lehenik eta behin uneko funtzioan bilatzen dela, eta, bertan aurkitzen ez bada, exekuzio-pilan atzera egiten dela, aurreko inguruneetan bilatu arte.

**Ezaugarri nagusiak:**

* **Exekuzioaren menpekotasuna:** Aldagaien esparrua ez da kodearen egituraren arabera zehazten, baizik eta programaren exekuzioan zehar funtzioak nola deitzen direnaren arabera.
* **Malguagoa baina zailagoa ulertzeko:** Errazagoa da aldagai batzuk partekatzea funtzioen artean, baina horrek programaren portaera zaildu dezake, batez ere kode konplexuetan.
* **Efizientzia gutxiago bilaketa denboran:** Aldagai baten balioa aurkitzeko exekuzio-pilan atzera joan behar izaten da, eta horrek denbora gehiago har dezake.

**Aldagai motak esparruaren arabera:**
* **Aldagai lokalak:** Funtzio jakin baten barruan bakarrik eskuragarri.
* **Aldagai globalak:** Programaren edozein lekutan erabil daitezkeenak, esparru mugagabea dutelako.
```java
public class Main {

    // Aldagai Globala
    static int aldagaiGlobala = 10;

    public static void main(String[] args) {
        // Aldagai lokala
        int aldagaiLokala = 5;

        System.out.println("Aldagai globala: " + aldagaiGlobala); // 10
        System.out.println("Aldagai lokala: " + aldagaiLokala); // 5
        
        // Bloke berri bat
        {
            int besteAldagaiLokala = 20;  // Beste aldagai lokala, bloke honetan bakarrik balio du
            System.out.println("Blokeko aldagai lokala: " + besteAldagaiLokala); // 20
        }
        
         System.out.println("Aldagai globala: " + aldagaiGlobala); // 5
        // Agindu honek errorea emango du, besteAldagaiLokala ez delako eskuragarri bloke honetatik kanpo
         System.out.println(besteAldagaiLokala); // Errorea: ezin da aldagaia topatu
    }
}
```

### Iraupena 
Iraupena aldagai baten ezaugarria da. 

* **Loturaren iraupena:** Programaren exekuzio-denborako tartea, non aldagaiak balio edo memoria-kokaleku berdina erreferentziatzen duen.
* Lotura aldagaia sortu edo hasieratzen denean hasten da. Lortura amaitzeko hainbait aukera daude:

# Esparrutikan kanpo ateratzen denean.
```java
void eredua() {
    int x = 10; // Lotura hasierarazi
    System.out.println(x);
}
// Funtzioaren exekuzioa amaitzerakoan lotura amaitu esparrutik atera baita
```

## Aldagaia ezabatu edo aldagaia askatu. 
# 
```c
int* ptr = malloc(sizeof(int)); // Lotura hasi
*ptr = 42;
free(ptr); // Aldagaia liberatu. Lotura amaitu
```

# Erreferentziak amaitzen direnean.
```java
public static void main(String[] args) {
    Pertsona obj = new Pertsona("Ane"); // Lotura hasi
    
    System.out.println(obj.izena);
    
    obj = null; // Lotura amaitu
}
```

#### Arazoak eta egoerak: 
* **Memoria-galera (memory leak):**
Programazio-lengoaiak **garbiketa automatikoa (garbage collection)** ez badu, memoria-ihesak sor daitezke. Aldagai baten erreferentzia galtzen bada(aldagaiaren izena ez dago eskuragarri, esaterako), objektuarentzako gordeta dagoen memoria ezin izango da askatu, aldagaia gehiago erabiltzen ez den arren.
* **Esparrua iraupena baino lehen hasten denean:**
Aldagaia **hasieratu gabe** dago, edo balio zehaztugabea bada. Programak aldagai horretako posizioan sartzen saiatzen denean erroreak gertatuko dira. Adibidez, **erreferentzia zintzilikari** **(wild pointer)** bat sortzen denean.
* **Iraupena esparrua baino lehen amaitzen denean:**
Memoria-posizio bat esparrua amaitu baino lehen liberatzen bada, **erakusle suntsitua (dangling pointer)** izeneko arazoa sor daiteke. Arazo hori gertatzen da programa oraindik erabilgarri ez dagoen aldagai bati erreferentzia egiten dionean, eta horrek erroreak eragin ditzake.

Zenbait programazio-lengoaietan, aldagai bat bere iraupenetik erabiltzeak erroreak ekar

ditzazke. Beste batzuetan, ezusteko emaitzak ekar ditzazke. Hala ere, balio berri bat esleituz gero, aldagai horrek iraupen berri bat izango du.

## Datu mota 
Aldagaiak balio jakin batzuk eduki edo haietara apuntatzen eta erakusten dituztenez, horien gaineko eragiketak eta beren balioen domeinua dagokion datu motak zehazten du. Erabiltzen diren datu mota batzuk hauek dira:

### Oinarrizko datu motak 
**Datu mota logikoa** (egia/1 edo gezurra/0): egiazkotasun-balioak gordetzeko erabiltzen da.

```java
boolean egiaDa = true; boolean gezurraDa = false;
```

**Datu mota osoa** (zenbaki erreala, hamartar gabekoa): zenbaki osoak gordetzeko erabiltzen da.

```java
int zenbakiOsoa = 42;
```

**Datu mota koma mugikorra** (zenbaki erreala, hamartarrekin): zenbaki hamartarrak gordetzeko erabiltzen da.

```java
float zenbakiHamartar = 3.14f; double zenbakiHandiagoa = 3.14159265359;
```

**Datu mota karakterea** (letra edo digitu bakarra): karaktere bakarra gordetzeko erabiltzen da.

```java
char letra = 'A'; char zenbakidunKarakterea = '9';
```

**Datu mota kate** (testu-katea edo karaktere multzoa): testua gordetzeko erabiltzen da.

```java
String testua = "Kaixo, mundua!";
```

**Datu mota bikoitz** (double): koma mugikorreko doitasun handiagoko balioak gordetzeko erabiltzen da.

```java
double doitasunHandikoa = 0.123456789012345;
```

**Datu mota luzea** (long): zenbaki oso handiagoak gordetzeko erabiltzen da.

```java
long zenbakiHandia = 123456789012345L;
```

**Datu mota matrizea** (array): elementu multzo antolatu bat gordetzeko erabiltzen da.

```java
int[] zenbakiak = {1, 2, 3, 4, 5}; String[] hiriak = {"Bilbo", "Donostia", "Gasteiz"};
```

**Datu mota egitura** (struct): Java-n `class` edo `record` erabil daiteke egitura konplexuak definitzeko.

```java
class Pertsona { 
    String izena; int adina;
    Pertsona(String izena, int adina) {  
        this.izena = izena;  
        this.adina = adina;  
    }  
}
```

**Datu mota data/ordua** (date/time): Javan `LocalDate`, `LocalTime`, eta `LocalDateTime` klaseak erabiltzen dira.

```java
import java.time.LocalDate; import java.time.LocalDateTime;
LocalDate gaurkoData = LocalDate.now();
LocalDateTime orduarekin = LocalDateTime.now();
```

## Izendapen hitzarpenak 
Programazioko aldagai eta konstanteek, beren baliokide matematikoetatik ez bezala, izen anitz-karakterekoak izaten dituzte normalean, adibidez, `COST` edo `total`. Karaktere bakarreko izenak gehienbat aldagai lagungarrietan erabiltzen dira; esaterako, `i`, `j`, `k` matrizeen indize-aldagai gisa. 

Aldagaiak izendatzeko hitzarpen batzuk hizkuntzaren sintaxiaren araberakoak dira, eta identifikatzailee zuzenentzako formatu jakin bat ezartzen dute. Programazio-hizkuntza gehienetan:

* **Aldagai izenek ezin dute digitu batekin hasi** (0–9),
* Ezta **zuriuneak (whitespace)** eduki ere.

Puntuazio-markak baimentzen diren ala ez hizkuntza bakoitzaren araberakoa da; hizkuntza askotan, **azpimarra** **(" _")** bakarrik onartzen da aldagai-izenetan, eta gainerako puntuazio-markak debekatuta daude. Programazio-hizkuntza batzuetan, **sigil** (ikur edo puntuazio-markak) erabil daitezke aldagaien identifikatzaileetan, haien **datu mota** edo **esparrua (scope)** adierazteko.

Aldagaien izenen **letra larrien eta letra xehen bereizmena (case-sensitivity)** ere hizkuntza bakoitzaren araberakoa da. Hizkuntza batzuk izenak letra larri edo xehez idazteko arau zorrotzak dituzte.

* **Hizkuntza moderno gehienak bereizleak dira** (maiuskula eta minuskula desberdintzen dituzte),
* **Hizkuntza zaharrago batzuk ez dira bereizleak.**

Gainera, hizkuntza batzuetan aldagai-izen batzuk erreserbatuta daude programaren erabilerarako. Adibidez, hizkuntza askotan **bi azpimarrarekin ("__")** hasten diren izenak sistemaren barne-funtzioetarako erabiltzen dira.

Programazio-hizkuntzak ezarritako oinarrizko mugetatik haratago, aldagaiak izendatzea **estilo kontu bat da**.

* **Makina-kodean** aldagai-izenak ez dira erabiltzen, beraz, ordenagailuarentzat izen zehatzak ez du garrantzirik.
* Aldagai-izenak programatzaileentzat dira baliagarriak, kodea **idazteko** eta **ulertzeko** errazagoa izan dadin.
* **Izen deskriptibo eskasek** kodea berrikusteko zailtasunak sor ditzakete, beraz, izen argiak erabiltzea gomendatzen da.

Programatzaileek sarritan **kode-estiloaren gidalerroak** sortu edo jotzen dute aldagaiak izendatzeko gomendioak sortu edo bilatzeko.

* **Izen laburrak** azkarrago idazten dira baina ez dira deskriptiboak.
* **Izen luzeagoek** kodea irakurtzea errazten dute eta aldagaien helburua hobeto ulertarazten dute.
* Hala ere, **izen oso luzeek** kodea ulergaitz bihur dezakete.
Aldagaiak izendatzeko hainbait modu: 

## Memoria esleipena 
Aldagai baten memoriaren esleipena oso desberdina izan daiteke bai programazio-lengoai batetik bestera, eta baita hizkuntza jakin baten inplementazioan ere. Hizkuntza askoren inplementazioek aldagai lokalentzako espazioa esleitzen dute, eta haien iraunaldia funtzio baten exekuzioaren iraupenarekin lotuta dago pilan (**call stack**)-ean. Funtzioa amaitzean, memoria hori automatikoki askatzen da. Orokorrean, izenen loturan (**name binding**), aldagai baten izena memoriako toki bati (byte-segida) lotzen zaio, eta aldagaiaren gaineko eragiketek bloke horretan jarduten dute.

### Erreferentzia bidezko esleipena: 
*Erreferentzia bidezko esleipena ohikoagoa da **tamaina handia edo ezezaguna duten balioetarako**. Kodea konpilatzen denean erazagutzen da posizioa, hau da, programaren exekuzioa hasi baino lehen.
* Kasu horietan, aldagaiaren balioa gorde beharrean, balio hori gordeta dagoen tokiari erreferentzia gordetzen dute, hau da, bere kokalekuari.
* Balio horiek **heap** izeneko memoria-pilatik esleitzen dira, non memoria dinamikoaki kudeatzen den.

### Memoria esleipen estatikoa: 
Memoria esleipen estatikoa programaren konpilazioan egiten da, hau da, programaren exekuzioa hasi baino lehen. Horrela, aldagai guztiek behar duten memoria espazioa aldez aurretik zehazten da, eta memoria hori programaren bizitza osoan zehar esleituta dago. Memoria estatikoa **pila** (stack) izeneko memoria-ataletik esleitzen da, eta bere tamaina finkoa da.

### Memoria esleipen dinamikoa: 
Memoria esleipen dinamikoa **heap**-ean gauzatzen da, eta ohikoa da objektuak, matrizeak edo tamaina handiko datuak gordetzeko. Memoria dinamikoa ez da automatikoki garbitzen erabilpena amaitzen denean, eta bi modu nagusi daude memoria hau kudeatzeko:

**1. Zabor-bilketa duten hizkuntzak** (Java, Python, C#, Go, Lisp, etab.):

Sistemak automatikoki identifikatu eta garbitzen ditu erabili gabeko datuak. Aldagai batek objektu bati erreferentzia egiten ez dioenean, zabor-biltzaileak memoria hori askatzen du.

**2. Zabor bilketarik gabeko hizkuntzak** (C bezalakoak):

Programatzaileak eskuz esan behar dio programari noiz esleitu eta memoria libre utzi, `malloc()` eta `free()` funtzioak erabiliz.

Programatzailea memoria askatzeaz ahazten bada, >(memory leak) bat gerta daiteke, non memoria denbora pasa ahala pilatzen doan, inoiz askatzen ez delako. Errendimendu arazoak edo programaren kraskadurak ekar ditzazke.

## Ikus Gainera 
Programazio-lenguaia

Memoria (informatika)

Aldagai (matematika)

## Erreferentziak 
## Kanpo estekak