←  Tutoriale

AMXX.pl: Support AMX Mod X i SourceMod

»

Zmienna globalna a zmienna statyczna

  • +
  • -
grankee - zdjęcie grankee 11.08.2008

static-zmienna statyczna ulokowana w danym obszarze pamięci przechowywana w nim przez cały czas działania programu(tak jak globalna). Różnica między zmienną globalną a zmienną lokalną statyczną jest taka, że zmienna static zadeklarowana wewnątrz funkcji jest widoczna tylko w niej, podam przykład


#include <amxmodx>
#include <amxmisc>

#define PLUGIN "static"
#define VERSION "1.0"
#define AUTHOR "grankee"


public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)
    jedynka()
    dwojka()
    jedynka()
    jedynka()
    dwojka()
    dwojka()
}
public jedynka()
{
    static liczba //domyślnie zmienna statyczna zawsze przyjmuje wartość początkową 0
        liczba=liczba+2
    client_print(1,print_chat,"zmienna liczba z funkcji jedynka ma wartosc:%d",liczba)
}
public dwojka()
{
    static liczba2
        liczba2++
    client_print(1,print_chat,"zmienna liczba z funkcji dwojka ma wartosc:%d",liczba2)
}

w rezultacie graczowi o id=1 zostanie wyprintowane


zmienna liczba z funkcji jedynka ma wartosc:2
zmienna liczba z funkcji dwojka ma wartosc:1
zmienna liczba z funkcji jedynka ma wartosc:4
zmienna liczba z funkcji jedynka ma wartosc:6
zmienna liczba z funkcji dwojka ma wartosc:2
zmienna liczba z funkcji dwojka ma wartosc:3

Jak zapewne zauważyliście "przydomek" static sprawia, że zmienna zadeklarowana wewnątrz funkcji mimo iż jest lokalna nie przestaje istnieć w momencie gdy kończy się jej zakres ważności.

Czyli z polskiego na nasze to będzie tak: po każdym wykonaniu się funkcji wartość zmiennej zadeklarowanej jako static zostaje zamrożona, aż do momentu kolejnego wykonania tej funkcji, wtedy jest odmrażana i ma taką wartość jak miała w momencie zamrożenia.

W tym miejscu przypominam, że pluginy ładowane są co mapę i aby zachować wartość zmiennej na następną mapę niezbędny jest zapis do pliku.

Zmienna globalna jest widziana przez cały czas wykonywania kodu, jednak widziana w każdym miejscu programu co często jest zbędne, dlatego jeśli chcemy zmienną widzieć tylko w danym zakresie kodu, ale tak by przy następnym wykonywaniu go zmienna "wiedziała" jaką ostatnio miała wartość i takową posiadała to używamy zmiennej static.
Użytkownik grankee edytował ten post 02.05.2010 22:44
Odpowiedz

  • +
  • -
Miczu - zdjęcie Miczu 04.09.2008

Odkrylem taka fajna rzecz o ktorej warto wspomniec:

public funkcja()
{
   static x=20
   x++
   client_print(0,print_chat,"%d",x)
}

Gdy sie wywola funkcje, to za kazdym razem widzimy inna liczbe (nie jest od nowa deklarowane jako 20) tj. 21,22,23,24,25...
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 04.09.2008

public jedynka()
{
    static liczba //domyślnie zmienna statyczna zawsze przyjmuje wartość początkową 0
        liczba=liczba+2
    client_cmd(1,"zmienna liczba z funkcji jedynka ma wartosc:%d",liczba)
}

w rezultacie graczowi o id=1 zostanie wyprintowane

zmienna liczba z funkcji jedynka ma wartosc:2
zmienna liczba z funkcji jedynka ma wartosc:4
zmienna liczba z funkcji jedynka ma wartosc:6

public funkcja()
{
   static x=20
   x++
   client_print(0,print_chat,"%d",x)
}


