Warum ist das Alphabet in diesem C-Code in mehrere Bereiche aufgeteilt?

Lesezeit: 4 Minuten

Benutzeravatar von Vladimir Ch
Wladimir Ch.

In einer benutzerdefinierten Bibliothek habe ich eine Implementierung gesehen:

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

Ist das ein Osterei oder was sind die Vorteile gegenüber der Standard-C/C++-Methode?

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

  • Beachten Sie, dass in EBCDIC der Zeichenbereich für Kleinbuchstaben vor dem Zeichenbereich für Großbuchstaben steht und beide vor den Ziffern stehen – was genau das Gegenteil der Reihenfolge in ASCII-basierten Codierungen ist (wie z. B. 8859- x-Serie oder Unicode oder CP1252 oder …).

    – Jonathan Leffler

    6. Mai 2015 um 13:44 Uhr

  • Hinweis: Wenn 'J' - 'I' und 'S' - 'R' beide gleich 1dann erwarte ich, dass ein vernünftiger Optimierer Ersteres in Letzteres verwandeln würde.

    – Matthias M.

    6. Mai 2015 um 14:44 Uhr


Benutzeravatar von Wintermute
Winterstumm

Der Autor dieses Codes musste vermutlich unterstützen EBCDIC an einem Punkt, an dem die numerischen Werte der Buchstaben nicht zusammenhängend sind (es gibt Lücken zwischen I, J und R, Swie Sie vielleicht schon erraten haben).

Es ist erwähnenswert, dass die C- und C++-Standards nur garantieren, dass die Zeichen 0 zu 9 haben genau aus diesem Grund zusammenhängende numerische Werte, sodass keine dieser Methoden streng standardkonform ist.

  • Die wahre WTF ist, warum der ursprüngliche Autor keinen Kommentar abgegeben hat: // In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details. Dann müsstest du die Frage gar nicht erst stellen. Sie hätten die Antwort in den Code integriert.

    – abelenky

    5. Mai 2015 um 15:12 Uhr


  • @abelenky Wenn der Code ursprünglich für ein System bestimmt war, auf dem normalerweise ebcdic verwendet wird, schien er zu diesem Zeitpunkt offensichtlich zu sein und erforderte keinen Kommentar. Leider erscheinen Dinge, die in Legacy-Code in Ordnung zu sein scheinen, jetzt seltsam.

    – Wertigkeit

    5. Mai 2015 um 15:57 Uhr

  • @abelenky: Die real WTF ist, warum der ursprüngliche Autor keine Standardfunktionalität verwendet hat, dh return ( isalpha( chValue ) && isupper( chValue ) )

    – DevSolar

    6. Mai 2015 um 8:12 Uhr


  • @Damon: Das ist nicht das Problem. Das müssen Sie vielleicht Prozess eine “fremde” Codierung, selbst auf einem System, das diese Codierung nicht nativ verwendet. Sie stellen also Ihr Gebietsschema auf die angegebene Codierung ein und müssen dann die Daumen drücken, dass der Programmierer tatsächlich Standardfunktionen verwendet hat, anstatt “intelligente” Codierungen wie oben durchzuführen, und denkt, er kennt jede Codierung, auf die sein Programm jemals stoßen wird …

    – DevSolar

    6. Mai 2015 um 9:53 Uhr


  • Wenn es geschrieben wurde, um EBCDIC aus den 1970er Jahren zu unterstützen, waren dann isalpha und isupper sogar ANSI oder wurden damals von den meisten Compilern unterstützt?

    – Nickalh

    6. Mai 2015 um 11:45 Uhr

Sieht so aus, als würde es versuchen, sowohl EBCDIC als auch ASCII abzudecken. Ihre alternative Methode funktioniert nicht für EBCDIC (sie hat falsch positive, aber keine falsch negativen)

C und C++ tun verlangen das '0'-'9' sind zusammenhängend.

Beachten Sie, dass die Standardbibliothek aufruft tun wissen, ob sie auf ASCII-, EBCDIC- oder anderen Systemen laufen, damit sie portabler und möglicherweise effizienter sind.

  • std::isupper fragt tatsächlich das aktuell installierte globale C-Gebietsschema ab.

    – Lingxi

    5. Mai 2015 um 10:21 Uhr

  • Ja, du hast recht. Das Verfahren ist so geschrieben, dass es beide Codierungen abdeckt. Danke für die Antwort!

    – Wladimir Ch.

    5. Mai 2015 um 10:26 Uhr

  • @Lingxi: Stimmt, aber das bedeutet nicht, dass Sie das Gebietsschema von ASCII auf EBCDIC umstellen können. 'A' muss bleiben 'A' unabhängig vom Gebietsschema. ASCII nach UTF-8, das wäre möglich.

    – MSalter

    5. Mai 2015 um 10:29 Uhr

  • @Lingxi: std::isupper fragt das aktuell installierte globale C-Gebietsschema ab, ja, aber die Phase der Kompilierung, die Zeichenliterale interpretiert, tut dies nicht.

    – Leichtigkeitsrennen im Orbit

    5. Mai 2015 um 10:51 Uhr

  • @Lingxi – Nur eine kurze Notiz. Es ist fraglich, ob std::isupper wird in den meisten Fällen wirklich benötigt. Es respektiert Gebietsschemas, die für Benutzereingaben verwendet werden. Aber wenn Sie Dateien parsen und mit Datenbanken interagieren, erwarten Sie normalerweise ein anderes Gebietsschema. Darüber hinaus sind zumindest unter Linux diese locale-bezogenen Aufrufe sehr langsam – zum Beispiel std::isalpha ruft dynamic_cast zweimal auf, um die richtige Locale-Implementierung zu “finden”, bevor tatsächlich ein einzelnes Zeichen verglichen wird.

    – ibre5041

    6. Mai 2015 um 7:02 Uhr

1424690cookie-checkWarum ist das Alphabet in diesem C-Code in mehrere Bereiche aufgeteilt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy