Kiedy warto używać zmiennej bez znaku zamiast zmiennej ze znakiem? A co z for
pętlą?
Słyszę wiele opinii na ten temat i chciałem sprawdzić, czy jest coś na kształt konsensusu.
for (unsigned int i = 0; i < someThing.length(); i++) {
SomeThing var = someThing.at(i);
// You get the idea.
}
Wiem, że Java nie ma wartości bez znaku, a to musiała być świadoma decyzja ze strony Sun Microsystems .
language-agnostic
types
Bernarda
źródło
źródło
Odpowiedzi:
Cieszyłem się, że znalazłem dobrą rozmowę na ten temat, ponieważ wcześniej nie myślałem o tym zbyt wiele.
Podsumowując, znak ze znakiem jest dobrym wyborem ogólnym - nawet jeśli nie masz pewności, że wszystkie liczby są dodatnie - jeśli zamierzasz wykonać operacje arytmetyczne na zmiennej (jak w typowym przypadku pętli).
Jeśli zamierzasz robić rzeczy bitowe, takie jak maski, brak znaku zaczyna mieć więcej sensu. Lub, jeśli desperacko pragniesz uzyskać ten dodatkowy dodatni zakres, wykorzystując bit znaku.
Osobiście lubię podpisane, ponieważ nie ufam sobie, że będę konsekwentny i unikam mieszania tych dwóch typów (jak ostrzega artykuł).
źródło
unsigned
znacznie lepiej sprawdza się w wykrywaniu przepełnienia niezaufanych danych wejściowych. Niestety, proponowane „odpowiedzi” na zagadkę nie są aż tak świetne. Moja jesttemplate<size_t limit> bool range_check_sum( unsigned a, unsigned b ) { return (a < limit) && (b < limit - a); }
taka, że jeśli ktoś ma podobnie prostą i prostą odpowiedź przy użyciu podpisanych typów, z przyjemnością to zobaczy.W powyższym przykładzie, gdy „i” zawsze będzie dodatnie, a wyższy zakres byłby korzystny, bez znaku byłby przydatny. Na przykład, jeśli używasz instrukcji „deklaruj”, takich jak:
Zwłaszcza, gdy te wartości nigdy się nie zmienią.
Jeśli jednak robisz program księgowy, w którym ludzie są nieodpowiedzialni za swoje pieniądze i ciągle są na minusie, z pewnością będziesz chciał użyć opcji „podpisane”.
Zgadzam się jednak z saintem, że dobrą praktyczną zasadą jest użycie znaku podpisanego, który tak naprawdę jest domyślny w C, więc jesteś objęty ochroną.
źródło
Myślę, że jeśli sprawa biznesu mówi, że liczba ujemna jest nieważny, byś chciał mieć błąd pokazany lub wyrzucane.
Mając to na uwadze, dopiero niedawno dowiedziałem się o liczbach całkowitych bez znaku, pracując nad projektem, przetwarzając dane w pliku binarnym i zapisując je w bazie danych. Celowo „uszkadzałem” dane binarne i otrzymałem wartości ujemne zamiast oczekiwanego błędu. Okazało się, że mimo przeliczenia wartości nie była ona prawidłowa w moim przypadku biznesowym.
Mój program nie popełnił błędu i skończyło się na tym, że dostałem błędne dane do bazy danych. Byłoby lepiej, gdybym użył
uint
i wystąpił błąd programu.źródło
Kompilatory C i C ++ wygenerują ostrzeżenie podczas porównywania typów podpisanych i niepodpisanych; w przykładowym kodzie nie można było zrobić zmiennej pętli bez znaku i kazać kompilatorowi wygenerować kod bez ostrzeżeń (zakładając, że te ostrzeżenia były włączone).
Oczywiście kompilujesz z ostrzeżeniami ustawionymi do góry, prawda?
I czy rozważałeś kompilację z „traktuj ostrzeżenia jako błędy”, aby pójść o krok dalej?
Wadą używania liczb ze znakiem jest to, że istnieje pokusa, aby je przeładować, tak aby na przykład wartości 0-> n były wyborem menu, a -1 oznacza, że nic nie zostało wybrane - zamiast tworzyć klasę, która ma dwie zmienne, jedną do wskaż, czy coś jest zaznaczone, a inne, aby zapisać, co to jest. Zanim się zorientujesz, wszędzie testujesz negatywny wynik, a kompilator narzeka, że chcesz porównać wybór menu z liczbą opcji menu, które masz - ale jest to niebezpieczne, ponieważ są to różne typy . Więc nie rób tego.
źródło
size_t
jest często dobrym wyborem do tego celu lubsize_type
jeśli używasz klasy STL.źródło
size_type
element członkowski dla liczby elementów, a nie tylko bajtów. Powinien być używany zamiast tego,std::size_t
gdzie jest dostępny, ale niedokładne jest sugerowanie, że wszystko, co zaczyna się od,size_t
może oznaczać tylko bajty.