• 2.7.1 Literal Constants
  • 2.7.2 Symbolic Constants
  • 2.7.3 매크로와 상수의 차이점
  • 2.7.4 상수를 사용하여 퇴근을 빨리 하는 방법
  • 2.7.5 const 키워드가 매개변수에 있는 경우

2.7.1 Literal Constants

 

상수는 변하지 않는 수를 의미하며 그중 하나가 리터럴 상수이다. 리터럴 상수에 대한 개념을 처음에는 받아들이기 힘들 수 있는데, 변수처럼 메모리에 이름이 지어져서 할당되는 것이 아니며, 메모리 공간을 가리키는 이름을 가지지 않은 수라 생각하면 좋을 것 같다.

 

일반적으로 우리가 변수에 값을 대입할 때 사용하는 숫자 및 문자가 리터럴 상수가 되겠다. C++ 14에서 Binary Literals도 추가가 되었다.

#include <iostream>

int main()
{
	using namespace std;

	// 숫자나 글자로 표기되는 r-value = literals
	float pi = 3.14f;

	unsigned int n = 5u;
	long n2 = 5L;

	// Decimal	: 0 1 2 3 4 5 6 7 8 9 10
	// Octal	: 0 1 2 3 4 5 6 7 10
	// Hexa		: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10

	int x = 0xF;
	cout << x << endl;
	x = 012;
	cout << x << endl;
	x = 0b1010;
	cout << x << endl;
	x = 0b1011'1111'1010; // 컴파일러는 '를 무시한다. 10진수에도 사용가능하다.
	cout << x << endl;

	return 0;
}

위의 코드에서는 대입 연산자(=) 오른쪽에 있는 것들이 모두 리터럴 상수이다. 바이너리 리터럴 상수를 보면 숫자들 사이에 문자가 들어간 것을 볼 수가 있는데 바이너리 리티럴 상수를 4bit 단위로 끊어서 볼 수 있도록 생겨난 표기법이다. 컴파일러는 '를 무시하므로 써도되고 안 써도 된다. 십진수에서도 사용할 수 있다.

 

숫자 앞에 여러 표현을 활용하면 프로그래밍에서 자주 쓰이는 진수 표현을 쓸 수 있다.

0x : 16진수
0  :  8진수
0b : 2진수

2.7.2 Symbolic Constants

 

심볼릭 상수란 const 키워드와 constexpr 키워드를 통해서 명시적으로 데이터를 상수화시키는 것이다. 심볼릭 상수를 만들면 추후에 해당 상수의 값을 변경하려 할 때 컴파일러가 막아준다. 즉, 우리가 실수할 수도 있는 부분을 컴파일러가 서포트해주는 것이다. constexpr은 C++ 11에서 생긴 것으로 완벽하게 컴파일타임에서 상수로 결정 난다는 것을 키워드로 표현한다.

#include <iostream>

using namespace std;

int main()
{
	const double gravity = 9.8;
	//double const gravity = 9.8; // 이처럼 선언해도 가능하다.

	int number;
	cin >> number;
	const int special_number(number); // 사용자가 입력하는 심볼릭 상수

	constexpr int price_per_item = 123;
    
    return 0;
}

컴파일타임에서 상수임이 결정 나는 것을 컴파일타임 상수라고 칭하며, 런타임에서 결정 나는 경우 런타임 상수라고 말한다. 런타임 상수의 경우 사용자가 입력하는 심볼릭 상수가 된다. 심볼릭 상수는 상수이기 때문에 선언과 동시에 초기화를 해야 한다.


2.7.3 매크로와 상수의 차이점

 

C언어를 먼저 배우는 사람의 경우 매크로를 상수처럼 취급하여 쓰는 경우가 많다. 매크로를 활용하면 컴파일 단계에서 매크로로 만든 리터럴 상수를 치환하여 입력해주기 때문에 편하다. 하지만 매크로를 C++에서는 잘 안 쓰게 되는데 그 이유는 바로 적용 범위가 너무 넓기 때문이다. 매크로가 존재하는 파일을 include하는 경우 그 파일에도 해당 매크로가 적용되기 때문에 객체 지향 언어로 넘어간 C++에서 보는 매크로가 전역 변수처럼 작동하는 게 좋지 않다고 보는 것이다.

#include <iostream>
#define PRICE_PER_ITEM 30 // c에서 많이 쓰지 c++에서는 잘 안쓴다. why? 적용범위가 너무 넓다.

using namespace std;

int main()
{
	constexpr int price_per_item = 123; // 매크로보다 const가 더 좋다.

	return 0;
}

2.7.4 상수를 사용하여 퇴근을 빨리 하는 방법

 

과학 계산을 수행하는 곳에서 업무를 수행하다 보면 많은 상수를 사용하게 되는데, 이를 한 곳에서 모아서 심볼릭 상수로 잡아두면 관리가 편해진다.

 

상수를 모아둔 헤더 파일

 

위처럼 상수를 한 곳에 모아서 두고 상수를 써야 하는 곳에서 include를 해준다.

#include <iostream>
#include "MY_CONSTANTS.h"

using namespace std;

int main()
{
	double radius;
	cin >> radius;
	double circumference = 2.0 * radius * constants::pi;

	return 0;
}

헤더에서 사용한 namespace와 함께 파이를 사용한 코드이다.


2.7.5 const 키워드가 매개변수에 있는 경우

 

함수가 선언된 코드들을 보면 간혹 매개변수에 const 키워드가 붙어 있는 경우를 볼 수가 있다. 매개변수에 const 키워드가 붙어 있는 이유는 해당 함수에서 인자로 들어온 매개변수를 함수 내에서 변경하면 안 된다는 제약 조건을 컴파일 수준에서 정하기 위함이다.

#include <iostream>

using namespace std;

void printNumber(const int my_number)
{
	cout << my_number << endl;
}

int main()
{
	printNumber(123);

	return 0;
}

이처럼 코드를 작성하면 printNumber 함수 안에서 my_number를 수정하게 될 때 컴파일 에러가 뜨게 된다.

+ Recent posts