3-5-라.3중 문자

3중 문자(Trigraph)란 세 개의 연속된 문자를 하나의 문자로 대체하는 표현이다. 잘 알다시피 C 언어는 미국에 의해 만들어졌고 그러다보니 자기네 나라의 문자 코드인 ASCII표에 정의되어 있는 { } [ ] 문자들을 별 생각없이 구두점으로 정의하고 있다. 그런데 유럽의 몇 개 국가들은 영어에 없는 자신의 고유한 글자(움라우트 등)를 표현하기 위해 이 문자 코드에 다른 문자를 할당해서 사용하고 있으며 그러다 보니 이런 나라의 키보드에는 ASCII표에 있는 9개의 문자들이 없을 수도 있다. 우리 나라의 경우도 \ 문자를 원화 표시인 \로 다르게 표시하고 있지 않은가?

그래서 C표준은 C에서 사용할 수 있는 문자들을 모든 나라에 공통적인 영문자, 숫자와 몇 가지 기호만으로 제한하고 있으며 나머지 문자들은 표준에 있는 문자들의 조합으로 입력할 수 있는 방법을 제공해야 할 필요가 생긴 것이다. 이런 이유로 C 표준은 3중 문자를 정의하고 있다. 물론 키보드에 이런 문자들이 있다면 굳이 3중 문자를 쓰지 않아도 된다. 3중 문자의 종류는 다음과 같다.

 

3 문자

대체 문자

3 문자

대체 문자

??=

#

??/

\

??'

^

??!

|

??(

[

??)

]

??<

{

??<

}

??-

~

 

 

 

??로 시작하는 세 개의 문자를 연속으로 사용하면 이 문자는 컴파일러가 토큰을 분석하는 과정에서 대체 문자로 바뀐다. 다음 예제는 3중 문자로 작성한 것이다. 굉장히 이상해 보이지만 잘 컴파일되며 Trigraph Test #1. num is 2를 출력한다.

 

: Trigraph

??=include <Turboc.h>

 

void main()

??<

int ar[5]=??<1,2,3,4,5??>;

     printf("Trigraph Test ??=1. num is %d\n",ar??(1??));

??>

 

{ } 괄호 대신 ??< ??>괄호를 사용할 수 있고 배열을 표기할 때도 [ ] 대신 ??( ??)를 사용할 수 있다. 다소 혼란스러워 보이기도 하고 가독성이 심하게 떨어지기는 하지만 C표준에 의해 정상적인 소스로 인정된다. 재미있는 것은 3중 문자 치환은 구문 해석(Parsing) 전에 일어나므로 문자열 상수에 있는 3중 문자까지도 치환된다는 점이다. 그래서 문자열 내에서 부작용이 발생할 수 있으며 이 부작용을 해결하기 위해 확장열에 3중 문자의 선두로 사용되는 ?를 표기할 수 있는 \?가 따로 정의되어 있는 것이다.

이 외에도 C++ 표준은 연산자나 구두점을 위한 대체 토큰인 이중 문자(Alternative token)라는 것도 정의하고 있다. 예를 들어 <%는 {로 대체되며 %>는 }로 대체되는 식인데 비주얼 C++과 Dev-C++은 2중 문자를 지원하지 않는다. 키보드에 { } 문자가 없는 나라들은 3중 문자가 필요하겠지만 우리나라 키보드에는 이 문자들이 모두 있으므로 우리가 3중 문자에 관심을 가져야 할 이유는 전혀 없는 셈이다.

 

참고

앞에서 문자형 변수에는 문자의 아스키 코드값이 저장되며 문자 상수도 아스키 코드값으로 평가된다고 설명했다. 그러나 이는 정확하게 말하면 사실이 아니다. 윈도우즈 환경에서는 사실이고 대부분의 환경에서도 이 설명이 맞다. 그러나 C 스팩에 문자 코드는 반드시 아스키 코드여야 한다고 명시되어 있지 않으며 다른 환경에서는 문자 코드 체계가 달라질 수도 있다. EBCDIC을 쓰는 환경, 유니코드를 쓰는 환경도 있으므로 'A'의 문자 코드가 항상 65라고 할 수 없다.

이 책은 정확한 설명보다는 이해를 쉽게 하는 쪽으로 작성되어 있다. 정확한 것도 좋지만 처음부터 너무 상세하게 모든 예외적인 문법까지 다 설명하려면 정의가 길고 복잡해진다. 또한 여러분들도 이 문법들을 한꺼번에 정확하게 공부하려고 하면 무척 피곤해진다. 그래서 처음에 다소 부정확한 면이 있더라도 직관적으로 이해하기 쉬운 쪽으로 설명을 전개하기로 한다. 문법의 상세한 면과 예외적인 사항에 대해서는 기본을 익힌 후에 스팩 문서를 보면서 연구해도 늦지 않다.