일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- C언어 # 핵심 정리
- C++ 언어 # 핵심 정리
- Hacking #Baic
- shell_script
- MySQL #핵심정리
- C언어 #핵심정리
- C언어 # 부록
- C++ 언어 #핵심정리
- C++ 언어 # 핵심정리
- C언어 #부록
- Bandit
- PHP #핵심정리
- HTML #핵심정리
- Today
- Total
cCcode
C Language [핵심정리] - 2 본문
1. 자료형 크기 구하기
자료형의 크기를 Byte 단위로 구하기 위해 sizeof 연산자를 사용할 수 있습니다.
sizeof 연산자는 sizeof 표현식 - sizeof(자료형) - sizeof(표현식) 와 같은 형식으로 표현할 수 있습니다.
일단 이 코드를 보시고 %zd 서식지정자가 뭐지..? 라는 의문이 드는 분도 계실텐데, 그런 의문을 가지셨다면 정말 대단한겁니다. 일단 간단히 설명해드리자면 %zd 서식지정자는 size_t형 변수를 출력할 때 지정해주는 서식지정자입니다. size_t 자료형은 부호 없는 정수 자료형으로 (long)unsigned int 와 의미가 같다고 보시면 될거에요. 그래서 흔히들 [이론상 가장 큰 크기를 담을 수 있는 unsigned 데이터 형]으로 정의되고 있답니다.
제가 size_t의 최댓값을 구하기 위해 임의로 언더 플로우가 발생되게 코드를 작성했습니다. 그 결과를 보시면 부호 없는 정수 자료형 중 가장 큰 자료형(unsigned long long)의 최댓값인 18446744 ... 가 나온다는 것을 알 수 있습니다.
그리고 우리는 이 과정을 통해 sizeof 연산자는 size_t를 결과로 반환해준다는 사실을 알아낼 수 있죠. 이외에 C언어 표준함수에서도 크기를 의미하는 매개변수나 반환값은 size_t를 사용하고 있고, CPU 비트 수에 맞게 자료형을 제공하고 있기 때문에 앞으로 크기를 의미하는 변수를 선언할 때 unsigned int 대신 size_t로 선언해주는게 좋아요.
아,, 그리고 unsigned(부호가 없는) 즉, 양수 값만을 가지고 있다해서 크기는 달라지지 않습니다. 아마 음수 범위에서 없는 만큼 양수 범위에서 늘어나기 때문에 그런거 같아요.
2. 최솟값과 최댓값 표현하기
정수의 최솟값이나 최댓값을 표현하려면 <limits.h>파일 안에 있는 최솟값과 최댓값들을 이용해야 합니다.
<limits.h>파일에는 unsigned 키워드를 가진 자료형의 최솟값들이 없더라고요. 그래서 가독성을 위해 0을 직접적으로 출력했더니 [warning C4477: 서식 문자열 '%llu'에 'unsigned __int64(unsigned long long)' 형식의 인수가 필요하지만 variadic(가변의) 인수2의 형식이 'int'입니다]라고 뜨더라고요. 사실 무시해도 결과는 같은 값이 나오지만 경고를 고치는 습관을 들이기 위해서 명시적 형변환을 통해 경고가 뜨지 않도록 수정했습니다.
다만, C언어는 초기에 개발 된 언어라 char, short, long과 같이 표현법이 모호 했으며, 시간이 지나 16비트, 32비트, 64비트 CPU가 나오고, 운영체제가 발전하는 등 자료형의 크기가 매번 변화했습니다. 그래서 혼란을 방지하기 위해 C99 표준부터는 <stdint.h>파일이 추가되었습니다.
이처럼 <stdint.h>파일에 정의된 정수 자료형들은 자료형 이름에 비트단위로 표시가 되어 있습니다. 그리고 부호없는(unsigned) 자료형은 앞에 u(unsigned)를 사용해서 uint8_t처럼 표현합니다. 이런 자료형은 크기를 정확하게 표현해야 하는 파일 압축 및 암호화, 네트워크 프로그래밍 등에 쓰이며, 일반적인 경우라도 <stdint.h>파일을 쓰는 게 좋습니다.
더군다나 최소, 최대값들도 해당 헤더파일에 정의되어 있어 간편하게 사용할 수 있습니다.
º 부호 있는 정수(signed) 최솟값 : INT8_MIN, INT16_MIN, INT32_MIN, INT64_MIN
º 부호 있는 정수 최댓값 : INT8_MAX, INT16_MAX, INT32_MAX, INT64_MAX
º 부호 없는 정수(unsigned) 최솟값 : 0
º 부호 없는 정수 최댓값 : UINT8_MAX, UINT16_MAX, UINT32_MAX, UINT64_MAX
제가 이 코드를 만들 때 오버플로우를 이용해서 최댓값과 최솟값을 한번에 보여주려고 계획했습니다만...
int8_t, uint8_t, int16_t, uint16_t 부분에서 오버플로우가 제대로 동작 하지 않아 그 부분은 최솟값을 직접 대입했습니다.
솔직히 말하면 이론 상 오버플로우가 발생해야 하는 부분인데 왜 동작하지 않는지 모르겠네요. 혹시 아시는 분 계신다면 알려주세요.
마지막으로 덧붙이자면 <stdint.h>파일에 정의된 자료형은 실제로 기본 자료형에서 새롭게 추가된것이 아닌 운영체제 환경에 맞도록, 키워드 typedef를 이용해 새로운 이름의 자료형으로 재정의 된겁니다.
'C Language Basic' 카테고리의 다른 글
C Language [핵심정리] - 6 (0) | 2021.05.10 |
---|---|
C Language [핵심정리] - 5 (0) | 2021.05.09 |
C Language [핵심정리] - 4 (0) | 2021.05.08 |
C Language [핵심정리] - 3 (0) | 2021.05.07 |
C Language [핵심정리] - 1 (1) | 2021.05.05 |