4 분 소요

  • 문자열 상수를 많이 만들면, 프로그램 용량이 커진다. 비슷한 문장을 쓸데없이 여러개 작성하지 마라.

모던 C++

개요

리터럴은 각 타입에 따른 상수값입니다. 컴파일 타임에 값이 결정되며, 대부분 코드 세그면트에 저장되어 그 값을 수정할 수 없습니다. 문자열 상수데이터 세그먼트rodata에 저장됩니다.

bool 과 숫자

true, false와 8진수/10진수/16진수 정수, unsigned, long, 고정 소수점 실수와 부동 소수점 실수가 제공됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// bool 형
bool a = true; // 참
bool b = false; // 거짓

// 정수형
int c = 10; // 10진수.
int d = 010; // 8진수.
int e = 0x1a; // 16진수. x 또는 X. a~f 또는 A~F
unsigned int f = 10U; // unsigned. u 또는 U
unsigned long g = 10U;
long h = 10L; // long. l 또는 L
unsigned long i = 10UL; // unsigned long. u 또는 U, l 또는 L

// 실수형
double j = 3.14; // 고정 소수점
double k = 3.14e10; // 부동 소수점 e 또는 E
float l = 3.14F; // f 또는 F
float m = 3.14e10F; 
long double n = 3.14L; // l 또는 L
long double o = 3.14e10L;

