Dlaczego istnieje konwencja "czyszczenia" zmiennych przed użyciem?

0

Wiele razy widziałem przypadek

var I: Integer;
begin
  Result := 0;
  //bla bla  
  //bla bla
  //bla bla
  Result := coś tam;
  //bla bla
end;

tak samo było z przypisanie "False" zmiennej logicznej, po co? Przecież i tak na początku jest False, lub pustego łańcucha '' stringowi. I tak przecież jest pusty na początku.

0

Niekoniecznie, zmienna wskazuje na pewien obszar pamięci a w tym obszarze coś jest (np jakaś pozostałość po uruchomionym wcześniej programie), Zrób eksperyment, zadeklaruj zmienną a potem ją od razu wyświetl. String może i będzie pusty, ale zmienna liczbowa już niekoniecznie.

0

dlatego, że nie powinno się polegać na żadnych trickach języka - kod ma być jak najbardziej zrozumiały

0
var Liczby: array of Integer;
    I :Integer;
const
    LiczbaLiczb = 100000;
begin
  SetLength(Liczby, LiczbaLiczb);
  for I := 0 to LiczbaLiczb - 1 do
    if Liczby[I] <> 0 then ShowMessage(IntToStr(Liczby[I]));
end;

Nie pokazało się żadne okienko :/

0

Nie pokazało się żadne okienko

Takie tablice tworzone są na stercie, może akurat jest ona czyszczona przez kompilator lub po prostu była wyzerowana...

A odpowiadając na pytanie zawarte w temacie:
Czasami (i w większości przypadków tak jest, że) zmienna może zostać zaalakowana w rejestrze, który niekoniecznie będzie pusty (tj.równy zero).
Może być tam np.wynik wywołania poprzedniej funkcji czy wartość czegokolwiek pozostawionego po poprzednim wywołaniu funkcji. Może, ale nie musi.
Dlatego najlepiej jest inicjować takie zmienne na jakąś wartość (chociaż chyba niekoniecznie tyczy się to stringów).

0

Bzdury. Nie ma żadnego przesłania, żeby inicjować zmienne dwa razy jak w przykładzie @TomRiddle z pierwszego postu, ba nawet kompilator będzie informował o niepotrzebnym przypisaniu temi słowy Value assigned to 'Result' never used
Jedynie w przypadku takim jak poniżej ma to sens:

function Dupa: Boolean;
begin
  Result := False;
  if cos then
    Result := True;
end;

ale tutaj wartość, na jaką zostanie zainicjowana zmienna może być wartością "końcową"

BTW sam moment inicjalizacji zmiennej na konkretną wartość powinien wynikać z samego algorytmu. Jeśli natomiast algorytm nie wskazuje na taki moment to najczęściej taka zmienna jest po prostu zbędna.

Jednocześnie należy zdać sobie sprawę, że stwierdzenie

TomRiddle napisał(a):

przypisanie "False" zmiennej logicznej, po co? Przecież i tak na początku jest False, lub pustego łańcucha '' stringowi. I tak przecież jest pusty na początku.

jest nieprawdziwe. Jedynie zmienne globalnezawsze inicjowane na wartości domyślne, natomiast zmienne lokalne nie mają ustalonej wartości, oznacza to jedynie (czy też aż) tyle, że mają one taką wartość jaką akurat miała komórka pamięci, którą ta zmienna zajęła.

0

Tutaj raczej chodzi o programowanie defensywne. Zalozmy ze mamy taki kod:

int a;
//tutaj duzo kodu nie korzystajacego z a
//znowu duzo kodu nie korzystajacego z a
a =1;
//tutaj duzo kodu korzystajacego z a
//znowu duzo kodu korzystajacego z a

Teraz jezeli ktos przez przypadek doda warunek:

int a;
//tutaj duzo kodu nie korzystajacego z a
if(warunek)
{
  //znowu duzo kodu nie korzystajacego z a
  a =1;
  //tutaj duzo kodu korzystajacego z a
}
//znowu duzo kodu korzystajacego z a

To teraz ostatni fragment kodu korzysta z niezainicjalizowanej zmiennej. Tak wiec dobra praktyka jest inicjalizacja zmiennych w podczas deklaracji. Oczywiscie ta technika nie jest lekarstwem na wszelkie bledy ale cos tam zawsze daje.

0

To, czy i kiedy zmienne są inicjalizowane domyślnymi wartościami zależy chyba od języka (no chyba, że w specyfikacji języka jest to określone jako "unspecified behaviour"), więc takie dyskusje są "language specific". :)

0
TomRiddle napisał(a):

Wiele razy widziałem przypadek

var I: Integer;
begin
  Result := 0;
  //bla bla  
  //bla bla
  //bla bla
  Result := coś tam;
  //bla bla
end;

I dobrze widziałeś tylko że nie uważnie patrzyłeś

var I: Integer;
begin
  Result := 0;
  //bla bla  
  if JAKOŚ_TAM then exit; //bla bla // Owszem też bla bla, ale zwraca wynik 0
  //bla bla
  Result := coś tam;
  //bla bla
end;
0

Jak napisał 0x200x20 - chodzi o programowanie defensywne.

Inne techniki z tej rodziny:

  • FreeAndNil
  • assert(p <> nil) - chociaż jesteśmy "pewni" że wskaźnik nigdy nie będzie nil
  • jeden punkt w którym zwraca się wartość przez return (w C)
  • stosowanie nawiasów chociaż priorytet operacji powinien załatwić odpowiednią kolejność obliczeń
  • sprawdzanie czy udało się otworzyć plik który został zapisany 2 ms temu

Są to rzeczy które mogą się wydawać niepotrzebne, mogą powodować wolniejsze działanie programu, ale znacznie ułatwiają znajdowanie błędów i ich poprawianie.

0

tak jeszcze OT - nie wiem w czym reszta z Was pisze ale zarówno Delphi (od wersji 6 na pewno, nie wiem jak wcześniejsze) oraz .net (c# i cf na pewno) krzyczy przy używaniu niezainicjowanych zmiennych, Delphi jako ostrzeżenie, .net wręcz jako błąd.

1 użytkowników online, w tym zalogowanych: 0, gości: 1