본문 바로가기
⌨️CS-STUDY/C

[C][header][limits.h]

by 미르의 블로그 2023. 1. 23.
728x90
반응형

『목차』
0. 개요

1. 내용
2. 오버플로우ㆍ언더플로우(OverflowㆍUnderflow)
3. 출처

0. 개요

limits.h는 C언어의 표준 라이브러리로, 정수형의 범위를 나타내는 상수들을 정의한다.

1. 내용

이름 설명
CHAR_BIT char의 비트 수 8
SCHAR_MIN signed char의 최솟값 -127 -1
SCHAR_MAX signed char의 최댓값 127
UCHAR_MAX unsigned char의 최댓값 255[0xFF]
CHAR_MIN char의 최솟값 SCHAR_MIN 또는 0
CHAR_MAX char의 최댓값 SCHAR_MAX 또는 UCHAR_MAX
MB_LEN_MAX 멀티바이트 문자의 최대 바이트 수 5
SHRT_MIN short의 최솟값 -32767 -1
SHRT_MAX short의 최댓값 32767
USHRT_MAX unsigned short의 최댓값 65535[0xFFFF]
INT_MIN int의 최솟값 -2147483647 -1
INT_MAX int의 최댓값 2147483647
UINT_MAX unsigned int의 최댓값 4294967295[0xFFFFFFFF]
LONG_MIN long의 최솟값 -2147483647 -1
LONG_MAX long의 최댓값 2147483647
ULONG_MAX unsigned long의 최댓값 4294967295[0xFFFFFFFF]
LLONG_MIN long long의 최솟값 -9,223,372,036,854,775,807 - 1
LLONG_MAX long long의 최대값 9,223,372,036,854,775,807
ULLONG_MAX unsigned long long의 최대값 18,446,744,073,709,551,615

 

자료형 최솟값 최댓값
char CHAR_MIN CHAR_MAX
short SHRT_MIN SHRT_MAX
int INT_MIN INT_MAX
long LONG_MIN LONG_MAX
long long LLONG_MIN LLONG_MAX
unsigned char 0 UCHAR_MAX
unsigned short 0 USHRT_MAX
unsigned int 0 UINT_MAX
unsigned long 0 ULONG_MAX
unsigned long long 0 ULLONG_MAX

 

2. 오버플로우ㆍ언더플로우(OverflowㆍUnderflow)

다음과 같이 limits.h에 정의된 최댓값을 넘어서도 오버플로우가 발생합니다.

/* integer_max_overflow.c */
#include <stdio.h>
#include <limits.h>    // 자료형의 최댓값과 최솟값이 정의된 헤더 파일

int main()
{
    char num1 = CHAR_MAX + 1;          // char의 최댓값보다 큰 수를 할당. 오버플로우 발생
    short num2 = SHRT_MAX + 1;         // short의 최댓값보다 큰 수를 할당. 오버플로우 발생
    int num3 = INT_MAX + 1;            // int의 최댓값보다 큰 수를 할당. 오버플로우 발생
    long long num4 = LLONG_MAX + 1;    // long long의 최댓값보다 큰 수를 할당. 오버플로우 발생

    // char, short, int는 %d로 출력하고 long long은 %lld로 출력
    // 부호 있는 정수에서 저장할 수 있는 범위를 넘어서면 최솟값부터 다시 시작
    printf("%d %d %d %lld\n", num1, num2, num3, num4);
    // -128 -32768 -2147483648 -9223372036854775808

    unsigned char num5 = UCHAR_MAX + 1;          // unsigned char의 최댓값보다 큰 수를 할당
                                                 // 오버플로우 발생
  
    unsigned short num6 = USHRT_MAX + 1;         // unsigned short의 최댓값보다 큰 수를 할당
                                                 // 오버플로우 발생

    unsigned int num7 = UINT_MAX + 1;            // unsigned int의 최댓값보다 큰 수를 할당
                                                 // 오버플로우 발생

    unsigned long long num8 = ULLONG_MAX + 1;    // unsigned long long의 최댓값보다 큰 수를 할당
                                                 // 오버플로우 발생

    // unsigned char, unsigned short, unsigned int는 %u로 출력하고 
    // unsigned long long은 %llu로 출력
    // 부호 없는 정수에서 저장할 수 있는 범위를 넘어서면 최솟값 0부터 다시 시작
    printf("%u %u %u %llu\n", num5, num6, num7, num8); // 0 0 0 0

    return 0;
}
/* 실행 결과 */
-128 -32768 -2147483648 -9223372036854775808 0 0 0 0

부호 있는 정수는 저장할 수 있는 범위를 넘어서면 최솟값(음수)부터 다시 시작하고, 부호 없는 정수는 범위를 넘어서면 최솟값인 0부터 다시 시작합니다.

 

마찬가지로 최솟값보다 작아지면 언더플로우가 발생합니다

/* integer_min_underflow.c */
#include <stdio.h>
#include <limits.h>    // 자료형의 최댓값과 최솟값이 정의된 헤더 파일

int main()
{
    char num1 = CHAR_MIN - 1;          // char의 최솟값보다 작은 수를 할당. 언더플로우 발생
    short num2 = SHRT_MIN - 1;         // short의 최솟값보다 작은 수를 할당. 언더플로우 발생
    int num3 = INT_MIN - 1;            // int의 최솟값보다 작은 수를 할당. 언더플로우 발생
    long long num4 = LLONG_MIN - 1;    // long long의 최솟값보다 작은 수를 할당. 언더플로우 발생

    // char, short, int는 %d로 출력하고 long long은 %lld로 출력
    // 부호 있는 정수에서 최솟값보다 작아지면 최댓값부터 다시 시작
    printf("%d %d %d %lld\n", num1, num2, num3, num4);
    // 127 32767 2147483647 9223372036854775807

    unsigned char num5 = 0 - 1;         // unsigned char의 최솟값보다 작은 수를 할당
                                        // 언더플로우 발생

    unsigned short num6 = 0 - 1;        // unsigned short의 최솟값보다 작은 수를 할당
                                        // 언더플로우 발생

    unsigned int num7 = 0 - 1;          // unsigned int의 최솟값보다 작은 수를 할당
                                        // 언더플로우 발생

    unsigned long long num8 = 0 - 1;    // unsigned long long의 최솟값보다 작은 수를 할당
                                        // 언더플로우 발생

    // unsigned char, unsigned short, unsigned int는 %u로 출력하고
    // unsigned long long은 %llu로 출력
    // 부호 없는 정수에서 최솟값보다 작아지면 최댓값부터 다시 시작
    printf("%u %u %u %llu\n", num5, num6, num7, num8);
    // 255 65535 4294967295 18446744073709551615

    return 0;
}
/* 실행 결과 */
127 32767 2147483647 9223372036854775807 255 65535 4294967295 18446744073709551615

최솟값에서 1을 빼서 값이 더 작아지면 언더플로우가 발생하여 다시 한 바퀴 돌게 되므로 최댓값이 출력됩니다.

3. 출처

① https://learn.microsoft.com/ko-kr/cpp/c-language/cpp-integer-limits?view=msvc-170

② https://dojang.io/mod/page/view.php?id=34

728x90
반응형

'⌨️CS-STUDY > C' 카테고리의 다른 글

[C][Macro] min max  (0) 2023.02.21
[C][header][stdio.h] printf  (0) 2023.01.31
[C][header][stdio.h] scanf  (0) 2023.01.29
[C][header][stdio.h] fgets  (0) 2023.01.23