여러 문자에 사용될 때 작은 따옴표는 C ++에서 무엇을합니까?


답변:


283

다중 문자 리터럴입니다. 19528057480x74657374로 분해됩니다

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

편집하다:

C ++ 표준, §2.14.3 / 1-문자 리터럴

(...) 둘 이상의 c-char를 포함하는 일반 문자 리터럴은 다중 문자 리터럴입니다. 다중 문자 리터럴은 int 유형과 구현 정의 값을 갖습니다.


11
이것이 구현 정의라고 언급하지 않았습니다.
토마스 보니 니

2
그 정의에서 가장 재미있는 것은 sizeof(int)구현도 정의되어 있다고 가정합니다 . 따라서 스토리지 주문 구현이 정의 될뿐만 아니라 이들의 최대 길이도 정의됩니다.
bobobobo

74

아니요, 주소가 아닙니다. 소위 멀티 바이트 문자입니다.

일반적으로 4 문자의 ASCII 값이 결합되어 있습니다.

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

따라서 0x74657374는 1952805748입니다.

그러나 다른 컴파일러에서는 0x74736574가 될 수도 있습니다. C 및 C ++ 표준은 모두 멀티 바이트 문자의 값이 구현 정의되어 있다고 말합니다 . 따라서 일반적으로 사용을 권장 하지 않습니다.


이러한 멀티 바이트 문자의 길이는 4 바이트로 제한됩니까? 즉, 문자로 작성된 int를 나타 냅니까?
조르지오

2
@Giorgio : 표준은 구현이 정의되어 있으며 더 이상 세부 사항이 없다고 말합니다. 실제로 int대부분의 컴퓨터에서 4 바이트이므로 4 바이트 이상을 사용하는 것이 의미가 없다고 생각합니다. 그렇습니다. 일정한 상수를 작성하는 편리한 방법이되었지만 불행히도 다른 컴파일러가 다르게 해석하여 요즘 대부분의 코딩 스타일은 사용을 권장하지 않습니다.
chys

2
@chys : 구현 정의라는 사실은 일관성이 필요하지 않다는 것을 의미합니다. 적합한 컴파일러는 모든 다중 문자 리터럴에 값 0을 제공 할 수 있습니다 (예를 들어, 비우호적 임).
Keith Thompson

2
이 loony 기능이 표준에 존재하는 이유를 물어야합니다. 그런 드문 유스 케이스처럼 보이고 어쨌든 구현이 정의되어 있으며 필요한 경우 일반적인 비트 이동 및 / 또는 '/'로 매우 명확하게 수행 할 수 있습니다.
Boann

1
@Boann , 제 감정은 정확히 맞습니다 . 그러나 직접 비교를 ==확인해야 하므로 스위치와 기타에서 안전하게 사용할 수 있습니다.
bobobobo

18

둘 이상의 c 문자를 포함하는 일반 문자 리터럴은 다중 문자 리터럴입니다. 다중 문자 리터럴은 int 유형과 구현 정의 값을 갖습니다.

구현 정의 동작은 구현에서 문서화해야합니다. 예를 들어 gcc에서는 여기에서 찾을 수 있습니다.

컴파일러는 한 번에 한 문자 씩 여러 문자 문자 상수를 계산하여 대상 문자 당 비트 수만큼 왼쪽으로 이전 값을 이동 한 다음 새 문자의 비트 패턴에서 대상 너비로 잘립니다 캐릭터. 최종 비트 패턴에는 int 유형이 지정되므로 단일 문자의 서명 여부에 관계없이 서명됩니다.

자세한 내용 은 이 페이지 의 설명을 확인 하십시오.


10

그들은 정말로 ints입니다. 예를 들어 CoreAudioTypes.h헤더 파일 에서 Core Audio API 열거 형에 광범위하게 사용 됩니다.

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

"플랫폼 독립형"이 아니라 특정 플랫폼 으로 만들어진 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;
}

6
"동일한 플랫폼에서 평등을 확인하는 것은 결코 실패하지 않습니다." 그것은 수도. Visual Studio xyz로 업그레이드하고 혀를 물으십시오. 이 도서관은 끔찍한 결정을 내 렸습니다.
궤도에서 가벼움 경주

@LightnessRacesinOrbit "Visual Studio xyz로 업그레이드하고 혀를 문지르 십시오." Core Audio API는 OS X의 시스템 오디오 API이므로 관련이 없습니다.
Jean-Michaël Celerier

5
@ Jean-MichaëlCelerier : 벌금; OSX Clang 버전을 업그레이드하고 혀를 깨 물어보십시오.
Lightness Races Orbit

1

이런 종류의 기능은 파서를 작성할 때 정말 좋습니다. 이걸 고려하세요:

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

이 코드는 특정 엔디안에서만 작동하며 다른 컴파일러에서 작동 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.