web-dev-qa-db-ja.com

C ++では、複数の文字で単一引用符を使用するとどうなりますか?

私はこのコードに興味があります:

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

1952805748の出力を提供します。

私の質問:出力はメモリ内のアドレスか何かですか?

277
lucidreality

これは複数文字のリテラルです。 19528057480x74657374、次のように分解されます

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

編集:

C++標準、§2.14.3/ 1-文字リテラル

(...)複数のc-charを含む通常の文字リテラルは、複数文字リテラルです。複数文字リテラルには、int型と実装定義値があります。

282
K-ballo

いいえ、住所ではありません。いわゆるマルチバイト文字です。

通常、ASCII 4つの文字を組み合わせた値です。

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

0x74657374は1952805748です。

ただし、他のコンパイラでは0x74736574になることもあります。 C標準とC++標準はどちらも、マルチバイト文字の値が実装定義であると述べています。そのため、一般的にその使用は強く推奨されていません。

73
chys

複数のc-charを含む通常の文字リテラルは、複数文字リテラルです。複数文字リテラルには、int型と実装定義値があります。

実装定義の動作は、実装によって文書化する必要があります。たとえば、gccで見つけることができます here

コンパイラは、複数文字の文字定数を一度に1文字ずつ評価し、前の値をターゲット文字ごとのビット数だけ左にシフトしてから、ターゲットの幅に切り捨てられた新しい文字のビットパターンを論理和します。キャラクター。最後のビットパターンにはint型が指定されているため、単一文字が署名されているかどうかに関係なく署名されます。

詳細については このページ の説明を確認してください

17
Mouna Cheikhna

本当にintsです。これらは、Core Audio API列挙型(たとえば、CoreAudioTypes.hヘッダーファイル、

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

これは「プラットフォームに依存しない」わけではないが、移植性を重視する特定のプラットフォームであるmade forのapiを使用している場合、多くのおしゃべりがあります。同じプラットフォームで平等を確認しても失敗することはありません。これらのenum 'dの値は読みやすく、実際にはその値のアイデンティティを含んでいます。これはかなりいいです。

以下でやろうとしたことは、マルチバイト文字リテラルをラップして印刷できるようにすることです(Macではこれが機能します)。奇妙なことは、4文字すべてを使い切っていない場合、結果は以下のようになります。

#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;
}
10
bobobobo

この種の機能は、パーサーを構築するときに非常に便利です。このことを考慮:

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

このコードは、特定のエンディアンでのみ動作する可能性が高く、異なるコンパイラ間で破損する可能性があります

1
Ayende Rahien