2015-09-01 25 views
6

Dlaczego nie wolno używać zmiennej I zadeklarowanej wewnątrz do i używam jej wewnątrz części while części pętli do/while?Nie można użyć zmiennej w klauzuli while, która jest zadeklarowana wewnątrz pętli do/while.

do 
{ 
    index += index; 
    int composite = index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); // cannot resolve symbol composite 

Po raz pierwszy zobaczyłem to pomyślałem, że to błąd kompilatora. Tak więc wielokrotnie uruchamiałem program Visual Studio, ale nadal nie rozpoznałem zmiennej w while.

Co jest nie tak z kodem, czy jest to błąd kompilatora?

+3

Sprawdź zakres zmiennych. "kompozyt" istnieje tylko w zasięgu pętli do wykonania, a nie poza nią. – Brandon

+0

i konw this, ale dlaczego kompilator nie może tego zrobić? –

+7

Dlaczego * powinna * zmienna poza zakresem może być użyta poza jej zakresem? Byłby to błąd, gdybyś mógł to zrobić. –

Odpowiedz

17

zmienna jest używana na zewnątrz do/while (w języku C# na Curlies zazwyczaj określają zakres), a ponieważ jest zadeklarowana wewnątrz do-while, nie można go używać poza tym zakresem.

Możesz to naprawić, po prostu deklarując je poza pętlą.

int composite = 0; // you are not required to set it to zero, as long 
        // as you do not use it before you initialize it 
do 
{ 
    index += index; 
    composite = index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); 

Uwaga (1), powszechną praktyką jest zadeklarować i ustawić zmienną za jednym zamachem, ale nie jest to wymóg, tak długo, jak ustawić go przed użyciem.

Uwaga (2): w języku C#, nawiasy klamrowe {....} definiują zakres zmiennych. Nie można używać zmiennej spoza jej zakresu, nie jest ona już "widoczna", w rzeczywistości, gdy wykracza poza zakres, jest gotowa do zbierania śmieci, a jej zawartość może być niezdefiniowana.


i konw tego, ale dlaczego kompilator nie mogę zrobić tego

Pytałeś to w komentarzach. Odpowiedź jest mniej trywialna, niż mogłoby się wydawać. To zależy w dużej mierze od definicji języka. Niektóre języki, takie jak Perl lub starsze BASIC, pozwalają na deklarowanie zmiennych na dowolnym poziomie iw dowolnym zakresie. Inne języki pozwalają na ustalanie zakresów zmiennych i wymagają deklarowania zmiennych przed ich użyciem (C#, Java, C++, Python). Zazwyczaj, ale niekoniecznie, jest to typowe dla statically typed languages, ponieważ kompilator musi wcześniej wiedzieć, jaki typ danych ma zostać umieszczony w zmiennej, aby dokonać sprawdzenia typu:.

Jeśli kompilator wymusiłby deklarację, ale nie zakres, oznacza to, że wszystkie zmienne miałyby charakter globalny, co jest trudne w przypadku większych programów, ponieważ jako programista trzeba zachować tam, gdzie użyto nazw zmiennych i zachować wyjątkowość . To bardzo uciążliwe (myśl COBOL).

C# dodało słowo kluczowe dynamic, które pozwala na wprowadzanie zmiennych o dynamicznym typie, ale to nadal wymaga zdefiniowania zmiennej przed jej użyciem.

Kompilator może to zrobić, ale projektanci C# zdecydowały, że jasny język jest lepszy, i ich zdaniem zadeklarowanych zmiennych are a good thing, ponieważ zapobiega fałszywych błędów i niemożliwe do wykonania kodu:

// can you see the problem? 
va1l = 1; 
val1 = 2; 
vall = va1l + vall; 

Wymuszenie deklarowania zmiennych i ich zakresów zapobiega tym i powiązanym rodzajom błędów.

+0

Myślę, że masz na myśli to, że jest "wewnątrz" do/while. – juharr

+0

@juharr, dziękuję, ale nie, miałem na myśli to, że jest on używany poza jego zakresem. Będę edytować. – Abel

+0

W tym przypadku nie trzeba inicjować zmiennej "composite" do zera przed pętlą. –

7

To nie jest błąd. Warunek wewnątrz pętli while znajduje się poza blokiem, w którym zdefiniowana jest zmienna.

int composite; 
do 
{ 
    index += index; 
    composite = index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); 
2

zakres tej zmiennej jest tylko wewnątrz pętli .... Nie można go używać poza pętlą

Powinieneś zrobić coś takiego ....

int composite; 
do 
{ 
    index += index; 
    composite = index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); 
2

Podczas { ... } oznacza codeblock wszystkie zmienne w tym bloku są ograniczone do tego specjalnego zakresu. Twój stan jest poza tym zakresem, więc nie może uzyskać dostępu do tamtej zmiennej. Zadeklarować ją na zewnątrz pętli i to działa:

int composite = 0; 
do 
{ 
    index += index; 
    composite += index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); 
2

Per Specification zmienna warunek do .. while powinny być zadeklarowane poza pętlą innego w każdej iteracji zmienna będzie ponownie zainicjowany, które nie ma sensu.

 int composite; 
     do 
     { 
      index += index; 
      composite = index + 1; 
      // more code here 
     } while (UnsetBitmask(bitmasks, composite)); 
2

Więcej ogólna zasada: ty nie może użycie zmiennej poza zakresem jego że w C# To {...}, na przykład

{ 
    int x = 123; 
    ... 
    } 
    x = 456; // <- compile time error 

do {} while w kodzie po prostu oznacza, że ​​zakres należący do pętli.

0
int composite; 
do 
{ 
    index += index; 
    composite = index + 1; 
    // more code here 
} while (UnsetBitmask(bitmasks, composite)); 
+0

zgodnie z formatem, w którym deklaracja zmiennej musi zostać wykonana przed uruchomieniem pętli – codemaster

+1

możesz edytować swoją odpowiedź, aby dodać (lub poprawić) informacje, zamiast dodawać komentarze. Edytowanie odpowiedzi jest lepsze, ponieważ ułatwia innym znalezienie i odczytanie informacji później. – dsh

Powiązane problemy