박가방
[C++] 리터럴 상수 (Literal Constant) 본문
개인 공부 중입니다. 조언 환영합니다.
1.서론
- 상수(constant)란 직접 코드에 삽입된 값.
- 상수는 변수와 달리 프로그램이 실행되는 동안 메모리에 저장된 데이터를 변경할 수 없다.
변수) 하나의 특정 값을 저장할 수 있는 메모리 공간 (특정 값이란 숫자, 문자,논리, 배열 등 하나의 데이터이다.)
int x = 25;
- 변수 x라는 값에 상수 25를 대입한다
- 25 라는 값에 30을 대입(25=30)할 수 없다. -> 상수
표 1.1 상수의 종류
숫자 상수 | 정수 상수 | -65536, -50, 0 ,10 등 |
실수 상수 | 3.141592, 15.6, 44.56 등 | |
문자 상수 | 문자 상수 | 'a'~'z', '!', '@' 등 |
문자열 상수 | 'Korea', 'Hello', '대한민국' 등 | |
논리 상수 | 참 | true 또는 0이 아닌 수 |
거짓 | false 또는 0 |
2. 표현방식에 따른 상수
C++에는 두 가지 상수가 존재한다.
- 리터럴 상수 (literal constant)
- 심볼릭 상수 (symbolic constant)
3. 리터럴 상수(literal constant)
- 리터럴 상수는 변수와 같이 자료형 타입(실수, 정수, 문자)을 갖는다.
- 그러나 변수와 달리 저장된 메모리 공간을 가리키는 이름을 가지지 않는다.
3.1 논리형(bool) 정수형(integer) 실수형(float) 리터럴
#include <iostream>
int main() {
using namespace std;
/*부울 리터럴*/
bool Weather = true; // Weather는 bool literal true가 할당.
/*정수 리터럴*/
int x = 1; // 정수 변수 'x'는 literal 5가 할당.
cout << 1 * 2 << endl; // 1와 2는 정수 리터럴
/*실수 리터럴*/
float pi = 3.141592f; // 3.14159s flaot literal
float le_pi = 0.628e1; // 0.628*10^1
float lee_pi = 628e-2; // 628*10^-2
cout << pi<<endl;
cout << le_pi << endl;
cout << lee_pi << endl;
}
- 숫자 리터럴의 경우 유형을 결정하는 접미사가 포함된다.
- 이를 생략할 경우 컴파일러는 의도하는 것이 어떤 종류의 상수인지 유추한다. (정수형의 경우 int, 실수형의 경우 float)
- 접미사를 통해 해당 상수의 타입을 명시할 수 있다.
표3.1. 접미사를 통해 나타낼 수 있는 정수형 및 실수형 타입
접미사(suffix) | 타입(type) | |
정수형 기본 설정 | int | |
u or U | usigned int | |
l or L | (singed) long | |
ul, uL, Ul, UL, lu, lU, Lu, or LU | unsigned long | |
ll or LL | (signed) long long | |
ull, uLL, Ull, ULL, llu, llU, LLu, or LLU | unsigned long long | |
실수형 기본 설정 | double | |
f or F | float | |
l or L | long double |
# 그러나 접미사를 사용하여 명시하는 것 보다 캐스팅 사용하는 것이 읽기 편하다.
float pi = 3.14f; //3.14가 캐스팅 되어 pi에 대입
long n2=5l;
double d= 6.0e10;
//명시해주기위한 용도로 사용되나, 차라리 캐스팅을 사용하는 것이 나음
/*Casting*/
int i = (unsinged int)1234; // 이럴 경우 프로그래머가 읽기 편함
3.2 10진수(decimal) 8진수(octal) 16진수(hexadecimal) 리터럴
3.2.1 각 진수 표현으로 나타낸 결과
3.2.2 cout 객체에 dec,hex,oct 조정자를 전달한 결과.
#include <iostream>
int main() {
using namespace std;
int a = 12;
int oct_a = 012; //8진수는 숫자앞에 0, 1*(8^1) + 2 = 10
int bin_a = 0b00010010; //2진수는 숫자앞에 0b 1*(2^4) + 1*(2^1) = 18
int hex_a = 0x12; //16진수는 숫자앞에 0x, 1*(16^1) + 2 = 18
/*3.2.1 각 진수 표현으로 나타낸 결과*/
cout << "12 : " << a << endl;
cout << "012 : " << oct_a << endl;
cout << "0b00010010 : " << bin_a << endl;
cout << "0x12 : " << hex_a << endl;
/*3.2.2 cout 객체에 dec,hex,oct 조정자를 전달한 결과.*/
cout <<"숫자 12를 10진수로 " << a << endl;
cout << oct;
cout << "숫자 12를 8진수로 " << a << endl;
cout << hex;
cout << "숫자 12를 16진수로 " << a << endl;
}
결과 12 : 12 012 : 10 0b00010010 : 18 0x12 : 18 숫자 12를 10진수로 12 숫자 12를 8진수로 14 숫자 12를 16진수로 c |
표 3.2. 각 진법의 출력 형태
10진법 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
8진법 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 |
16진법 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B |
- 실수로 0을 붙였다가 8진수가 되는 케이스가 있으므로 주의하자
- 16진수를 프로그래머들이 많이 사용하는 이유는 0011 1010 1111 ... 처럼 이진수가 반복되면 읽기 힘든데
3A7F로 바꾸면 읽기가 훨씬 편하다
4 심볼릭 상수(Symbolic constant) [Reference 2번]
- 심볼릭 상수는 변수와 같이 문자로된 이름을 가지는 상수이다.
- 심볼릭 상수는 반드시 선언과 동시에 초기화를 해야한다
- 심볼릭 상수는 매크로(define)와 const 키워드를 사용하여 선언 가능하나,
매크로는 C언어의 문법으로, C++에서는 가급적 const 키워드를 사용하여 선언한다.
/*const 상수*/
const int Age = 10;
/*define 상수*/
#define MAX_STUDENT 30
- define은 상수를 만드는게 아니라 문자열을 치환하는 전처리기이다. 단지 MAX_STUDENT를 30으로 치환하는 개념.
4.1 매크로를 이용한 선언보다 const 키워드를 사용한 심볼릭 함수의 장점으로는
- 매크로는 직접 가서 봐야하기 때문에 디버깅이 힘들다. (쉽게배우는 C언어 강의 중, 무슨말인지 모르겠음.)
- define은 cpp file에서 전처리기 역할로 인해 위치가 main 바깥에 있어, 영향을 끼치는 범위가 넓어 좋지 않다.
- 상수의 타입을 명시적으로 지정할 수 있다.
- 구조체와 같은 복잡한 사용자 정의 타입에도 사용할 수 있다.
- 해당 심볼릭 상수를 특정 함수나 파일에서나 사용할 수 있도록 제한이 가능하다.(함수나, 파일 내에서만 사용가능)
TMI
- 매크로는 대문자로 많이 사용한다
- const는 물리함수에서 ceff_, k_로 사용하기도 한다.
- 만약 const price_per_item이 변수가 되려면 const만 풀어놓으면 되므로 관리하기 편하다.
4.2 심볼릭 상수의 사용법
4.2.1 변수 선언 시
const double gravity{ 9.8 };
// const -> 내 코드 바꾸지마
// const는 반드시 선언과 동시에 initial 해줘야함.
gravity =1.2; //오류뜸. 절대 이런 방식으로 변경하지 말 것.
//어떠한 경우에도 변해야하는 게임을 만들어야한다면 주석을 달거나 다른 기법을 사용.
// 참고 : double const gravity {9.8} 도 가능하지만, 일반적으로 const는 앞에 붙임
4.2.2 함수 사용 시
void printNumber(const int my_number) //const로 파라미터를 변경하지 않도록 막음.
{
cout << my_number << endl;
}
int main()
{
printNumber(123);
}
- 함수의 작동 형태는 123이란 argument가 printNubmer 함수로 전달되는 과정에서
함수의 영역( 중괄호{} )안에서 int my_number라는 것이 선언되고 123이 들어가는 형태.
- 따라서 my_number라는 파라미터는 printNumber의 입력이다.
이를 내부에서 파라미터를 변경하는 것은 코드 설계상 매우 좋지 않으므로 const로 막아버린다.
4.3 의미적인 차이
const int my_const(123); //의미적으로는 컴파일 타임 상수
//컴파일 시 반드시 지정되는 값.
int number;
cin >> number;
const int special_number(number); //변수로 상수를 초기화, 의미적으로 런타임 상수
//런타임 시 지정되는 값.
// 이두개를 잘 분리해서 해석하기위해 cpp11버전부터
constexpr int my_const1(123); // constexpression -> 컴파일 타임 상수.
- 의미적으로 컴파일 시 지정되는 데이터가 있고, 런타임 시 지정되는 데이터가 있다. 이 둘을 분리하기 위해 C++11버전부터는 Constexpr를 통해 분리한다.
4.4 symbolic 상수의 헤더파일 선언
/*CONSTANT.h file*/
#pragma once
namespace constants
{
constexpr double pi(3.141592);
constexpr double avogardo(6.0221413e23);
constexpr double moon_gravity(9.8 / 6.0);
//...
}
/*main.cpp*/
#include <iostream>
#include "CONSTANT.h"
using namespace std;
int main(){
double radius;
cin >> radius;
double circumference = 2.0 * radius * constants::pi;
}
- 위와 같이 CONSTANT를 따로 지정하여 관리할 경우 용이하다.
5. 바이너리코드의 single quote 사용시 장점
- 컴파일러가 single quote를 무시하므로 가시적으로 좋다.
int x= 0b1010'1111'1000; // '붙으면 컴파일러가 무시하므로. 프로그래머 입장에서 읽기 편함.
cout <<x<< endl; // 10진수도 (', single quote)를 쓸 수 있음.
6.매직넘버(Magic Numbers)
# 나쁜 예
/*나쁜 예*/
int num_items=1;
int price = num_items * 10; // 10 is ~~something
위 코드에서 10 숫자를 매직넘버라고 부른다.
이는 콘텍스트(context,주석 2)가 없는, 코드 중간에서 하드코딩된 리터럴을 말한다.
- 주석이 없는 경우 추론하기 매우 어렵다.
- 주석이 있는 경우에도 반복 사용될 경우, 수정해야할 경우(price가격에 곱한 상수 10이 -> 30으로 변경될 시) 문제를 해결하기 어렵다.
# 좋은 예
/*좋은 예*/
const int price_per_item = 10;
int price2 = num_items * price_per_item;
- 귀찮더라도 특정 상수를 변수에 대입하여 코딩하자.
2 ) 정보통신 용어로서의 컨텍스트는 호출, 응답 간의 환경 정보라고 정의할 수 있을 것 같다. 즉, 누가 무엇을 어떤 의도를 가지고 언제 행위를 하였는지에 대한 정보를 통칭하여 컨텍스트라고 하는 듯 하다. [Reference 6]
Reference
1: https://boycoding.tistory.com/155
2: http://www.tcpschool.com/cpp/cpp_datatype_constant
3: https://digiconfactory.tistory.com/entry/C-%EC%83%81%EC%88%98-%EB%A6%AC%ED%84%B0%EB%9F%B4-%EC%83%81%EC%88%98%EC%99%80-%EC%8B%AC%EB%B3%BC%EB%A6%AD-%EC%83%81%EC%88%98
4: https://opentutorials.org/module/3921/23508
5. 따라 배우는 C++ - 홍정모
6. https://m.blog.naver.com/ljhsecret/60155604088
'프로그램 언어 > C++' 카테고리의 다른 글
[C++] Expression(표현식)과 Statement(명령문) 차이 (0) | 2022.08.07 |
---|---|
[C++] 함수 (0) | 2022.08.07 |