czy to nie to samo co napisałem? ^^
Odpowiedz

  • +
  • -
Miczu - zdjęcie Miczu 04.09.2008

Chodzi mi oto (sam tak myslalem) ze jak bedzie sie przypisywac wartosc tj. static x=20 i wywolywal ta funkcje, to bedzie sie ona od nowa ustawiac z wartoscia 20 :P
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 05.09.2008

Miczu nie żebym się czepiał, ale trochę bez sensu piszesz xP Jak przypiszesz do zmiennej 20 to będzie ona miała wartość 20 a jak przypiszesz 47 to będzie miała wartość 47 nieważne czy to zmienna globalna czy statyczna. To tak jak byś napisał, że jeśli włożysz palec w ogień na kilka sekund to się sparzysz :)

Następną kwestią jest to, że nie ma sensu przypisywać wartości do zmiennej statycznej przed jej użyciem lub już przy deklaracji, bo tak samo to zadziała jeśli zmienna nie będzie statyczna. Oczywiście można się zastanowić i wymyślić kawałek kodu, który zaprzeczy temu co tu napisałem, ale sądzę, że taki kod można będzie napisać w inny prostszy sposób, który potwierdzi moje słowa :]
Odpowiedz

  • +
  • -
Miczu - zdjęcie Miczu 05.09.2008

grankee, nie kazdy chce zaczynac z zmienna o wartosci 0.

jesli zamiast
public funkcja() 
{ 
   static x=20 
   x++ 
   client_print(0,print_chat,"%d",x) 
}
zrobisz
public funkcja() 
{ 
   static x
   x=20 
   x++
   client_print(0,print_chat,"%d",x) 
}
To zawsze bedziesz mial wywolywana liczbe 21, wiec ustalanie poczatkowej wartosci przy deklaracji ma jak najwiekszy sens :]
Szczegolnie ze static moze byc uzyty tylko w tej funkcji co zostal zdeklarowany, wiec bys musial nie potrzebnie zasmiecic kod by zasmiecic kod (np. if(x==0) x=20 xD)
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 05.09.2008

Chyba źle Cię zrozumiałem, chodzi Ci o to, że jeżeli przypiszemy wartość przy deklaracji
static zmienna=20
to zostanie to przypisane tylko przy pierwszym wywolaniu funkcji, a przy każdym następnym wartość będzie taka jaka była zamrożona? Jeśli tak to się z Tobą zgadzam, zapomniałem o tym napisać, a jeśli nie to już nie wiem o co Ci chodzi ;>
Odpowiedz

  • +
  • -
Miczu - zdjęcie Miczu 05.09.2008

zostanie to przypisane tylko przy pierwszym wywolaniu funkcj

Tak wlasnie o to, troche ci to zajelo ;>
Odpowiedz

Seba - zdjęcie Seba 05.09.2008

Chodzi mi oto (sam tak myslalem) ze jak bedzie sie przypisywac wartosc tj. static x=20 i wywolywal ta funkcje, to bedzie sie ona od nowa ustawiac z wartoscia 20 :P

bo dlatego że nie tworzy jej na nowo tak jak za pomocą new, tak naprawdę jest ona cały czas zdefiniowana tak jak globalna...
Odpowiedz

  • +
  • -
Miczu - zdjęcie Miczu 05.09.2008

Tylko ze mozna uzyc tej samej nazwy (teoretycznie) w tysiacu funkcji i nie beda ze soba koalidowac :)
Odpowiedz

GT Team - zdjęcie GT Team 03.05.2013

Pytanie, lepiej w PreThinku robić:
new Origin[3]
get_user_origin(id, Origin)
czy
static Origin[3]
get_user_origin(id, Origin) // Origin będzie zawsze zmieniany, bo pobiera
Odpowiedz

  • +
  • -
DarkGL - zdjęcie DarkGL 03.05.2013

jeżeli bierzesz pod uwagę kwestie wydajnościowe to static 

Odpowiedz