일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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언어
- Windows Forms
- 알고리즘
- 실습
- 소켓 통신
- 동영상 강의
- 캡슐화
- 소스 코드
- C++
- 실습으로 다지는 c#
- 안드로이드 앱 개발
- 네트워크 프로그래밍
- 산책하기 좋은 곳
- 무료 동영상 강의
- 유튜브 동영상 강의
- c#
- 강의
- 표준 라이브러리 함수
- 동영상
- 파이썬
- 프로젝트
- 표준 입출력
- 추천
- 원격 제어 프로그램
- 언제나 휴일
- 언제나휴일
- 졸업 작품 소재
- 클래스 다이어그램
- 충남 천안
- 졸업 작품
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
Part 6. 정수 형식의 표현 범위와 Overflow 값 잘림 현상 본문
17. 정수 형식의 표현 범위
char 형식과 unsigned char 형식은 정수를 표현할 때도 사용할 수 있다고 했어요.
두 가지 형식 모두 1바이트를 할당하여 256가지의 정수를 표현할 수 있답니다.
unsigned char 형식은 부호 없는 정수만 표현하므로 0~0xFF(0~255)까지 표현 가능해요.
char 형식은 최상위 비트가 0인 0x00~0x7F(0~127)까지는 부호없는 정수예요.
그리고 최상위 비트가 1인 0x80~0xFF(-128~-1)까지는 부호있는 정수죠.
◈ char 형식과 unsigned char 형식의 표현 범위 확인
#include <stdio.h>
int main()
{
char c = 0;
unsigned char uc = 0;
c = 0x7F; //최상위 비트가 0
uc = 0x7F;
printf("%d %d\n",c,uc);
c = 0x80; //최상위 비트가 1
uc = 0x80;
printf("%d %d\n",c,uc);
c = 0xFF;
uc=0xFF;
printf("%d %d\n",c,uc);
return 0;
}
◈ 실행 결과
127 127
-128 128
-1 255
다음은 부호 있는 정수를 표현하는 char, short, int, long 형식으로 표현할 수 있는 최대값과 최소값을 확인하는 코드예요.
◈ 부호 있는 정수 형식의 최솟값과 최댓값
#include <stdio.h>
int main()
{
char c = 0x7F;
short s = 0x7FFF;
int i = 0x7FFFFFFF;
long l = 0x7FFFFFFF;
long long ll = 0x7FFFFFFFFFFFFFFFLL;
printf("char max:%d ",c);
c = 0x80;
printf("char min:%d \n",c);
printf("short max:%d ",s);
s = 0x8000;
printf("short min:%d \n",s);
printf("int max:%d ",i);
i = 0x80000000;
printf("int min:%d \n",i);
printf("long max:%d ",l);
l = 0x80000000;
printf("long min:%d \n",l);
printf("long long max:%lld ",ll);
ll = 0x8000000000000000;
printf("long long min:%lld \n",ll);
return 0;
}
◈ 실행 결과
char max:127 char min:-128
short max:32767 short min:-32768
int max:2147483647 int min:-2147483648
long max:2147483647 long min:-2147483648
long long max: 9223372036854775807 long long min: -9223372036854775808
여기서 잠깐!
설마 눈으로만 보고 머리로 이해할 수 있다고 개발 도구에서 직접 확인하지 않는 것은 아니죠?
프로그램 언어는 개발 도구를 통해 몸으로 익혀야 합니다.
코드를 보면서 작성해도 오타가 나오거든요.
오류를 확인하면서 문제를 해결하는 것을 익히는 것은 매우 중요해요.
18. OVERFLOW와 값 잘림 현상
만약 정수 형식에서 표현할 수 있는 범위를 벗어나는 연산을 수행하면 어떻게 될까요?
표현 범위를 벗어날 때 처리하는 방식은 프로그래밍 언어마다 달라요.
C언어에서는 표현 범위를 벗어나도 프로그램은 예외를 발생하지 않고 동작해요.
물론 연산 결과는 개발자가 원하는 결과가 아닌 엉뚱한 값이 되겠죠.
이처럼 연산 결과가 표현 범위의 벗어나는 것을 오버플로우(overflow)라고 불러요.
좀 더 세분화하면 최대값을 넘어서는 것을 오버플로우, 최소값보다 작아지는 것을 언더플로우(underflow)라고 부르죠.
예를 들어 char 형식 변수 c1에 127(16진수 0x7F)로 설정한 후에 1을 더하면 오버플로우가 발생해요.
이 때 연산 결과는 -128(16진수 0x80)이예요.
물론 c1의 값이 -128(16진수 0x80)일 때 1을 빼면 127(16진수 0x7F)이구요.
◈ 오버플로우와 언더플로우
#include <stdio.h>
int main()
{
char c = 127; //char 형식 변수 c를 선언하고 127(0x7F)로 초기화
c = c+1;
printf("c: %d \n",c); //변수 c의 값 출력
c = c-1;
printf("c:%d \n",c); //변수 c의 값 출력
return 0;
}
◈ 실행 결과
c: -128
c:127
C언어에서는 표현 범위가 다른 정수 형식 사이에 묵시적 형변환을 제공하죠.
표현 범위가 좁은 형식 변수를 넓은 형식 변수에 대입하는 것은 아무런 문제도 발생하지 않아요.
그런데 표현 범위가 넓은 형식 변수를 좁은 형식 변수에 대입할 때는 주의하세요.
예를 들어 int 형식 변수 i에 0x1234 값이 있을 때 char 형식 변수 c에 대입하면 하위 1바이트의 값인 0x34만 남아요.
이러한 현상을 값 잘림 현상이라고 불러요.
◈ 정수 값 잘림 현상
#include <stdio.h>
int main()
{
int i = 0x1234;
char c=0;
c = i;
printf("c:%#x i:%#x \n",c,i); //16진수로 출력
return 0;
}
◈ 실행 결과
c:0x34 i:0x1234
◈ 기본 연습
1. short 형식의 변수 s를 0x7FFF 값으로 초기화한 후 s 변수에 1을 더하면 10진수로 얼마인지 확인하는 코드를 작성하시오.
그리고 실행한 후 출력 결과의 이유를 설명하시오.
//1. short 형식의 변수 s를 0x7FFF 값으로 초기화
//s 변수에 1을 더하면 10진수로 얼마인지 확인하는 코드를 작성하시오.
//그리고 실행한 후 출력 결과의 이유를 설명하시오.
#include <stdio.h>
int main(void)
{
short s = 0x7FFF;
printf("short s: %d\n",s);
s+=1;
printf("short s: %d\n",s);
return 0;
}
▷ 실행 결과
short s: 32767
short s: -32768
▷ 이유
short 형식의 크기는 2바이트이며 부호있는 정수를 표현하는 형식입니다.
0x7FFF는 이진수로 0111 1111 1111 1111 이며 short로 표현할 수 있는 가장 큰 정수입니다.
여기에 1을 더하면 이진수로 1000 0000 0000 0000 이며 short로 표현할 수 있는 가장 작은 정수입니다.
이러한 현상을 overflow라고 부릅니다.
2. int 형식 변수 i를 128 값으로 초기화한 후 char 형식 변수 c에 i를 대입한 후에 값을 출력하는 코드를 작성하시오.
그리고 실행한 후 출력 결과의 이유를 설명하시오.
//2. int 형식 변수 i를 128 값으로 초기화한 후
// char 형식 변수 c에 i를 대입한 후에 값을 출력하는 코드를 작성하시오.
// 그리고 실행한 후 출력 결과의 이유를 설명하시오.
#include <stdio.h>
int main(void)
{
int i = 128;
char c;
c = i;
printf("c: %d\n",c);
return 0;
}
▷ 실행 결과
-128
▷ 이유
int 형식 128은 이진수로 0000 0000 0000 0000 0000 0000 1000 0000 입니다.
char 형식의 크기는 1바이트입니다.
char 형식 변수에 int 형식을 대입하면 하위 1바이트를 제외한 나머지는 값이 잘립니다.
따라서 대입 연산으로 c 의 메모리에는 1000 0000 을 설정합니다.
2진 보수 방식에서 1000 0000은 -128입니다.
'C & C++ > 디딤돌 C언어' 카테고리의 다른 글
Part 9. 산술, 논리, 비교 연산자 (0) | 2024.01.09 |
---|---|
Part 8. 표준 입출력 (0) | 2024.01.09 |
명명법과 형식 정리하기 (0) | 2024.01.09 |
Part 7. 실수 표현과 메모리 구조 (0) | 2024.01.09 |
Part 5. 문자 형식과 ASCII 코드 (1) | 2024.01.09 |
Part 4. 부호 있는 정수 표현 방법 (0) | 2024.01.09 |
Part 3. 형식과 메모리 크기, 진수 표현 (1) | 2024.01.09 |
정리하기 (C언어 소개 ~ 첫 번째 프로그램, Part 1, 2) (0) | 2024.01.09 |