Чому в цьому коді C алфавіт розділений на кілька діапазонів?


161

У спеціальній бібліотеці я побачив реалізацію:

inline int is_upper_alpha(char chValue)
{
    if (((chValue >= 'A') && (chValue <= 'I')) ||
        ((chValue >= 'J') && (chValue <= 'R')) ||
        ((chValue >= 'S') && (chValue <= 'Z')))
        return 1;
    return 0;
}

Це писанка або які переваги перед стандартним методом C / C ++?

inline int is_upper_alpha(char chValue)
{
    return ((chValue >= 'A') && (chValue <= 'Z'));
}

Зауважте, що в EBCDIC діапазон символів для малих букв виходить перед діапазоном символів для великих літер, а обидва - перед цифрами - що прямо протилежне порядку в кодування на основі ASCII (наприклад, 8859- серія x, або Unicode, або CP1252, або…).
Джонатан Леффлер

1
Примітка: якщо 'J' - 'I'і 'S' - 'R'обидва рівні 1, тоді я сподіваюся, що розумний оптимізатор перетворить перший у другий.
Матьє М.

Відповіді:


214

Автор цього коду імовірно мав підтримувати EBCDIC в якій - то точці, де числові значення букв є непослідовною (пропуск існують між I, Jі R, Sяк ви вже здогадалися).

Варто відзначити , що C і C ++ стандарти тільки гарантує , що символи 0НЕ 9мають безперервні числові значення саме по цій причині, так що ні один з цих методів, суворо відповідний стандартам.


64
Реальний WTF чому не зробив початковий автор поклав в коментарі: // In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details. Тоді вам ніколи навіть не доведеться ставити питання. У вас буде вбудована відповідь до коду.
абеленький

66
@abelenky Якщо код спочатку був для системи, де ebcdic зазвичай використовується, він, можливо, здавався очевидним і не потребував коментарів, на жаль, речі, які здаються прекрасними у застарілому коді, зараз здаються дивними.
Vality

26
@abelenky: Справжній WTF - це те, чому оригінальний автор не використовував стандартну функціональність, тобто return ( isalpha( chValue ) && isupper( chValue ) )...
DevSolar

4
@Damon: Це не проблема. Можливо, вам доведеться обробити "чужорідне" кодування навіть у системі, яка не використовує кодування на самому собі. Таким чином, ви встановите свою локальну локалізацію на задане кодування, а потім вам слід тримати пальці, щоб програміст фактично використовував стандартні функції замість того, щоб робити "розумне" кодування, як описано вище, думаючи, що він знає, що кожне кодування його програми коли-небудь зустрінеться ...
DevSolar

6
Якщо це було написано на підтримку EBCDIC з 1970-х, чи була ізалфа і самовивірка ANSI чи тоді підтримувалася більшістю компіляторів?
nickalh

54

Схоже, це намагається охопити як EBCDIC, так і ASCII. Ваш альтернативний метод не працює для EBCDIC (він має помилкові позитиви, але не має помилкових негативів)

C і C ++ дійсно вимагають, '0'-'9'є суміжними.

Зверніть увагу , що стандартні бібліотечні виклики дійсно знають , чи запускати вони на ASCII, EBCDIC або інших систем, тому вони більш портативними і , можливо , більш ефективним.


5
std::isupperнасправді запитує поточно встановлену глобальну локальну мову C.
Лінсі

1
Так, ти маєш рацію. Метод написаний для покриття обох кодувань. Дякую за відповідь!
Володимир Ч.

4
@Lingxi: Це правда, але це не означає, що ви можете переключити локаль з ASCII на EBCDIC. 'A'має залишатися 'A'незалежно від місцевості. ASCII до UTF-8, це було б можливо.
MSalters

2
@Lingxi: std::isupperзапитує поточно встановлену глобальну локальну мову C, так, але фаза компіляції, що інтерпретує літеральні символи, не відповідає.
Гонки легкості по орбіті

1
@Lingxi - Просто швидка примітка. Сумнівно, чи std::isupperдійсно це потрібно в більшості випадків. Він поважає локалі, які використовуються для введення даних від користувача. Але під час розбору файлів, взаємодії з базами даних, ви зазвичай очікуєте деякого іншого локалу. Більше того, принаймні в Linux ці дзвінки, пов’язані з std::isalphaлокальною локальністю , дуже повільні - наприклад, дзвінки з динамічним_кастом два рази, щоб "знайти" належну реалізацію локалі, перш ніж насправді порівнювати один символ.
ibre5041
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.