Was bewirken einfache Anführungszeichen in C++, wenn sie für mehrere Zeichen verwendet werden?

Lesezeit: 4 Minuten

Was bewirken einfache Anfuhrungszeichen in C wenn sie fur mehrere
Luzidrealität

Mich interessiert dieser Code:

cout << 'test'; // Note the single quotes.

gibt mir eine Ausgabe von 1952805748.

Meine Frage: Ist die Ausgabe eine Adresse im Speicher oder so?

  • Beachten Sie, dass der tatsächliche Wert implementierungsdefiniert ist stackoverflow.com/questions/3960954/c-multicharacter-literal

    – FireAphis

    18. September 2011 um 7:46 Uhr

1647178208 959 Was bewirken einfache Anfuhrungszeichen in C wenn sie fur mehrere
K-ballo

Es ist ein Literal mit mehreren Zeichen. 1952805748 ist 0x74657374die zerfällt als

0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'

Bearbeiten:

C++-Standard, §2.14.3/1 – Zeichenliterale

(…) Ein gewöhnliches Zeichenliteral, das mehr als ein c-char enthält, ist ein Mehrzeichenliteral . Ein aus mehreren Zeichen bestehendes Literal hat den Typ int und einen durch die Implementierung definierten Wert.

  • Sie haben nicht erwähnt, dass dies implementierungsdefiniert ist.

    – Thomas Bonini

    18. September 2011 um 15:23 Uhr

  • Ich nehme an, das Witzigste an dieser Definition ist das sizeof(int) ist auch die Implementierung definiert. Es wird also nicht nur die Implementierung der Speicherreihenfolge definiert, sondern auch deren maximale Länge.

    – bobobobo

    28. Dezember 2013 um 16:32 Uhr

Was bewirken einfache Anfuhrungszeichen in C wenn sie fur mehrere
chys

Nein, es ist keine Adresse. Es ist das sogenannte Multibyte-Zeichen.

Typischerweise sind es die ASCII-Werte der vier kombinierten Zeichen.

't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74; 

0x74657374 ist also 1952805748.

Aber es kann auch 0x74736574 auf einem anderen Compiler sein. Die C- und C++-Standards sagen beide, dass der Wert von Multibyte-Zeichen ist Umsetzung definiert. So allgemein ist seine Verwendung stark entmutigt.

  • Ist die Länge eines solchen Multibyte-Zeichens auf 4 Bytes beschränkt? Dh stellt es ein als Zeichen ausgeschriebenes int dar?

    – Giorgio

    18. September 2011 um 8:47 Uhr


  • @Giorgio: Der Standard sagt nur, dass seine Implementierung definiert ist, ohne weitere Details. In der Praxis seit int auf den meisten Maschinen 4 Bytes beträgt, halte ich es nicht für sinnvoll, mehr als 4 Bytes zu verwenden. Ja, es sollte ein bequemer Weg sein, um einige Konstanten zu schreiben, aber leider haben verschiedene Compiler es unterschiedlich interpretiert, so dass heutzutage die meisten Codierungsstile von seiner Verwendung abraten.

    – Chys

    18. September 2011 um 8:52 Uhr


  • @chys: Und die Tatsache, dass es implementierungsdefiniert ist, bedeutet, dass es nicht einmal konsistent sein muss. Ein konformer Compiler könnte beispielsweise allen Literalen mit mehreren Zeichen den Wert 0 geben (obwohl das unfreundlich wäre).

    – Keith Thompson

    18. September 2011 um 19:28 Uhr

  • Man muss sich fragen, warum dieses verrückte Feature im Standard existiert. Es scheint ein so seltener Anwendungsfall zu sein, ist die Implementierung sowieso definiert und kann bei Bedarf ganz klar mit gewöhnlicher Bitverschiebung und ODER-Verknüpfung durchgeführt werden.

    – Boanne

    23. Februar 2013 um 2:11 Uhr

  • @Bann Jawohl, meine Gefühle genau. Aber Sie können es sicher in Schaltern und so weiter verwenden, als direkten Vergleich für == sollte auschecken

    – bobobobo

    21. Dezember 2013 um 2:07 Uhr

