2012-12-09 11 views
5

Czytam Gilles Dowek za zasad programowania Languanges:Dlaczego można zadeklarować zmienną bez wartości początkowej?

Mówi, że jest to również możliwe, aby zadeklarować zmienną bez nadając mu wartość początkową, a także, że musimy uważać, by nie użyć zmiennej który został zadeklarowany bez wartości początkowej i któremu nie przypisano wartości. Powoduje to błąd.

Uwaga: Autor książki wspomina o możliwości zadeklarowania zmiennych bez wartości początkowej na Javie.

Dlaczego ta deklaracja zmiennych jest ważna? Kiedy zamierzam go użyć?

+0

Uważam, że odpowiedź jest różna w różnych językach. –

+0

Tak, jest. Autor książki wspomina, że ​​ta funkcja jest ważna w Javie, będę edytować post. –

+1

Dobre pytanie. Zastanawiam się, jakie jest uzasadnienie? – xagyg

Odpowiedz

7

Istnieje wiele różnych powodów dla wielu różnych języków.

PAMIĘĆ
Kiedy deklarujesz zmienną, chcesz trochę pamięci do przechowywania zmienną. Wiąże się to z pytaniem jądro systemu operacyjnego do pamięci, albo jakiś program monitorujący, który śledzi pamięci. W skrócie, może to być kosztowna operacja. W wielu przypadkach pożądane jest przydzielenie całej pamięci wymaganej dla obiektu w tym samym czasie, a następnie przypisanie jej później dowolnej wartości. W ten sposób możesz zwiększyć wydajność programu w kluczowych częściach. Ten przypadek użycia jest na tyle powszechny, że dopuszcza się funkcję zezwalającą na deklarację bez inicjalizacji. Jednak dobre praktyki twierdzą, że we wszystkich innych przypadkach powinieneś zainicjować zmienną podczas przypisywania.

Pomyśl o alokacji pamięci jako biurokracji. Za dużo papieru. Tak więc, jeśli wiesz, że będziesz używać dużej ilości pamięci później, poprosisz o dużą ilość pamięci z góry w jednej transakcji, zamiast pytać o jądro za każdym razem.

kosztowne INICJALIZACJI
Punkt ten jest bardzo podobny do powyższego punktu. Załóżmy, że masz tablicę 1 milion razy milion. Inicjowanie takiej tablicy jest kosztowną procedurą. Aby to zrobić z domyślnymi wartościami, byłoby głupotą, a więc taką funkcją, w której pamięć jest przydzielana, a następnie używana w razie potrzeby.

Tutaj kupujesz ogromną ilość klocków lego, aby coś skonstruować, ale chcesz kupić je w kształtach domyślnego spiderman. Sprzedawca lub będziesz musiał bardzo się starać, aby uzyskać je w kształtach spiderman, kiedy będziesz je później przekształcić.

5

Na przykład można mieć coś takiego:

int i; 
if (first_condition) 
    i = 1; 
elseif (second_condition) 
    i = 2; 
else 
    i = 0; 

zmiennej musiałyby być zadeklarowane poza if na to, aby być wykorzystane później, ale jego wartość jest ustalona wewnątrz warunkach if.

1

Coś jak:

//declare without giving value. 
int i; 

//set value 
i=9; 
+1

To nie jest moje pytanie, moje pytanie brzmi: dlaczego można zadeklarować zmienną bez wartości początkowej, jeśli będzie ona miała błąd? –

+0

Nie wszystko da błąd ... Jak int i; da 0. Ale jeśli zrobisz użytkownika User; Potem później String s = user.address; Daje ci to błąd: – user903772

+0

@ user903772 zmienne lokalne nie zostały zainicjalizowane na nic, są niezdefiniowane ... "Zmienne lokalne są nieco inne, kompilator nigdy nie przypisuje wartości domyślnej do niezainicjowanej zmiennej lokalnej .Jeśli nie możesz zainicjować zmiennej lokalnej, gdzie to jest jest zadeklarowane, upewnij się, że przypisałeś mu wartość przed próbą użycia. Uzyskanie dostępu do niezainicjowanej zmiennej lokalnej spowoduje błąd kompilacji. " – xagyg

1

Można zadeklarować pusty var na przykład w skrypcie walidacji

