Was ist die Idee hinter ^= 32, wandelt Kleinbuchstaben Ober-und Umgekehrt?

War ich der Lösung einiger problem auf codeforces. Normalerweise bin ich erstmal prüfen, ob das Zeichen ist die Obere oder untere Englisch schreiben, dann subtrahieren oder fügen Sie 32 zu konvertieren, um den entsprechenden Buchstaben. Aber ich fand jemand ^= 32 um das gleiche zu tun. Hier ist es:

char foo = 'a';
foo ^= 32;
char bar = 'A';
bar ^= 32;
cout << foo << ' ' << bar << '\n'; //foo is A, and bar is a

Suchte ich nach einer Erklärung für diese und nicht herausfinden. Also, warum das funktioniert?

  • en.wikipedia.org/wiki/File:USASCII_code_chart.png Tipp: Sie können konvertieren @ in " mit ^ 32.
  • FWIW, es ist nicht wirklich "Arbeit". Es funktioniert für dieses Besondere Zeichen gesetzt, aber es gibt andere sets, wenn es nicht, sollten Sie Sie verwenden toupper und tolower zu wechseln, Fällen.
  • irgendwann mit online-Gewinnspiele "die Idee" ist, code zu schreiben, bei solch einer verwirrenden Weise, dass es nie eine ernsthafte überprüfung 😉
  • ^= ist die Umwandlung der Wert mit XOR. Großbuchstaben ASCII-Buchstaben haben eine null in das entsprechende bit, während Kleinbuchstaben ein. Das heißt, bitte nicht! Verwenden Sie die richtigen Zeichen (unicode -) Routinen zur Konvertierung zwischen klein-und Großschreibung. Die ära der nur ASCII ist lange vorbei.
  • was @NathanOliver sagte. Das ist nett, aber sein gehen, verursachen einen Fehler.
  • Es ist nicht nur, dass es funktioniert nur mit manchen Zeichensätzen. Selbst wenn wir annehmen, dass alle Welt UTF-8 (das könnte zumindest eine nette utopische Ziel), es funktioniert darüber hinaus nur mit den 26 Buchstaben A zu Z. Das ist in Ordnung, solange Sie nur die Sorge um Deutsch (und nicht verwenden, Schreibweisen von "naiv", Wörter wie "café" oder Namen mit diakritischen Zeichen...), aber die Welt ist nicht nur Englisch.
  • Verwandte: Sie können prüfen, ob Sie eine alphabetische ASCII-Zeichen durch erzwingen Kleinbuchstaben mit |= 0x20 und dann die Kontrolle (unsigned) if(c - 'a' < ('a'-'z')). Also nur 3 Operationen: ODER + SUB + CMP. Siehe auch Wandelt einen String In C++ - groß SIMD (string toupper Maskierung der operand XOR) und Wie auf ein char-array und ändere Kleinbuchstaben in Großbuchstaben und Umgekehrt (C mit SIMD-Interna, und skalaren x86-asm-Fall-Abdeckung für alphabetische Zeichen, so dass andere unverändert.)
  • Auch wenn [sehr hypothetisch] das war weniger empfindlich und haben mehr Charakter-sets, etc., Ich würde noch raten es zu benutzen. Es sind standard-Möglichkeiten, um dies zu tun, so versuchen, um die Vorteile der Werkzeuge, die bereits existieren. Erfinden Sie Ihre eigene "clevere" Art und Weise zu tun, es ist eine großartige Möglichkeit, um am Ende mit nicht lesbar/wartbaren code, das ist wirklich schwer zu Debuggen, wenn Sie schließlich feststellen, dass der Fall ist, bricht Ihre Umsetzung. (Nur ein allgemeiner Kommentar und nicht ein Angriff auf die OP, die wirklich nur gefragt warum das funktioniert)
  • Ich kann nicht sagen, von der Frage, ob Sie wissen, was die ^ und ^= Betreiber in den ersten Platz, aber es ist relevant für die Beantwortung Ihrer Frage. Tun Sie?
  • Nebenbei die XOR/ODER usw. ist eine sehr verbreitete Methode für EBCDIC Fall das wechseln und hantieren. Ich würde nicht versuchen, diese mit DBCS noch Unicode. Umwandlung in " int " für arithmetische weitgehend in Ungnade gefallen, für viele gute Gründe.
  • Im follow-up an @NathanOliver Kommentar - Dinge, die zu funktionieren scheinen für einen Teil der Dinge, aber nicht behaupten, dass Sie nur vermittelt bekommen, dass die Teilmenge ist betteln für ein Fehler in der Zukunft ... und du wirst es nie erfahren. Wenn Sie nicht möchten, zu verwenden, std::toupper/tolower (weil vielleicht Ihrer Plattform nicht bieten die std-Bibliothek), dann sollten Sie zumindest geltend machen, dass Sie suchen, bei [a-zA-Z]
  • TBH toupper und tolower sind hoffnungslos gebrochen in alle multibyte-Codierung, wie die ach-so-selten-verwendet UTF-8. Es wäre vielleicht eine Lösung, vielleicht in den 80er Jahren, aber heute würde ich argumentieren, ist wahrscheinlich noch schlimmer als ^32.
  • Mögliche Duplikate von Wie geht s[i]^=32 konvertieren oberen bis zum unteren Fall?
  • Ich habe immer gewusst, dass dieser trick als ^= ' '
  • Der "trick", den ich verwendet wurde, war ^= 'A' ^ 'a' wenn toupper() war nicht verfügbar und benötigt enge code.
  • Es funktioniert einfach für die standard-ASCII-Tabelle, wobei der Abstand 32 zwischen groß-Buchstaben und einem Kleinbuchstaben Alphabete. Es berücksichtigt nicht die locale oder die erweiterte ASCII-Tabelle. In der grundlegenden Tabelle, können Sie diese verwenden, um zu gehen von e zu e oder Umgekehrt. Aber in der locale fr_FR, alle Varianten des e zuzuordnen sind E-Mail, wenn groß geschrieben, aber in fr_CA, die Akzente bleiben. Das bedeutet, dass Großbuchstaben("eéèëê") ==> "EEEEE" in fr_FR ==> "EÉÈËÊ" in fr_CA.

InformationsquelleAutor Devon | 2019-02-05
Schreibe einen Kommentar