Czy mogę użyć tej samej zmiennej licznika dla for
pętli wewnątrz for
pętli?
A może zmienne będą miały na siebie wpływ? Czy poniższy kod powinien używać innej zmiennej dla drugiej pętli, na przykład j
, czy jest w i
porządku?
for(int i = 0; i < 10; i++)
{
for(int i = 0; i < 10; i++)
{
}
}
i
o różnych zakresach. Używaj-Wshadow
z GCC, aby automatycznie zgłaszać takie problemy.-Wshadow
nie ma tego w-Wall
.-Wshadow
ostrzega również o cieniowaniu zmiennych globalnych, co może łatwo irytować w przypadku większych projektów.-Wextra
nie zawiera-Wshadow
. Wydaje mi się, że jest to dość powszechne w niektórych projektach lub niektórzy deweloperzy gcc uwielbiają shadowing jako styl kodowania, aby zagwarantować, że zostanie w ten sposób pominięty.-Wshadow
ma horrendalny wskaźnik fałszywie dodatnich, co czyni go całkowicie bezużytecznym. Zakres istnieje z jakiegoś powodu, a cieniowanie nie jest a priori problematyczne. Teraz-Wshadow-local
(uwaga: nie-Wshadow=local
) jest zupełnie inaczej. Ale niestety GCC jak dotąd odmówił włączenia go do bagażnika (chociaż wydaje się, że istnieją rozwidlenia GCC, które go zawierają).Odpowiedzi:
Możesz użyć tej samej nazwy (identyfikatora). To będzie inny obiekt. Nie będą na siebie wpływać. Wewnątrz pętli wewnętrznej nie ma możliwości odniesienia się do obiektu używanego w pętli zewnętrznej (chyba że poczynisz na to specjalne przepisy, np. Przez podanie do niego wskaźnika).
Jest to ogólnie zły styl, jest podatny na pomyłki i należy go unikać.
Obiekty różnią się tylko wtedy, gdy wewnętrzny jest zdefiniowany osobno, tak jak
int i
pokazałeś. Jeśli ta sama nazwa zostanie użyta bez definiowania nowego obiektu, pętle będą używać tego samego obiektu i będą ze sobą kolidować.źródło
Po pierwsze, jest to całkowicie legalne: kod skompiluje się i uruchomi, powtarzając treść zagnieżdżonej pętli 10 × 10 = 100 razy. Licznik pętli
i
wewnątrz zagnieżdżonej pętli ukryje licznik pętli zewnętrznej, więc dwa liczniki będą zwiększane niezależnie od siebie.Ponieważ zewnętrzna
i
jest ukryta, kod wewnątrz treści zagnieżdżonej pętli miałby dostęp tylko do wartościi
zagnieżdżonej pętli, a niei
z zewnętrznej pętli. W sytuacjach, gdy zagnieżdżona pętla nie potrzebuje dostępu do zewnętrznegoi
kodu, taki kod może być całkowicie uzasadniony. Jednak może to spowodować większe zamieszanie wśród czytelników, więc dobrym pomysłem jest unikanie pisania takiego kodu, aby uniknąć „zobowiązań alimentacyjnych”.Uwaga: Mimo że zmienne licznikowe obu pętli mają ten sam identyfikator
i
, pozostają dwiema zmiennymi niezależnymi, tj. Nie używasz tej samej zmiennej w obu pętlach. Możliwe jest również użycie tej samej zmiennej w obu pętlach, ale kod byłby trudny do odczytania. Oto przykład:Teraz obie pętle używają tej samej zmiennej. Jednak zajmie trochę czasu, aby dowiedzieć się, co robi ten kod bez kompilowania go ( demo );
źródło
int
wewnętrznej pętli for, tj. Faktyczne użycie tej samej zmiennej licznika, spowoduje, że zewnętrzna pętla uruchomi się tylko raz, ponieważ wewnętrzna pętla opuścii == 10
. Jest to trywialne, ale myślę, że zapewnia wyjaśnienie, biorąc pod uwagę sposób, w jaki zostało postawione pytanieMożesz. Ale powinieneś zdawać sobie sprawę z zakresu
i
s. Jeżeli nazywamy zewnętrzneji
zi_1
a wewnętrznąi
zi_2
, zakresi
S jest następujący:Należy zauważyć, że nie oddziałują one na siebie, a tylko ich zakres definicji jest inny.
źródło
Jest to całkowicie możliwe, ale pamiętaj, że nie będziesz w stanie zająć się pierwszym zadeklarowanym i
w drugiej pętli w drugiej pętli potomnej
jeśli chcesz dostosować lub uzyskać wartość pierwszego i, użyj j w drugiej pętli
a jeśli jesteś wystarczająco kreatywny, możesz wykonać je obie w jednej pętli
źródło
Tak, możesz użyć tej samej nazwy zmiennej licznika dla
for
pętli wewnętrznej , jak dlafor
pętli zewnętrznej .Od pętli for :
Zakres loop_statement jest zagnieżdżony w zakresie init_clause .
Ze standardów C # 6.8.5p5 Instrukcje iteracyjne [ wyróżnienie moje]
Ze standardów C # 6.2.1p4 Zakresy identyfikatorów [ wyróżnienie moje]
źródło
Z punktu widzenia kodu / kompilatora byłoby to całkowicie uzasadnione i zgodne z prawem.
int i
Uznane w wewnętrznejfor(int i = 0; i < 10; i++)
pętli jest nowy i mniejszym zakresie, tak, że deklaracja cieni przyjęcia zgłoszenia oint i
w zewnętrznej pętli (lub innymi słowy, w ramach wewnętrznej wszystkich wejść do zmienneji
przejść doint i
uznane w zakresie wewnętrznego, pozostawiającint i
nietknięty zewnętrzny zakres).To powiedziawszy, z punktu widzenia jakości kodu jest to całkowicie okropne. Jest trudny do odczytania, trudny do zrozumienia i łatwy do niezrozumienia. Nie rób tego.
źródło
Tak, możesz go używać, ale jest to dość zagmatwane. Najważniejszy jest zasięg zmiennej lokalnej wewnątrz pętli. O ile zmienna jest zadeklarowana wewnątrz funkcji, zakresem tej zmiennej jest ta funkcja.
Podobnie jest w przypadku pętli, zmienna zadeklarowana wewnątrz pętli wewnętrznej ma inny zasięg, a zmienna zadeklarowana w pętli zewnętrznej ma inny zasięg.
Lepszym podejściem jest użycie różnych zmiennych dla pętli wewnętrznej i zewnętrznej.
źródło
Tak, zdecydowanie możesz użyć tej samej zmiennej nazwy.
Zmienne programowania C można zadeklarować w trzech miejscach:
zmienne lokalne: -Wewnątrz funkcji lub bloku.
Zmienne globalne: - Spoza wszystkich funkcji.
Parametry formalne: -W parametrach funkcji.
Ale w twoim przypadku
i scope
będziesz musiał pamiętać o poniższych rzeczachUwaga: Najlepszym rozwiązaniem byłoby użycie różnych zmiennych dla pętli wewnętrznej i zewnętrznej
źródło
Tak - a co jeszcze bardziej interesujące, możesz ponownie użyć nazwy zmiennej za każdym razem, gdy otwierasz zestaw nawiasów klamrowych. Jest to często przydatne podczas wstawiania kodu diagnostycznego. Wpisz otwarty nawias „{”, po którym następuje deklaracja i użycie zmiennych, a następnie zamknij nawias, a zmienne znikną. Gwarantuje to, że nie będziesz ingerować w nic w głównym ciele, zachowując jednocześnie przewagę wszelkich zmiennych, klas i metod zadeklarowanych poza nawiasami klamrowymi.
źródło
Zasada zakresu: Zmienna zadeklarowana w instrukcji for może być używana tylko w tej instrukcji i w treści pętli.
Jeśli w swoim kodzie zdefiniowałeś wiele instancji i w wewnętrznych pętlach, każda instancja będzie zajmować własną przestrzeń pamięci. Więc nie ma się co martwić o wyniki i tak byłoby tak samo.
Nie zaleca się jednak używania tej samej nazwy zmiennej, ponieważ jest ona trudna do zrozumienia i później staje się kodem niemożliwym do utrzymania.
źródło
Ważną częścią jest to, że zawiera parametr pętli wewnętrznej
int i
. Ponieważi
jest przedefiniowany w ten sposób, dwie zmienne nie wpływają na siebie; ich zakresy są różne. Oto dwa przykłady, które to pokazują:Zauważ, że powyższy kod zawiera
int i
parametr pętli wewnętrznej, a poniższy kod zawiera tylkoi
.źródło
Cóż, możesz to zrobić bez problemu ze skryptami, ale powinieneś unikać takiej struktury. Zwykle prowadzi to do zamieszania
źródło