2025. 2. 15. 19:44ㆍ카테고리 없음
1. C++에서 변수의 선언과 초기화
각 언어마다 변수의 선언 방법과 초기화에 다른점이 있기에 이 부분에 대해서는 한번 살펴보고 가자.
C++에서는 변수의 선언과 초기화를 각각 진행할 수 있다.
그리고 선언과 동시에 초기화를 하는 것 또한 가능하다
또한 한번에 여러개의 변수를 선언할 수 도 있고
동일하게 한번에 선언하면서 초기화도 가능하다.
추가 Cstyle의 초기화가 있는데 C style 초기화는 아래와 같이 사용하면 된다.
2. 정수형 데이터
2-1. 정수형 변수에 실수 데이터 삽입의 결과
C++에서 정수형 데이터의 경우는 실수형 데이터를 삽입할 경우 소수점은 모두 버린 채로 들어가게 된다.
물론 연산을 해서 나온 결과 또한 동일하다.
이렇게 1을 곱셈/나눗셈을 했을 경우 출력되는 결과는
셈을 한 정수 부분만 들어가게 된다.
그리고 출력에서 보면
double형에서 int형으로 자동으로 변환되면서 데이터가 손실될 수 도 있다고 한다.
이는 넣어주는 값은 double형인데 이걸 int형으로 넣으면서 소수점 값들이 사라지면서 손상된 상태임을 알 수 있다.
2-2. 다양한 진법의 데이터
숫자에는 진법이란게 존재한다.
우리가 사용하는 기본적인 숫자는 10진법 숫자로 0부터 9까지의 숫자를 가지고 이를 통해서 값을 표현한다
10진법 외에 2진법, 8진법 ,16진법이라는 진법이 있으며 이는 각각 0과 1까지의 2개의 숫자를 사용하는 2진법, 0부터 7까지의 8개의 숫자를 사용하는 8진법, 0부터 9까지의 숫자와 알파벳 A~F까지의 16개의 문자를 사용하는 16진법이 존재한다
그리고 프로그램의 언어에서는 이 숫자들이 변수에 초기화 시킬때 컴퓨터가 이 값이 무슨 진법을 사용한 데이터인지를 알려줘야만 한다.
그렇기에 숫자 앞에 특수한 단어를 추가해서 사용하고 그 방법은 아래와 같다
이렇게 변수에 넣어주는 저 값을 리터럴 이라고 부르고(정확하게는 프로그래밍에선 변수가 아닌 코드에 직접 적힌 고정된 값을 리터럴이라고 함), 위에서 사용한 저런 숫자를 사용한 리터럴을 숫자 리터럴이라고 한다.
그래서 각각 10진수 정수 리터럴, 2진수 정수 리터럴, 8진수 정수 리터럴, 16진수 정수 리터럴 이라고 부를 수 있다.
3. 정수형 데이터의 타입
정수형 데이터 타입은 크게 short, int , long 이 있다.
구체적인 타입에 대한 설명은 아래 표와 같다.
데이터 타입 | 크기(바이트) | 비트수 | 값의 범위 |
short( signed char ) | 2 | 16 | -32,768 ~ 32,767/ 0 ~ 65,535 |
unsigned short | 2 | 16 | 0 ~ 65,535 |
int( signed int ) | 4 | 32 | -2,147,483,648 ~ 2,147,483,647 / 0 ~ 4,294,967,295 |
unsigned int | 4 | 32 | 0 ~ 4,294,967,295 |
long( signed long ) | 4 (Windows) / 8 (Linux) | 32 or 64 | 플랫폼에 따라 다름 |
unsigned long | 4 or 8 | 32 or 64 | 플랫폼에 따라 다름 |
long long( signed long long ) | 8 | 64 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807/ 0 ~ 18,446,744,073,709,551,615 |
unsigned long long | 8 | 64 | 0 ~ 18,446,744,073,709,551,615 |
- int는 대부분 4바이트(32비트)
- long은 Windows에서는 4바이트, Linux/macOS에서는 8바이트
- long long은 항상 8바이트(64비트)
이렇게 시스템에 따라서 크기가 변경될 수 있기 때문에 운영체제나 컴파일러에 상관없이 정확한 크기의 정수형을 사용하게 하려면 <cstdint> 헤더에서 제공하는 타입을 쓰는 것이 좋다
데이터 타입 | 크기 (바이트) | 비트 수 | 설명 |
int8_t | 1 | 8 | 부호 있는 8비트 정수 |
uint8_t | 1 | 8 | 부호 없는 8비트 정수 |
int16_t | 2 | 16 | 부호 있는 16비트 정수 |
uint16_t | 2 | 16 | 부호 없는 16비트 정수 |
int32_t | 4 | 32 | 부호 있는 32비트 정수 |
uint32_t | 4 | 32 | 부호 없는 32비트 정수 |
int64_t | 8 | 64 | 부호 있는 64비트 정수 |
uint64_t | 8 | 64 | 부호 없는 64비트 정수 |
이를 사용하는 방법은
#include <iostream>
#include <cstdint> // 고정 크기 정수
int main() {
int32_t a = 100; // 32비트 정수
uint64_t b = 99999999999ULL; // 64비트 부호 없는 정수
std::cout << "a: " << a << "\n";
std::cout << "b: " << b << "\n";
return 0;
}
와 같이 사용하면 된다.
추가적으로
이렇게 unsigned int 타입의 변수에 그냥 정수 리터럴을 넣으려고 하면 내부적으로 자동적으로 형변환 하여 넣어주게 되는데 그러면 성능적으로 안좋을 수 있기 때문에 그 뒤에 u를 붙여주면
이런 unsigned 정수 리터럴이 되게 되어 바로 넣어지게 된다.
마찬가지로 long타입의 정수 경우는
그냥 숫자가 아니라 뒤에 L을 붙여서 롱타입을 명시해주면
롱타입 정수 리터럴이 되어 형변환 없이 들어가게 된다
근데 모두 거의 형변환이 자동으로 수행되고 이 속도 차이는 미미한 정도니 신경 쓸 필요 없으나 코드의 가독성과 연산과 같은 행동에 대한 안정성 때문에 붙여주는것이 좋다.
long long 타입의 경우는 LL을 붙여주고 거기서 unsigned Long Long 타입이라면 uLL을 붙여주면 된다.
4. int 타입과 2진법
아래와 같은 코드가 있다고 보자.
uint8_t num0 = 1;
이 경우는 Fixed with 인티져타입으로 8비트 크기의 unsigned int 타입임을 나타내는 변수에 1을 넣었다.
그러면 8칸의 비트를 모두 수를 표현하는데 사용하게 된다.
십진수 값 | 8비트 바이너리 표현 |
0 | 00000000 |
1 | 00000001 |
127 | 01111111 |
128 | 10000000 |
255 | 11111111 (최댓값) |
그런데 unsigned말고 그냥 int인 경우에는 음수와 양수를 구분해야하기 때문에 부호를 표현하기 위해서 8개의 비트중 맨앞의 비트를 MSB(최상위 비트, 7번째 비트)를 부호 비트로 사용된다.
이중 음수의 경우는 2의 보수법(Two’s Complement)으로 표현된다.
십진수 값 | 8비트 바이너리 표현 (2의 보수) |
0 | 00000000 |
1 | 00000001 |
127 | 01111111 (최댓값) |
-1 | 11111111 |
-2 | 11111110 |
-127 | 10000001 |
-128 | 10000000 (최솟값) |