1647178210 64 Was bewirken einfache Anfuhrungszeichen in C wenn sie fur mehrere
Mouna Cheikhna

Ein gewöhnliches Zeichenliteral, das mehr als ein c-char enthält, ist ein Mehrzeichenliteral. Ein aus mehreren Zeichen bestehendes Literal hat den Typ int und einen durch die Implementierung definierten Wert.

Implementierungsdefiniertes Verhalten muss von der Implementierung dokumentiert werden. zum Beispiel in gcc finden Sie es Hier

Der Compiler wertet eine Mehrzeichen-Zeichenkonstante zeichenweise aus, verschiebt den vorherigen Wert um die Anzahl der Bits pro Zielzeichen nach links und führt dann eine ODER-Verknüpfung im Bitmuster des neuen Zeichens durch, das auf die Breite eines Ziels gekürzt wird Charakter. Das endgültige Bitmuster erhält den Typ int und ist daher vorzeichenbehaftet, unabhängig davon, ob einzelne Zeichen vorzeichenbehaftet sind oder nicht.

Überprüfen Sie die Erklärung in diese Seite für mehr Details

Sie sind wirklich gerecht intS. Sie werden ausgiebig in den Enums der Core Audio API verwendet, zum Beispiel in der CoreAudioTypes.h Header-Datei,

enum
{
    kAudioFormatLinearPCM               = 'lpcm',
    kAudioFormatAC3                     = 'ac-3',
    kAudioFormat60958AC3                = 'cac3',
    kAudioFormatAppleIMA4               = 'ima4',
    kAudioFormatMPEG4AAC                = 'aac ',
    kAudioFormatMPEG4CELP               = 'celp',
} ;

Es wird viel darüber geredet, dass dies nicht “plattformunabhängig” ist, aber wenn Sie eine API verwenden, ist das so gemacht für eine bestimmte Plattform, die sich um Portabilität kümmert. Die Prüfung auf Gleichheit auf derselben Plattform wird niemals fehlschlagen. Diese enum‘d Werte sind einfacher zu lesen und sie enthalten tatsächlich ihre Identität in ihrem Wertwas ziemlich nett ist.

Was ich unten versucht habe, ist, ein Multibyte-Zeichenliteral zu verpacken, damit es gedruckt werden kann (auf dem Mac funktioniert das). Das Merkwürdige ist, wenn man nicht alle 4 Zeichen aufbraucht, wird das Ergebnis unten falsch..

#include <stdio.h>

#define MASK(x,BYTEX) ((x&(0xff<<8*BYTEX))>>(8*BYTEX))

struct Multibyte
{
  union{
    int val ;
    char vals[4];
  };

  Multibyte() : val(0) { }
  Multibyte( int in )
  {
    vals[0] = MASK(in,3);
    vals[1] = MASK(in,2);
    vals[2] = MASK(in,1);
    vals[3] = MASK(in,0);
  }
  char operator[]( int i ) {
    return val >> (3-i)*8 ; // works on mac
    //return val>>i*8 ; // might work on other systems
  }

  void println()
  {
    for( int i = 0 ; i < 4 ; i++ )
      putc( vals[i], stdout ) ;
    puts( "" ) ;
  }
} ;

int main(int argc, const char * argv[])
{
  Multibyte( 'abcd' ).println() ;  
  Multibyte( 'x097' ).println() ;
  Multibyte( '\"\\\'\'' ).println() ;
  Multibyte( '/*|' ).println() ;
  Multibyte( 'd' ).println() ;

  return 0;
}

Diese Art von Funktion ist wirklich gut, wenn Sie Parser erstellen. Bedenken Sie:

byte* buffer = ...;
if(*(int*)buffer == 'GET ')
  invoke_get_method(buffer+4);

Dieser Code funktioniert wahrscheinlich nur mit bestimmten Endianness und kann über verschiedene Compiler hinweg brechen

997870cookie-checkWas bewirken einfache Anführungszeichen in C++, wenn sie für mehrere Zeichen verwendet werden?

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

Privacy policy