3-3-다.정수형 상수

정수형 상수를 표기하는 방법은 아주 쉽고 상식적이다. 아라비아 숫자와 부호로 직접 그 값을 표기하면 된다. 다음이 정수형 상수의 예이다.

 

123

8906299

-86400

 

이렇게 값을 바로 표기하면 그 크기와 형태를 보고 적당한 타입으로 메모리에 저장된다. 위 예의 경우 차례대로 short, int, int의 타입을 가진다. 123은 2바이트로 표현할 수 있으므로 short형이면 충분하고 8906299는 2바이트의 범위를 넘으므로 int형이 되어야 한다. 만약 크기를 강제로 지정하고 싶으면 상수 뒤에 L(Long, 소문자로 써도 됨)을 붙이고, 부호없는 타입으로 지정하고 싶으면 U(Unsigned, 소문자로 써도 됨)을 붙인다.

예를 들어 28은 short형이지만 28L로 표기하면 4바이트의 long형 상수가 되고 123U는 부호없는 2바이트의 정수인 unsigned short가 된다. 만약 부호없는 4바이트의 상수로 표기하고 싶으면 순서나 대소문자에 상관없이 UL, LU, ul, lu 중 하나를 붙이면 된다. C/C++언어는 타입을 중요하게 생각하므로 상수에도 정확한 타입을 지정할 수 있도록 되어 있다. 정수형 상수를 별도의 표기없이 그냥 쓰면 10진수로 해석된다. 그러나 진법에 따라 다음 두가지 형식으로 상수를 표현할 수도 있다.

 

8진수 : 0으로 시작하면 8진수로 인식되며 027, 032등과 같이 표현한다. 09같은 상수는 에러로 처리되는데 9라는 숫자는 8진수에서 쓸 수 없는 숫자다.

16진수 : 0x 또는 0X로 시작하면 16진수이다. 0x12ab, 0x3f와 같이 표현한다. 16진수에서 10 이상의 값을 표현하는 A~F는 대소문자에 상관없이 아무 문자나 사용할 수 있다. 접두로 붙는 0x는 알파벳의 "오엑스"가 아니라 숫자 0과 알파벳 x이므로 "영엑스" 또는 "공엑스"로 읽는다.

 

보편적으로 10진수를 사용하지만 어셈블리와 관계있는 값이나 비트별로 의미가 다른 상수는 16진수로 표기하면 더 편리한 경우가 많다. 아쉽게도 C는 2진 상수 표기법은 제공하지 않으므로 2진수는 16진수로 바꾸어 표기해야 한다. 예를 들어 2진수 10100110은 16진수 0xa6으로 표기한다. 사실 8진 표기보다는 2진 표기법이 더 많이 사용되는데 베이직도 지원하는 2진 표기법이 C문법에 빠진 것은 데니스 리치의 실수가 아닌가 생각된다. 실제로 표준 위원회에 2진 표기법을 도입하자는 건의가 여러 차례 있었으나 익숙해지면 16진수로 암산 가능하다는 이유로 표준에서 제외됐다.

C에서 0으로 시작하는 상수는 8진수라는 것은 잘 알아 두어야 한다. 그렇지 않으면 다음과 같은 엉뚱한 실수를 할 수도 있다. HPNum에 10진수로 17을 대입하고자 했는데 전혀 문제가 없는 문장이기 때문에 컴파일러는 어떠한 에러 메시지도 출력하지 않는다.

 

int HPNum;

HPNum=017;

 

이렇게 하면 상수 017이 8진수로 해석되어 Num에 17이 대입되는 것이 아니라 15가 대입될 것이다. C 컴파일러는 017과 17을 엄연히 다른 상수로 취급하는데 0으로 시작하는 상수는 8진수라는 것을 잘 기억해 두도록 하자.

참고로 진법이란 수치값을 표기하는 다른 방법일 뿐이지 표현하는 값 자체가 다른 것은 아니다. 012나 10이나 0xa나 모두 십진수로 10(이진수로는 1010)을 나타내며 메모리에 기록될 때는 똑같은 값이다. 따라서 "10진수 값을 어떻게 16진수로 바꾸나요?" 이런 질문은 잘못된 것이다. 10진수를 16진수 형태로 출력한다거나 문자열 형태로 저장된 16진수를 10진값으로 구하는 방법을 질문하는 것은 옳지만 말이다.