wellcome_공부일기

C++ | 02.09 리터럴 상수(Literal constants)와 진수들 본문

프로그래밍/C++

C++ | 02.09 리터럴 상수(Literal constants)와 진수들

ma_heroine 2020. 5. 10. 23:57

<목차>

1. 상수(constants)란?

2. 리터럴 상수(Literal constants)

3. 8진수와 16진수 사용하기

4. 이진수 사용하기

5. 10진수와 8진수, 16진수, 이진수 출력하기 

 

상수(constants)란?

프로그래밍에서 상수(constants)란 변하지 않는 고정된 값을 말합니다.

C++은 literal constants와  symbolic constants, 두가지 종류의 상수를 가지고 있습니다.

이번에는  literal constants에 대해 공부했으므로, 이에 대해 포스팅하겠습니다.  ٩(ˊᗜˋ*)و 

(learncpp의 literals에 대해 공부한 내용입니다!)

 

리터럴 상수(Literal constants)는 보통 literals이라고 불리며, 코드에 직접적으로 삽입된 값을 말합니다. 

return 5; // 5 is an integer literal
bool myNameIsAlex { true }; // true is a boolean literal
std::cout << 3.4; // 3.4 is a double literal

위 예들은 모두 동적으로 변할 수 없는 값들이기 때문에 상수(constants)입니다. 

만약 값을 바꿔야 한다면 바꾼 값에 대한 변경사항을 위해 다시 컴파일해야 합니다. -> 수동

 

객체가 타입(type)을 가지는 것처럼, 모든 literals는 타입을 가집니다.

literal이 가지는 값과 형식에 따라 literal의 타입을 추정할 수 있습니다. 

 

아래는 기본적인 literal type입니다. 

 

https://www.learncpp.com/cpp-tutorial/literals/

 

Literal suffixes

만약 리터럴의 기본 타입이 원하던 것이 아니라면, 리터럴에 접미사(suffix)를 추가하여 타입을 바꿀 수 있습니다.

 

https://www.learncpp.com/cpp-tutorial/literals/

 

물론 integer type을 사용하기 위해서 접미사구를 사용할 필요는 없지만, 때로 자세한 integer type을 표현하기 위해 사용할 수 있습니다.

하지만 변수의 값 뒤보다는 앞에 명확하게 타입을 지정하는 것이 가독성에 더 좋습니다. 

unsigned int value1 { 5u }; // 5 has type unsigned int
long value2 { 6L }; // 6 has type long

// better to put the type before the value for readability
int i =-123424u;
int j = (unsigned int) -123424; 

 

기본적으로 부동소수점 리터럴 상수(floating point literal constants)은 double 타입을 가집니다.

해당 상수를 float로 만들기 위해서는 f (or F)접미사를 사용하면 됩니다. 

float f { 5.0f }; // 5.0 has type float

주의사항

float f { 4.1 }; // warning: 4.1 is a double suffix, not a float suffix

4.1은 suffix가 없기 때문에, 이는 float literal이 아닌 double literal로 간주됩니다. 

C++이 리터럴의 타입을 정의할 때, float 변수를 초기화할 때 리터럴을 사용하든, 리터럴로 무엇을 하든 상관하지 않습니다. 

그러므로, 4.1이 변수 f 에 대입되고 정밀도의 손실 결과를 가져오기 전에 double에서 float로 변환시켜줘야 합니다.  

 

String literals

std::cout << "Hello, world!"; // "Hello, world!" is a C-style string literal
std::cout << "Hello," " world!"; // C++ will concatenate sequential string literals

C++도 string literals을 지원하고 있습니다.

하지만 C에서와 달리 C++에서는 변수에 string을 선언하거나 함수로 string을 전달하는 것은 작동하지 않습니다.

 

Scientific notation for floating point literals

부동소수점 리터럴(Scientific notation for floating point literals)을 선언하는 두가지 방법이 있습니다.

첫번째는 아래와 같습니다.

double pi { 3.14159 }; // 3.14159 is a double literal in standard notation
double avogadro { 6.02e23 }; // 6.02 x 10^23 is a double literal in scientific notation

두번째 형식은, exponent 뒤의 숫자가 음수인 경우입니다. 

double electron { 1.6e-19 }; // charge on an electron is 1.6 x 10^-19

 

8진수와 16진수 사용하기

우리는 일상생활에서도 그리고 프로그래밍에서도, 10진수 숫자(decimal number)를 많이 이용합니다. 

여기서 각 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9가 될 수 있습니다.

10진수(decimal)은 "base 10"이라고도 불리는데, 0부터 9까지 10개의 자릿수가 가능하기 때문입니다.

이진수가 0과 1이라는 2개의 자릿수를 가져서 base 2라고도 말하는 것과 같은 원리입니다. (0, 1, 10, 11, ...)

C++ 프로그램에서도 숫자는 모두 10진수로 가정합니다.

int x { 12 }; // 12 is assumed to be a decimal number

 

아래는 차례대로 10진수, 8진수, 16진수를 나타내는 표입니다. 

8진수 사용하기

8진수는 0부터 7까지 사용가능한 자릿수가 있기 때문에 base 8이라고 합니다. 

그래서 8진수를 셀 때는 7에서 끊고 8과 9를 넘어간 다음에 10부터 숫자를 셉니다.

#include <iostream>
 
int main()
{
    int x{ 012 }; // 0 before the number means this is octal
    std::cout << x;
    return 0;
}

- 숫자 앞에 0을 넣어주면 8진수를 숫자임을 나타냅니다.

- 컴퓨터가 10진수로 숫자를 출력하기 때문에 8진수 12는 10진수 10이 됩니다. 

