Tại sao bảng chữ cái được chia thành nhiều phạm vi trong mã C này?


161

Trong một thư viện tùy chỉnh, tôi thấy một triển khai:

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ó phải là một quả trứng Phục sinh hay những lợi thế so với phương pháp C / C ++ tiêu chuẩn là gì?

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

Lưu ý rằng trong EBCDIC, phạm vi ký tự cho chữ in thường xuất hiện trước phạm vi ký tự cho chữ in hoa và cả hai đều đứng trước các chữ số - hoàn toàn ngược lại với thứ tự trong mã hóa dựa trên ASCII (chẳng hạn như 8859- x series, hoặc Unicode, hoặc CP1252 hoặc hoặc).
Jonathan Leffler

1
Lưu ý: nếu 'J' - 'I''S' - 'R'cả hai bằng nhau 1, thì tôi hy vọng rằng một trình tối ưu hóa hợp lý sẽ biến cái trước thành cái sau.
Matthieu M.

Câu trả lời:


214

Tác giả của mã này có lẽ đã phải hỗ trợ EBCDIC tại một số điểm, nơi các giá trị số của các chữ cái đều là phòng không tiếp giáp (khoảng cách tồn tại giữa I, JR, Snhư bạn có thể đoán).

Điều đáng chú ý là C và C ++ tiêu chuẩn duy nhất đảm bảo rằng các nhân vật 0để 9có giá trị số liền kề nhau cho chính xác lý do này, vì vậy không ai trong số những phương pháp này là đúng tiêu chuẩn phù hợp.


64
WTF thực sự là lý do tại sao tác giả ban đầu không đưa ra nhận xét : // In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details. Sau đó, bạn thậm chí không bao giờ phải đặt câu hỏi. Bạn sẽ có câu trả lời tích hợp cho mã.
abelenky

66
@abelenky Nếu mã ban đầu được sử dụng cho một hệ thống mà ebcdic thường được sử dụng, nó có thể có vẻ rõ ràng vào thời điểm đó và không cần bình luận, thật không may là những thứ có vẻ tốt trong mã kế thừa bây giờ có vẻ lạ.
Vality

26
@abelenky: WTF thực sự là lý do tại sao tác giả ban đầu không sử dụng chức năng tiêu chuẩn, tức là return ( isalpha( chValue ) && isupper( chValue ) )...
DevSolar

4
@Damon: Đó không phải là vấn đề. Bạn có thể phải xử lý mã hóa "người ngoài hành tinh" ngay cả trên một hệ thống không sử dụng mã hóa đó nguyên bản. Vì vậy, bạn đặt ngôn ngữ của mình thành mã hóa đã cho, và sau đó bạn phải giữ ngón tay của mình vượt qua rằng lập trình viên thực sự đã sử dụng các chức năng tiêu chuẩn thay vì thực hiện mã hóa "thông minh" như trên, nghĩ rằng anh ta biết mọi chương trình mã hóa của mình sẽ gặp phải ...
DevSolar

6
Nếu nó được viết để hỗ trợ EBCDIC từ những năm 1970, thì isalpha và isupper thậm chí là ANSI hay được hỗ trợ bởi phần lớn các trình biên dịch hồi đó?
nickalh

54

Có vẻ như nó cố gắng bao gồm cả EBCDIC và ASCII. Phương pháp thay thế của bạn không hoạt động đối với EBCDIC (nó có kết quả dương tính giả, nhưng không có phủ định sai)

C và C ++ không yêu cầu phải '0'-'9'liên tục.

Lưu ý rằng các cuộc gọi thư viện tiêu chuẩn sẽ biết liệu chúng có chạy trên ASCII, EBCDIC hoặc các hệ thống khác hay không, vì vậy chúng dễ mang theo hơn và có thể hiệu quả hơn.


5
std::isupperthực sự truy vấn ngôn ngữ C toàn cầu hiện đang được cài đặt.
Lingxi

1
Vâng, bạn đúng. Phương pháp này được viết để bao gồm cả mã hóa. Cảm ơn câu trả lời!
Vladimir Ch.

4
@Lingxi: Đúng, nhưng điều đó không có nghĩa là bạn có thể chuyển ngôn ngữ từ ASCII sang EBCDIC. 'A'phải ở lại'A' bất kể từ miền địa phương. ASCII đến UTF-8, điều đó là có thể.
MSalters

2
@Lingxi: std::isuppertruy vấn ngôn ngữ C toàn cầu hiện đang được cài đặt, vâng, nhưng giai đoạn biên dịch diễn giải nghĩa đen của ký tự thì không.
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
@Lingxi - Chỉ cần ghi chú nhanh. Một câu hỏi đặt ra std::isupperlà có thực sự cần thiết trong hầu hết các trường hợp hay không. Nó tôn trọng các địa phương được sử dụng cho đầu vào từ người dùng. Nhưng khi phân tích tệp, tương tác với cơ sở dữ liệu, bạn thường mong đợi một số ngôn ngữ khác. Ngoài ra, ít nhất là trên Linux, các cuộc gọi liên quan đến ngôn ngữ này rất chậm - ví dụ như std::isalphagọi Dynamic_cast hai lần để "tìm" triển khai ngôn ngữ phù hợp trước khi thực sự so sánh một ký tự.
ioust5041
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.