ทำไมตัวอักษรถึงแบ่งออกเป็นหลายช่วงในรหัส 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 หรือ ... )
Jonathan Leffler

1
หมายเหตุ: หาก'J' - 'I'และ'S' - 'R'ทั้งสองเท่ากัน1จากนั้นฉันคาดหวังว่าเครื่องมือเพิ่มประสิทธิภาพที่เหมาะสมจะเปลี่ยนอดีตในภายหลัง
Matthieu M.

คำตอบ:


214

ผู้เขียนรหัสนี้สันนิษฐานได้ให้การสนับสนุนEBCDICในบางจุดที่ค่าเป็นตัวเลขของตัวอักษรที่ไม่ต่อเนื่องกัน (ช่องว่างอยู่ระหว่างI, JและR, Sในขณะที่คุณอาจจะเดา)

เป็นที่น่าสังเกตว่ามาตรฐาน C และ C ++ รับประกันได้ว่าตัวละคร0จะ9มีค่าตัวเลขที่ต่อเนื่องกันด้วยเหตุผลนี้เท่านั้นดังนั้นวิธีการเหล่านี้จึงไม่สอดคล้องกับมาตรฐานอย่างเคร่งครัด


64
// In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for detailsวะจริงคือเหตุผลที่ไม่ได้ใส่ผู้เขียนต้นฉบับในความคิดเห็น: ถ้าอย่างนั้นคุณก็ไม่จำเป็นต้องถามคำถามเลย คุณมีคำตอบในตัวรหัส
abelenky

66
@abelenky หากรหัสเดิมสำหรับระบบที่ใช้ ebcdic ปกติมันอาจจะเห็นได้ชัดในเวลานั้นและไม่จำเป็นต้องมีความคิดเห็น แต่น่าเสียดายที่สิ่งต่าง ๆ ที่ดูเหมือนว่าดีในรหัสมรดกดูเหมือนแปลกในขณะนี้
Vality

26
@abelenky: WTF ตัวจริงคือเหตุผลที่ว่าทำไมผู้เขียนดั้งเดิมไม่ได้ใช้ฟังก์ชั่นมาตรฐานนั่นคือreturn ( isalpha( chValue ) && isupper( chValue ) )...
DevSolar

4
@Damon: นั่นไม่ใช่ปัญหา คุณอาจต้องประมวลผลการเข้ารหัส "เอเลี่ยน" แม้ในระบบที่ไม่ได้ใช้การเข้ารหัสนั้น ดังนั้นคุณตั้งค่าโลแคลของคุณเป็นการเข้ารหัสที่กำหนดและจากนั้นคุณต้องให้นิ้วของคุณข้ามไปที่โปรแกรมเมอร์ใช้ฟังก์ชั่นมาตรฐานแทนการทำรหัส "ฉลาด" ดังที่กล่าวมาข้างต้นโดยคิดว่าเขารู้ทุกการเข้ารหัสโปรแกรมของเขา
DevSolar

6
ถ้ามันถูกเขียนขึ้นเพื่อรองรับ EBCDIC จากปี 1970 isalpha และ isupper แม้แต่ ANSI หรือสนับสนุนโดยคอมไพเลอร์ส่วนใหญ่แล้ว
nickalh

54

ดูเหมือนว่าจะพยายามครอบคลุมทั้ง EBCDIC และ ASCII วิธีการอื่นของคุณใช้ไม่ได้กับ EBCDIC (มีข้อดีเป็นเท็จ แต่ไม่มีเชิงลบที่ผิด)

C และ C ++ ไม่จำเป็นต้องให้'0'-'9'มีความต่อเนื่องกัน

โปรดทราบว่าการเรียกใช้ไลบรารี่มาตรฐานจะทราบว่าพวกเขาทำงานบน ASCII, EBCDIC หรือระบบอื่น ๆ หรือไม่ดังนั้นจึงมีความคล่องตัวและอาจมีประสิทธิภาพมากกว่า


5
std::isupperจริงแบบสอบถามตำแหน่งที่ตั้งส่วนกลาง C ที่ติดตั้งอยู่ในปัจจุบัน
Lingxi

1
ใช่คุณถูก. วิธีนี้เขียนขึ้นเพื่อให้ครอบคลุมการเข้ารหัสทั้งสอง ขอบคุณสำหรับคำตอบ!
วลาดิมีร์ Ch

4
@Lingxi: จริง แต่นั่นไม่ได้หมายความว่าคุณสามารถเปลี่ยนสถานที่จาก ASCII เป็น EBCDIC 'A'ต้องอยู่'A'โดยไม่คำนึงถึงสถานที่ ASCII ถึง UTF-8 ที่จะเป็นไปได้
MSalters

2
@Lingxi: std::isupperเคียวรีโลแคล C โกลบอลที่ติดตั้งในปัจจุบันใช่ แต่เฟสของการคอมไพล์ที่ตีความตัวอักษรของอักขระไม่ได้
การแข่งขัน Lightness ใน Orbit

1
@Lingxi - เพียงบันทึกย่อ เป็นที่น่าสงสัยว่าstd::isupperในกรณีส่วนใหญ่จำเป็นหรือไม่ มันเคารพสถานที่ที่ใช้สำหรับการป้อนข้อมูลจากผู้ใช้ แต่เมื่อทำการแยกวิเคราะห์ไฟล์การโต้ตอบกับฐานข้อมูลคุณมักจะคาดหวังสถานที่อื่น ๆ นอกจากนี้อย่างน้อยบน Linux การเรียกที่เกี่ยวข้องกับโลแคลเหล่านี้ช้ามาก - ตัวอย่างเช่นการstd::isalphaเรียก dynamic_cast สองครั้งเพื่อ "ค้นหา" การใช้โลแคลที่เหมาะสมก่อนที่จะเปรียบเทียบอักขระเดียวจริง ๆ
ibre5041
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.