(C++11 ~) long long용 정수형 상수인 ll, ull, LL, ULL 리터럴이 추가되었습니다.
(C++14~) 이진 리터럴이 추가되어 0b, 0B 접두어로 이진수 상수를 표현할 수 있습니다.
(C++14~) 숫자 구분자가 추가되어 1'000'000와 같이 작은 따옴표(')를 숫자 사이에 선택적으로 넣을 수 있으며, 가독성이 좋아졌습니다.
(C++17~) 16진수 부동 소수점 리터럴이 추가되어 0xA.9p11과 같이 16진수로 실수를 표현할 수 있습니다.

문자 상수

문자 상수는 1byte 크기인 ''wchar_t 크기(Windows 에서는 2byte이고 리눅스에서는 4byte. 기본 타입 참고) 인L''이 있습니다.

1
2
char a = 'A';
wchar_t b = L'A'; // 와이드 문자 2byte 또는 4byte

문자열 상수

문자열 상수문자 상수들의 집합으로서, 문자열의 끝을 나타내는 널문자(정수 0인 문자, '\0')가 추가되어 있으며, 데이터 세그먼트rodata에서 프로그램 수명만큼 존재합니다.

프로그램 용량이 커질 수도 있으니, 비슷한 문장을 쓸데없이 여러개 작성하지 마세요.(동일한 것을 여러번 사용하는 경우 컴파일러가 1개로 취합해 주긴 합니다만(데이터 세그먼트 참고), 코드 중복이니 1개만 정의해서 사용하세요.)

문자열이 커봐야 얼마나 크겠어? 하실 수도 있지만, 다국어로 번역되다 보면 무시 못할 크기로 커집니다.

const char*const wchar_t*문자열 상수가 있는 영역을 참조하거나, 배열을 이용하여 복사할 수 있습니다.

(C++11~) u8””, u””, U””, u’‘(문자), U’‘(문자) 리터럴이 추가되어 유니코드를 지원하는 char16_t, char32_t 타입용 문자 상수를 제공합니다.
(C++14~) 표준 사용자 정의 리터럴이 추가되어 operator ""s, operator ""min, operator ""if, 등 문자열, 날짜 / 시간, 복소수 관련 표현이 간편해 졌습니다.
(C++17~) u8’‘(문자) 리터럴이 추가되어 유니코드를 지원하는 1byte 크기의 문자 상수를 제공합니다.

const형 포인터

수정할 필요가 없는 문자열 상수const형 포인터를 사용합니다.

1
2
const char* str1 = "abc"; // 문자열 상수
const wchar_t* str2 = L"abc"; // 와이드 문자열 상수

배열

배열 초기화에서 언급했듯, 배열문자열 상수로 초기화 하면, 끝에 널문자(정수 0인 문자, '\0')가 추가됩니다.

1
2
3
4
5
6
7
8
9
10
11
char str3[] = "abc"; // {'a', `b`, 'c', '\0'};
EXPECT_TRUE(str3[0] == 'a');
EXPECT_TRUE(str3[1] == 'b');
EXPECT_TRUE(str3[2] == 'c');
EXPECT_TRUE(str3[3] == '\0'); // 널문자가 추가됨

wchar_t str4[] = L"abc"; // {L'a', L`b`, L'c', L'\0'};
EXPECT_TRUE(str4[0] == L'a');
EXPECT_TRUE(str4[1] == L'b');
EXPECT_TRUE(str4[2] == L'c');
EXPECT_TRUE(str4[3] == L'\0'); // 널문자가 추가됨

결합

문자열 상수가 너무 긴 경우에, 서로 연달아 배치하면 자동으로 이어 붙이기가 됩니다. 하기 예에서 str1, str2, str3은 모두 Hello World 문자열 상수를 가리키며, 동일한 메모리 주소를 사용합니다.(동일한 문자열을 여러번 사용하는 경우 컴파일러가 1개로 취합해 줍니다. 데이터 세그먼트 참고)

1
2
3
4
5
const char* str1 = "Hello World"; 
const char* str2 = "Hello " "World"; // (O) 두 문자열 상수 이어 붙이기
const char* str3 = "Hello " // (O) 개행된 문자열 상수 붙이기
                   "World";   
EXPECT_TRUE(str1 == str2 && str2 == str3); // (O) 동일한 문자열 상수는 컴파일러가 1개만 생성해 줍니다.   

(C++11~) R”()”리터럴이 추가되어 개행이나 이스케이프 문자를 좀더 편하게 입력할 수 있습니다

이스케이프 문자

언어 내부에서 사용하는 기호여서 문자 상수문자열 상수로 컴파일러가 파싱할 수 없거나, 개행등 키보드로 표시할 수 없는 특수 문자들은 \을 이용하여 표현할 수 있습니다.(널문자(*정수 0인 문자, '\0'*)이스케이프 문자로서 8진수 0입니다.)

항목 내용 아스키 코드(https://www.ascii-code.com/ASCII)
\' 작은 따옴표 0x27
\" 큰 따옴표 0x22
\? 물음표 0x3F
\\ 백슬래시 0x5C
\a 비프음 0x07
\b 백스페이스 0x08
\f Form Feed 0x0C
\n 라인 피드(line feed,LF) - 개행 0x0A
\r 캐리지 리턴(carriage return, CR) - 줄의 앞으로 이동 0x0d
\t 가로탭 0x09
\v 세로탭 0x0b
\nnn nnn : 3자리의 8진수  
\xn... n… : 임의 자리 16진수  
\unnnn nnnn : 2byte(16진수 4자리)의 유니코드 image
\Unnnnnnnn nnnnnnnn : 4byte(16진수 8자리)의 유니코드 image

개행 문자

line feed로 줄을 바꾸고, carriage return으로 줄의 제일 앞으로 이동하는 CR-LF(엔터키의 동작이죠.)의 경우 OS에 따라 사용하는 이스케이프 문자가 다릅니다.

항목 내용
Windows \r + \n, CR-LF를 모두 입력합니다.
\n만 입력해도 됩니다.
Linux, MAC OS X 이상 \n, LF 만 입력합니다.
MAC OS X 이전 \r, CR 만 입력합니다.

현재는 대부분이 \n으로 CR-LF를 지원하기 때문에 별 문제는 없습니다만, 혹시나 예전 OS와의 호환성이 필요하다면 \r\n을 함께 사용해야 될 수도 있습니다.

(C++11~) R”()”리터럴이 추가되어 개행이나 이스케이프 문자를 좀더 편하게 입력할 수 있습니다.

댓글남기기