본문 바로가기

C-programing

[C언어 기초] 자료형, 자료형 변환

※사진이 별로 없기 때문에, 가독성이 좀 떨어질 수 있습니다. ●표시는 >표시에 속한 것으로 진하게 표시되어 있는 것과 표, 주황색 글씨 위주로 읽어주시면 쉽게 틀을 잡으실 수 있을 것입니다.

 

 

오늘은 C언어 자료형에 대해서 이야기 하려고 한다. 이것을 배울 때는, 컴퓨터가 선호하는 자료형이 어떤 건지 알아두는 것이 포인트 이다. 그리고, 복잡한 수칙연산과 데이터 입력과 출력에 있어서 자동형 변환이 이루어짐을 알고 이것을 방지하기 위해 프로그래머가 강제로 자료형을 변환하는 경우를 생각하는 것도 매우 중요하다. 기초적이기 때문에, 큰 프로젝트를 짤 때 지나치기 쉽기 때문이다. 접근은 세가지로, 1. 컴퓨터가 선호하는 자료형 설명, 2. 자동형 변환, 3. 강제형 변환 이다.

 

 

> 자료형? 컴퓨터가 선호하는 자료형?

 

자료형이란, 임시 데이터를 저장하는 공간의 범위이다. 헷갈리기 쉬운게, 자동형 변환을 이해할 때, 변수를 두고 생각하면 쉽게 풀리지 않을 수 있다. 자료형은 그저 범위일 뿐이고, 그것이 문자를 담는 전용 자료형이거나 실수를 담는 전용 자료형이라고 생각하면 안된다. 그러니까, 범위가 있기 때문에 그저 자료형이 자주 이용되는 변수의 타입(정수, 실수, 문자)이 일정한 것일 뿐이다.

 

 

● char 자료형의 문자저장, 정수저장

 

 

 

 

char a = 120;

문자형 변수 a에 정수형 120을 저장하겠다. 하지만, 문자형인데 왜 정수형이 저장되는 것일까? char의 범위는 -128~+127이다. 즉, 127만 넘지 않으면, 정수형도 저장이 가능하다는 것이다.

 

printf("%c \n", a);

문자형 변수 a를 문자형으로 출력하겠다. x가 출력된다. ASCII코드를 보아라.

 

printf("%d \n", a);

문자형 변수 a를 정수형으로 출력하겠다. 127을 넘지 않은 120이므로, 그대로 출력이 가능하다. 만약 127을 넘으면 오버플로어, -128 보다 아래면 언더플로어가 되는데, 이것은 차후에 연산자 포스팅할 때 언급하겠다.

 

 

 

자료형 

메모리크기 

데이터 표현 범위 

char  

1byte (8bit) 

-128~ +127 

int 

4byte (32bit) 

-214783648~ +2147483647 

double

8byte (64bit) 

~ 생략하겠다. 

 

 

 

여기서 말하는게 무엇이겠는가? 자료형은 그저 범위의 표현일 뿐이고, 저장되는 데이터가 곧 그 범위에 속한다면, 오버 플로어도 언더플로어도 아니라는 것이다. 데이터 범위를 고려해야하는 이유는 int는 정수의 범위만 표현하고 있다는 점에서 실수형을 대입하게 되는 경우, 데이터가 손실될 수 있다는 것과, 자동형 변환에서 실수형과 정수형, 문자형이 데이터에 맞지 않게 수행되어 데이터손실이 생기는 경우이다. 

 

 

 

●  double, 소수점 표시 방법. 

 

 

 

 

float a=  0.123....;

실수형 변수 a에 실수형 0.123..을 저장하겠다

 

printf("%.15f \n", a);

소수점 15자리 까지 실수형 변수 a에 저장된 데이터 실수형으로 출력하겠다. 하지만, 여기서 데이터손실이 생긴다. double이 선호되는 이유이기도 한데, float형은 소수점 6자리까지만 표현이 가능하기 때문에 데이터가 손실되는 것이다. 

 

 

 

선호하는 자료형 int와 double

 