- 8진수는 거의 사용하지 않고 보통 피하는 것을 권장합니다. 

16진수 사용하기

16진수는 base 16으로 , 알파벳 대문자가 포함됩니다.

16진수의 10은 10진수의 16과 대응됩니다. 

#include <iostream>
 
 int main()
{
    int x{ 0xF }; // 0x before the number means this is hexadecimal
    std::cout << x;
    return 0;
}

- 출력값은 15가 나옵니다.

- 16진수 자리에는 16개의 다른 값들이 있기 때문에 하나의 16진수 자리에 4비트가 포함되어 있다고 말할 수 있습니다.

- 결과적으로 16진수 자리의 한 쌍을 이용하여 전체 바이트를 정확하게 나타낼 수 있습니다. 

16진수를 어디에서 사용할까?

값이 0011 1010 01111 10011 1000 0010 0110의 32비트 정수(integer)가 있다고 가정해봅시다.

숫자의 길이와 중복때문에, 읽기가 쉽지 않습니다. 16진수를 이용하면 위 값을  3A7F 9826 으로 표현할 수 있습니다.

이러한 특징은 16진수가 메모리 내의 값을 나타낼 때  간결한 방법으로 나타내는데 유용하게 쓰이게 됩니다.

그래서 16진수 값은 메모리 주소나 메모리 내의 원시적 값(raw value)를 나타내는데 많이 사용됩니다. 

 

C++14 이전에는 이진수 리터럴을 대입(assignment)할 방법이 없었는데, 16진수 쌍은 이러한 문제에 대한 해결방안을 제시할 수 있었습니다. 아래는 16진수로 이진수를 표현한 코드입니다.

(https://www.learncpp.com/cpp-tutorial/literals/)

#include <iostream>
 
int main()
{
    int bin{};
    bin = 0x01; // assign binary 0000 0001 to the variable
    bin = 0x02; // assign binary 0000 0010 to the variable
    bin = 0x04; // assign binary 0000 0100 to the variable
    bin = 0x08; // assign binary 0000 1000 to the variable
    bin = 0x10; // assign binary 0001 0000 to the variable
    bin = 0x20; // assign binary 0010 0000 to the variable
    bin = 0x40; // assign binary 0100 0000 to the variable
    bin = 0x80; // assign binary 1000 0000 to the variable
    bin = 0xFF; // assign binary 1111 1111 to the variable
    bin = 0xB3; // assign binary 1011 0011 to the variable
    bin = 0xF770; // assign binary 1111 0111 0111 0000 to the variable
 
    return 0;
}

 

 

이진수 사용하기

C++14에서는 이진수 리터럴(binary literals)을 ' 0b ' 접두사를 사용하여 할당할 수 있습니다. 

#include <iostream>
 
int main()
{
    int bin{};
    bin = 0b1;  // assign binary 0000 0001 to the variable
    bin = 0b11; // assign binary 0000 0011 to the variable
    bin = 0b1010; // assign binary 0000 1010 to the variable
    bin = 0b11110000; // assign binary 1111 0000 to the variable
 
    return 0;
}

긴 리터럴은 읽기 힘들어서, C++14는 따옴포(')를 숫자 구분으로 사용할 수 있는 기능을 추가하였습니다.

10진수에도 사용가능하며, 컴파일러가 위와 같은 상황에선 '을 무시합니다. 

#include <iostream>
 
int main()
{
    int bin{ 0b1011'0010 };  // assign binary 1011 0010 to the variable
    long value{ 2'132'673'462 }; // much easier to read than 2132673462
 
    return 0;
}

 

10진수와 8진수, 16진수, 이진수 출력하기 

#include <iostream>
 
int main()
{
    int x { 12 };
    std::cout << x << '\n'; // decimal (by default)
    std::cout << std::hex << x << '\n'; // hexadecimal
    std::cout << x << '\n'; // now hexadecimal
    std::cout << std::oct << x << '\n'; // octal
    std::cout << std::dec << x << '\n'; // return to decimal
    std::cout << x << '\n'; // decimal
 
    return 0;
}

- std::dec or std::oct or std::hex를 이용하면 10진수, 8진수, 16진수를 출력할 수 있습니다. 

 

이진수 출력하기 

std::cout에는이진수를 출력하는 내장된 기능이 없어, 다른 라이브러리를 사용해야 합니다.

C++의 표준 라이브러리의 std::bitset를 이용하면 되는데, #include <bitset>을 선언해주어야 합니다.

그 후, std:::bitset 변수를 정의하고 std:::bitset에 저장할 비트 수를 정의해야 합니다.

비트 수는 컴파일러의 기준에서 상수가 되어야 합니다.

std::bitset는 10진수, 8진수, 16진수 또는 2진수를 포함한 어떤 형식으로든 초기화할 수 있습니다. 

#include <iostream>
#include <bitset> // for std::bitset
 
int main()
{
	// std::bitset<8> means we want to store 8 bits
	std::bitset<8> bin1{ 0b1100'0101 }; // binary literal for binary 1100 0101
	std::bitset<8> bin2{ 0xC5 }; // hexadecimal literal for binary 1100 0101
 
	std::cout << bin1 << ' ' << bin2 << '\n';
	std::cout << std::bitset<4>{ 0b1010 } << '\n'; // we can also print from std::bitset directly
 
	return 0;
}

- 출력값은 차례대로, 11000101 11000101와 1010이 나옵니다.

 

 

 

 

 

 

 

 

 

* 해당 글은 홍정모님의 따라 배우는 C++과 learncpp에서 공부한 토대로 작성되었습니다.

Comments