$error=''; 
if(empty($_POST['first_name']{ 
$error=$error."You did not enter a name"; 

}

tak, ale chciałbym używać go tylko wtedy, gdy kod zaraz po tym, jak został ponownie zadeklarowany, tak jak powyżej, aby nie został "zagubiony".

3

Jeśli naprawdę przyjrzysz się temu, co się stanie, gdy zadeklarujesz zmienną i zainicjujesz ją (przypisujesz wartość początkową), zobaczysz, że na poziomie instrukcji maszynowej lub kodu bajtowego dla Javy jest znacząca ilość mocy obliczeniowej użyte w obu tych krokach.

  1. deklarowania zmiennych środki przydzielania pamięci, tworząc instancję poprosił typu, etc etc
  2. Następnie inicjowania tej lokalizacji pamięci, ponownie wymaga więcej przetwarzania przenieść wartość domyślną do przydzielonego miejsca pamięci, jak wypełnienie go z 0s jeżeli wartość domyślna to 0. (Uwaga: kiedy losowe miejsce w pamięci jest przypisana do zmiennej, że pamięć może zawierać dowolny wzór, pozostawione tam przez poprzedniej wartości)

Więc jeśli użytkownik nieświadomie użyć zmiennej bez uprzedniego nadając mu akceptowalną wartość dla swojego typu, wtedy może wystąpić błąd, jeśli wartość, którą wa s nie było poprawne.

Więc jeśli język wymusza na inicjalizowaniu zmiennej (lub robi to samodzielnie) w deklaracji, zmniejsza szanse na błąd w dół linii, ale może marnować moc przetwarzania na coś, czego tak naprawdę nie chcesz.

Z drugiej strony, jeśli pozwala zadeklarować zmienną bez jej inicjalizacji, daje kontrolę i może zaoszczędzić trochę mocy obliczeniowej, ale otwiera szanse na błąd. (Załóżmy, że masz scenariusz, w którym początkowa wartość dla zmiennej zależy od innych warunków, które będą brać pod uwagę i odpowiednio przypisać zmienną.W takim przypadku inicjowanie var na deklaracji może być po prostu marnotrawstwem mocy obliczeniowej).

Języki decydują o tym, którą ścieżkę chcą przejść, w większości zależą od tego, co uważają za swoją moc.

jeśli chodzi o umożliwienie programistom sterowania i tworzenie zoptymalizowanych programów, wtedy zazwyczaj zezwalają na zadeklarowanie vars bez inicjalizacji, a także na dodatkowe rzeczy.

Ale jeśli chodzi o język zmuszający programistę do pisania programów bezbłędnych, zajęłoby to drugą ścieżkę.

2

Jeżeli Java miały wymagać pól obiektu klasy zawsze musi być napisany zanim były one odczytywane, wymagałoby to, że albo

  • Konstruktor obiektu klasy musi napisać do wszystkich dziedzinach tego obiektu , w tym te, które byłyby kodowane, nigdy nie przeczytałyby bez napisania ich po raz drugi; byłoby to zarówno brzydkie, jak i nieefektywne.

  • Każde pole musi mieć wartość never been written różniącą się od innych wartości, które można do niej zapisać.

  • Kompilator musiałby rozwiązać problem zatrzymania w celu ustalenia, czy dane pole można odczytać bez jego napisania.

  • Język musi akceptować możliwość, że pole zostanie odczytane bez wpisania kodu użytkownika.

Z tych możliwych wyborów, # 4 jest najmniej złym.Aby uniknąć niezdefiniowanego zachowania, Java definiuje zachowanie odczytu pola, które nigdy nie zostało zapisane: będzie zawierało domyślną wartość jego typu.

+0

Tylko pola instancji mają wartości domyślne.Próba użycia lokalnego pola bez inicjalizacji spowoduje błąd kompilacji. Fakt, że pola instancji nie wymagają inicjalizacji, jest raczej uproszczeniem kompilatora niż dobrym projektem. Ta odpowiedź wyjaśnia to dobrze: https://stackoverflow.com/questions/1560685/why-must-local-variables-including-primitives-always-be-initialized-in-java –

+0

Być może powinienem był powiedzieć raczej "instancja klasy" niż "obiekt klasy", ale nie sądzę, aby odpowiedzi na to inne pytanie dotyczyły tego, co byłoby konieczne, gdyby język wymagał zapisania pól instancji. Umożliwienie kompilatorowi generowania kodu bez konieczności rozwiązywania problemu zatrzymania lub zarezerwowania "nigdy nie zapisanej" wartości dla każdego pola może być "uproszczeniem", ale uważam to za bardziej praktyczną. – supercat

1

OK, tutaj jest przykład. Obecnie ustawiam wartości globalne, które są ustawione na stałe na forach PDF. Dla tej aplikacji chcę użyć tych wartości jako przechowywania danych podobnie jak pole tekstowe. Nie jest to najlepsza metoda, ale działa w tym przypadku. Zamiast umieszczać na moim forum setki ukrytych pól tekstowych, mogę ustawić wartości jako trwałe zmienne globalne.

Jeśli moje początkowe opóźnienie jest ustawione na lub „” jako wartości zmiennej niż nie będzie trzymać dane pomiędzy sesjami. Inicjalizacja forum zresetuje wartość do zera. Podobnie jak Scrips, fora działają w kolejności. Najpierw rozpozna wszystkie skrypty w dokumencie, zanim przypisze wartości do przeniesienia zmiennych. Dlatego konieczne jest zadeklarowanie zmiennej bez wartości, aby inicjalizacja nie zastąpiła wartości.

Ogólnie rzecz biorąc jest to również dobre prowadzenie domu, aby zadeklarować wszystkie swoje zmienne u góry. Możliwe jest zadeklarowanie ich w trakcie pracy, ale odkryłem, że po dodaniu nowego elementu do skryptu muszę przesuwać linie w górę iw dół, aby zachować mój kod w czystości. Jeśli zmienna zostanie zadeklarowana, gdy jest używana, wówczas bardzo łatwo będzie użyć zmiennej przed jej zadeklarowaniem, co nie będzie działało.

Dodatkowo

Jest wydajny, aby przypisać wartość podczas deklarowania, Ale nie rodzajowy wartości posiadacz miejsce. W większości skryptów int nie jest tak proste jak powiedzenie int x = 5; Częściej wzywamy danych, takich jak this.getField ("TextBox3"). Wartość; lub inny kod linii. Poprzez przypisanie ogólnej wartości, takiej jak "" lub lub true Twoja funkcja może działać, nawet jeśli nie udało Ci się poprawnie wykorzystać wartości. Nie przypisując wartości, jeśli nie wykorzystasz swojej zmiennej, to twoja funkcja zawiedzie, pozwalając zawęzić możliwości przy rozwiązywaniu problemów. Jeśli int x; to nadal NaN do czasu, gdy użyjesz x niż twoje gromadzenie danych, a weryfikacje prawdopodobnie będą źródłem problemu.

Ogólnie zadeklaruj wszystkie wartości u góry i unikaj ustawiania ogólnych wartości, chyba że musisz. Jeśli zamierzasz zdefiniować wartości x później niż nie ustawiać tego na int x = 0;.