컴퓨터가 선호하는 자료형은, c언어 프로그램이 4byte 단위로 짜여있기 때문이다. double, float, long double 실수형 자료형으로 3가지지만, 딱히 double 외에 잘 쓰지 않는다. int 형도 마찬가지이다. 그래도 알아두고자 한다면, c언어 기초 서적으로 공부하는 것이 좋을 것이다.

 

 

 

 

 

 

>자동형변환

● 자동형변환으로 인한 오류는 두가지이다. 데이터손실과 오버플로어 or 언더플로어이다.

 자동형변환이 일어나는 경우는 두가지이다. 대입연산할 때와 다른 자료형의 변수간의 연산을 할 때이다.

 

 

대입연산으로 인한 자동형변환

 

 

 

 

char ah = 289;

○ 정수형 289를 문자형으로 변환하여 ah라는 변수에 저장하겠다 -> 자동형 변환이 되었다. 정수형이 문자형으로 변환. 오버플로우이다.

 

printf("%c \n", ah);

문자형 변수 ah를 문자형으로 출력하겠다. -> 왜 !가 출력되나? char 형의 최대값은 127이다. 오버플로우이므로, 289-127로,(연산자 포스팅 때 제대로 언급하겠습니다.) 162만큼 초과되었다. char형의 범위 -128~127 내에서 최소값에서부터 162만큼 이동하면, 33이다. 즉, ASCII코드의 10진수 33으로 인식되는 문자 !이다.

 

printf("%d \n", ah);

문자형 변수 AH를 정수형으로 출력하겠다. -> 33이 출력되죠?

 

int a = 3.14;

실수형 3.14를 정수형으로 변환하여 a라는 변수에 저장하겠다. -> 자동형 변환이 되었다. 실수형이 정수형으로 변환. 데이터가 손실된다. 3이 출력될 것이다.

 

그렇다면, 아래 코드도 이해할 수 있을 것이다. 범위가 큰 자료형이 범위가 작은 자료형으로 변환되면 데이터 손실 혹은 오버플로우 언더플로우가 되는 것이다.

 

 

 

연산에 의한 자동형 변환과, 자동형 변환으로 인한 데이터 손실을 방지하는 강제형 변환

 

 

 

 

result = a / b;

○ 정수형 변수 a, b를 나눈 값을 실수형 변수 result에 저장하겠다. -> 연산에 의한 자동형 변환이 일어난다. 정수와 정수를 나누면 정수 혹은 실수가 나올 것이다. 하지만 자동형 변환에 의해서, 결과는 무조건 정수형으로 변환된다. 이미 데이터 손실이 생기고 나서 실수형 변수에 저장되는 것이다.

 

printf("%lf \n", result);

result를 실수형으로 출력한다. 0이 출력된다. -> 이미 잘려버린 데이터이므로 변수가 실수형이어도 잘린값으로 출력된다.

 

result = (double) a / b;

정수형 변수 a를 강제로 실수형으로 변환하겠다. 그리고 b로 나누어 결과값을 실수형 변수 result에 저장하겠다.

-> 강제형 변환을 했다. (double) a : 변수 a를 실수형으로 변환한다. (이해가 잘 가지 않는다면, 밑에 간락햔 정리를 보아라)

 

 

 

 

 강제형 변환 : (int) a -> a라는 변수를 int 자료형으로 강제형 변환하겠다.

 자동형 변환 : 연산에 의한 자동형 변환  정수 / 정수 = 결과가 정수형으로 자동형 변환

                                                             -> 실수 / 정수 = 결과가 실수형으로 자동형 변환

                                                                                     (큰 자료형으로 변환된다.)

                      : 대입에 의한 자동형 변환 -> char a = 129; 정수형이 문자형으로 변환

                                                             -> int a = 3.14; 실수형이 정수형으로 변환

                      : 자동형 변환에 의한 데이터 손실 or 오버 플로우, 언더 플로우

                           ->char a = 129; 오버플로우, 아무것도 출력되지 않는다.

                           ->int a= 31.4; 데이터 손실, 31이 출력