W bibliotece niestandardowej zobaczyłem implementację:
inline int is_upper_alpha(char chValue)
{
if (((chValue >= 'A') && (chValue <= 'I')) ||
((chValue >= 'J') && (chValue <= 'R')) ||
((chValue >= 'S') && (chValue <= 'Z')))
return 1;
return 0;
}
Czy to jajko wielkanocne, czy też jakie są zalety w porównaniu ze standardową metodą C / C ++?
inline int is_upper_alpha(char chValue)
{
return ((chValue >= 'A') && (chValue <= 'Z'));
}
'J' - 'I'
i'S' - 'R'
oba są równe1
, to spodziewam się, że rozsądne byłoby włączyć optymalizator były w tym ostatnim.Odpowiedzi:
Autor tego kodu prawdopodobnie musiał w pewnym momencie obsługiwać EBCDIC , gdy wartości liczbowe liter nie są ciągłe (istnieją luki między
I
,J
aR
,S
jak można się domyślić).Warto zauważyć, że standardy C i C ++ gwarantują tylko, że znaki
0
będą9
miały ciągłe wartości liczbowe właśnie z tego powodu, więc żadna z tych metod nie jest ściśle zgodna ze standardami.źródło
// In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details
. Wtedy nigdy nie musiałbyś nawet zadawać tego pytania. Odpowiedź byłaby wbudowana w kod.return ( isalpha( chValue ) && isupper( chValue ) )
...Wygląda na to, że próbuje objąć zarówno EBCDIC, jak i ASCII. Twoja alternatywna metoda nie działa w przypadku EBCDIC (ma fałszywe alarmy, ale nie ma fałszywych negatywów)
C i C ++ nie wymagają,
'0'-'9'
są przyległe.Należy pamiętać, że standardowe połączenia biblioteki nie wiem, czy działają one na ASCII, EBCDIC lub innych systemów, więc są bardziej przenośne i prawdopodobnie bardziej efektywne.
źródło
std::isupper
faktycznie pyta o aktualnie zainstalowane globalne locale C.'A'
musi pozostać'A'
niezależnie od lokalizacji. ASCII do UTF-8, to byłoby możliwe.std::isupper
odpytuje aktualnie zainstalowane globalne locale C, tak, ale faza kompilacji, która interpretuje literały znaków, nie.std::isupper
w większości przypadków jest to naprawdę potrzebne. Szanuje ustawienia regionalne używane do wprowadzania danych przez użytkownika. Ale podczas analizowania plików, interakcji z bazami danych, zwykle spodziewasz się innych ustawień regionalnych. Co więcej, przynajmniej w Linuksie te wywołania związane z ustawieniami lokalnymi są bardzo powolne - na przykładstd::isalpha
wywołanie dynamic_cast dwa razy w celu „znalezienia” właściwej implementacji ustawień regionalnych przed faktycznym porównaniem pojedynczego znaku.