티스토리 툴바

메인 채팅

'프로그래밍 ▒ ━/┣ C/C++'에 총 19개의 글이 있습니다.
  1. 2012/01/30 [C/C++] 6. printf와 scanf
  2. 2012/01/12 [C/C++] 5. 상수와 기본 자료형

2012/01/30 22:32 article by: 임시점검 상태의 Rorolena 카테고리: 프로그래밍 ▒ ━/┣ C/C++
[printf 함수]

1. printf 함수는 문자열을 출력하는 함수이다.
printf 함수는 문자열을 출력하는 함수입니다.
그런데 C언어는 큰 따옴표를 사용해서 문자열을 표현합니다.
따라서 큰 따옴표로 묶인 문자열을 전달하면서 printf 함수를 호출하면
전달된 문자열이 모니터상에 출력됩니다.

사용은 다음과 같이합니다.
printf("I like programing\n");

2. 특수문자의 출력이 필요한 이유
문자열에 포함되는 특수문자는 작은 따옴표로 묶어서 독립된 문자상수로도 존재할 수 있습니다.
즉, 알파벳 문자와 마찬가지로 다음과 같이 표현 하는 것도 가능합니다.

char ch='\n';

그렇다면 특수문자 혹은 이스케이프 스퀀스라 불리는
문자들이 필요한 이유를 다음 문장을 통해 알아봅시다.

printf("앞집 강아지가 말했다, "멍~! 멍~!" 정말 귀엽다.");

우리가 바라는 출력결과는
앞집 강아지가 말했다, "멍~! 멍~!" 정말 귀엽다.
이지만 사실 위의 문장은 컴파일 에러를 일으킵니다.

컴파일러는 다음과같이 인식하기 때문입니다.
"앞집 강아지가 말했다, " //문자열
명~! 명~! //???
" 정말 귀엽다." //문자열
이러한 연유들 때문에 특수문자가 필요하게 되었습니다.

3. 특수문자의 종류
다음과 같은 특수 문자들이 있습니다.

특수문자

의미하는 바

\a 경고음
\b 백스페이스(backspace)
\f 폼피드(form feed)
\n 개 행(new line)
\r 캐리지 리턴(carriage return)
\t 수평 탭
\v 수직 탭
\' 작은 따옴표 출력
\" 큰 따옴표 출력
\? 물음표 출력
\\ 역슬래쉬 출력

이중 \f와 \v는 모니터 출력이 아닌 프린터 출력을 위해 정의된
특수문자이기 때문에 모너티의 출력에 사용 하면, 이상한 문자가 출력됩니다.

4. printf 함수의 서식지정
printf란 서식이 지정된 형태의 출력함수 입니다.
따라서 이를 바꾸어 말하면 다음과 같이 말할수 있습니다.
"출력양식이 만들어진 상태에서 출력을 진행한다."

그럼 printf를 어찌 사용하는 지 다음 예를 통해 보겠습니다.

int myAge = 12;
printf("제 나이는 10진수로 %d살, 16진수로 %X살입니다. \n", myAge, myAge);

위의 예제에서 살펴 볼점은 먼저
서식문자가 2개 printf에 전달인자는 3개 라는 것입니다.
만약 절달 인자가 부족하면 정상적이지 않은 결과가 출력됩니다.

다음으로 %X인대 이를 대문자로 작성하면 출력이 대문자로
소문자로 작성하면 출력이 소문자로 출력됩니다.

5. 서식문자의 종류와 그 의미

서식문자 출력 대상(자료형) 출력 형태
%d char, short, int 부호 있는 10진수 정수
%ld long 부호 있는 10진수 정수
%lld long long 부호 있는 10진수 정수
%u unsigned int 부호 없는 10진수 정수
%o unsigned int 부호 없는 8진수 정수
%x, %X unsigned int 부호 없는 16진수 정수
%f float, double 10진수 방식의 부동소수점 실수
%Lf long double 10진수 방식의 부동소수점 실수
%e, %E float, double e 또는 E 방식의 부동소수점 실수
%g, %G float, double 값에 따라 %f와 %e 사이에서 선택
%c char, short, int 값에 대응하는 문자
%s char * 문자열
%p void * 포인터의 주소 값

6. 정
수의 출력을 위한 서식문자들: %d, %u, %o, %x
%d, %u, %o, %x는 정수를 표현하기 위한 서식문자들 인대
예제를 통해 간단하게 확인하고 넘어가도록 합시다.

int num1=7, num2=13;
printf("^%o %#o \n", num1, num1);
printf("^%x %#x \n", num2, num2);

위 예제에서 보이듯이 10진수외에 출력할 경우 출력된 내용이
10진수가 아님을 알리기 위해서 가급적 서식문자에 #을 포함시키는 것이 좋습니다.

7. 실수의 출력을 위한 서식문자들: %f, %e, %g
다음 실수 예제를 보도록 합시다.

printf("%f \n", 0.1234);
printf("%e \n", 0.1234);
printf("%f \n", 0.12345678);
printf("%e \n", 0.12345678);

위 예제중 서식문자 %e를 사용했을 때의 출력결과를 확인할 필요가 있습니다.

1.234000e-001
1.234568e-001

이러한 출력의 형태를 가리켜 e표기법 이라 하며
이는 지수형태의 출력을 표현한 것입니다.

그럼 다음의 숫자가 있다고 가정하고 이를 지수로 표현한다면
0.00000000000000000001
1.0x 10^-20

그런데 이를 프로그램상에서는 지수를 표현할수 없기때문에 다음과같이 작성합니다.
1.0e-20

그럼 이를 이용해 다음 예제를 확인해봅시다.

double d1=1.23e-3;
double d2=1.23e-4;
double d3=1.23e-5;
double d4=1.23e-6;

printf("%g \n", d1);
printf("%g \n", d2);
printf("%g \n", d3);
printf("%g \n", d4);

위의 예제를 통해 할수 있는 사실은 다음과 같습니다.
"%g는 소수점 이하의 자릿수가 늘어나면 e표기법으로 출력을 하는구나!"

8. %s를 이용한 문자열의 출력
%s에서의 s는 string의 약자로서 문자열의
출력을 지시하기 위한 서식문자에 사용됩니다.

자세한 사항은 후에 설명하니 여기서는
간단한 사용법만 살펴 보도록 하겠습니다.

printf("%s, %s, %s \n", "AAA", "BBB", "CCC");

9. 필드 폭을 지정하여 정돈된 출력 보이기
서식문자에는 출력의 필드 폭을 지정하는 옵션을 추가할 수 있습니다.
printf 함수는 명령 프롬프트상에 출력하기 떄문에, 보기 좋은 출력을 위해서
필드의 폭을 지정하는 것도 필요한대 다음과 같습니다.

- %8d 필드 폭을 8칸 확보하고, 오른쪽 절렬해서 출력을 진행한다.
- %-8 필드 폭을 8칸 확보하고, 왼쪽 정렬해서 출력을 진행한다.

[scanf 함수]
scanf 함수의 기본적인 사용법에 대해서는 앞서 자세히 설명하였으므로
여기서는 입력을 위한 서식 지정 방법만 설명하도록 하겠습니다.

1. 정수 기반의 입력형태 정의하기
scanf 함수는 printf 함수의 상대적인 기능을 지닙니다.
printf 함수는 출력에 사용되지만 scanf 함수는 입력에 사용됩니다.
따라서 scanf 함수의 호출을 위해서는 다음 두 가지 정보가 전달되어야 합니다.

- 입력의 형식 어떻게 받아들일 건가?
- 입력의 장소 어디에 저장할것인가?

이 중에서 입력이 형식을 지정할 때도 printf 함수와 마찬가지로 서식문자를 사용합니다.
scanf 함수의 관점에서 서식문자의 의미는 다음과 같습니다.

%d 10진수 정수의 데이터 입력
%o 8진수 양의정수 테이터 입력
%x 16진수 양의정수 데이터 입력

다음 예제를 통해 확인해 보도록합시다.

inr num1, num2, num3
printf("세 개의 정수 입력: ");
scanf("%d %o %x", &num1, &num2, &num3);
printf("입력된 정수 10진수 출력: ");
printf("%d %d %d \n", num1, num2, num3);

2. 실
수 기반의 입력형태 정의하기
printf 함수에서는 서식문자 %f, %e, %g의 으미가 각각 달랐습니다.
그러나 scanf 함수에서는 float형 데이터를 입력 받겠다는
동일한 의미를 담고 있습니다.

그럼 double형 데이터는 어떻게 입력 받아야 하는가는
다음과같이 작성할수 있습니다.

%lf double
%Lf long double

저작자 표시 비영리 변경 금지
트랙백 0 댓글 0 위로↑

 
 
 
 
 
 
 
 
 
 
 
 
 
 


2012/01/12 22:56 article by: 임시점검 상태의 Rorolena 카테고리: 프로그래밍 ▒ ━/┣ C/C++
이번 포스팅에선 상수와 기본 자료형에대한
간략적 개념을 살펴보도록 하겠습니다.


[C언어가 제공하는 기본 자료형의 이해]

1. 자료형은 데이터를 표현하는 방법입니다.

변수는 데이터의 저장을 위해서 할당된 메모리 공간에
붙여진 이름 이라고 앞서 설명하였습니다.

그런데 이 메모리 공간의 할당에 앞서 다음의 내용이 결정되어야 합니다.
"어떤 데이터를 저장 할것입니까"

이는 변수의 타입마다 저장을 위한 범위와 저장방식이 틀리기 때문입니다.
그래서 우리는 변수선언에 앞서 이것지 실수인지 정수인지 문자인지
그리고 얼만큼의 수를 쓸지를 미리 탐색하고 알맞은 타입을 선언해주어야 합니다.

2. 기본 자료형의 종류와 데이터의 표현범위
C언어는 여러가지의 자료형을 정의하고 있습니다.

자료형

크기

값의 표현범위

정수형

char 1바이트 -128이상 +127이하
short 2바이트 -32,768이상 +32.767이하
int 4바이트 -2,147,483,648이상 +2,147,483,647이하
long 4바이트 -2,147,483,648이상 +2,147,483,647이하
long long 8바이트 -9,223,372,036,854,775,808이상
+9,223,372,036,854,775,807이하

실수형

float 4바이트 ±3.4 × 10^-37이상 ±3.4 × 10^38이하
double 8바이트 ±1.7 × 10^-307이상 ±3.4 × 10^308이하
long double 8바이트 이상 double 이상의 표현범위

상기 제공되는 자료형을 가르켜 기본 자료형이라 합니다.

여기서 우리는 외이렇게 많은 자료형을 제공하는지
생각해보아야 하는대 이이유는 다음과같습니다.

- 데이터의 표현방식이 다르므로, 최소 둘이상의 자료형이 필요합니다.
- 메모리 공간의 적절한 사용을 위해서 다양한 크기의 자료형이 필요합니다.

3. 연산자 sizeof를 이용하면 자료형의 크기를 확인할 수 있습니다.
메모리 공간에서 소모하는 메모리의 크기를 바이트 단위로
계산해서 반환하는 sizeof라는 연산자가 존재 합니다.

이 연산자는 피연산자로는 변수와 상수뿐만 아니라, 자료형의 이름도
올 수 있기 때문에 이를 이용해서 자신이 사용하는 컴파일러의
자료형 별 바이트 크기도 확인할 수 있습니다.

sizeof 연산자의 사용방법은 다음과 같습니다.

int main(void)
{
int num = 10;
int sz1 = sizeof(num);
int sz2 = sizeof(int);
return 0;
}

위의 예제에서는 sizeof 연산자의 피연산자를 모두 소괄호로 감싸줬는데,
이소괄호는 int와같은 자료형은 필수지만 나머지 피연산자에 대해서는 선택사항 입니다.
하지만 소괄호를 사용하는 것이 가독성이 높기에 쓰도록합니다.

4. 정수를 표현 및 처리하기 위한 일반적인 자료형의 선택
지금까지 자료형 이야기를 하였는데 그렇다면
이런 다양한 자료형 중에서 무엇을 선택하는 것이 적합하겠는가?
이를 정할 어느정도 지침이 있다면 선택이 한결 수월 해질것 입니다.
그럼 먼저 정수 데이터 처리의 경우를 살펴봅시다.

가령 short형 범위 만으로 저장할수 있는 정수가 있다면 이를
int형 변수를 대신해서 short형 변수를 선언하는 것이 더 효율적인가?
이 질문의 답은 상황에 따라 다릅니다.

이는 아래의 코드를 통해 확인 해보도록 합시다.

int main(void)
{
char num1=1, num2=2, result1=0;
short num3=300, num4=400, result2=0;

printf("size of num1 & num2: %d, %d \n", sizeof(num1), sizeof(num2));
printf("size of num3 & num4: %d, %d \n", sizeof(num3), sizeof(num4));
printf("size of char add: %d \n", sizeof(num1+num2));
printf("size of short add: %d \n", sizeof(num3+num4));

result1=num1+num2;
result1=num3+num4;
printf("size of result1 & result2: %d, %d \n", sizeof(result1), sizeof(result2));
return 0;
}

실행결과는 다음과 같습니다.

여기서 우리가 주목 해야할점은 이부분입니다.
printf("size of char add: %d \n", sizeof(num1+num2));
printf("size of short add: %d \n", sizeof(num3+num4));
출력되는 값이 4바이트로 나오고 있습니다.
하지만 아래에 합한 값은 정상적으로 1, 2바이트로 표기 되고있습니다.

사실 이는 그럴만한 이유가 있는대
일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형은 int로 정의됩니다.
따라서 int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 더 빠릅니다.
이렇듯 int형 연산이 CPU가 성능을 내기 가장 좋은 연산이다 보니
int보다 작은 데이터는 잠시 int형으로 바꿔 연산이 진행됩니다.

그럼 char와 short은 불필요 한것이 아니냐 라는 말이 나올수 있는대
이는 용량이 민감한 데이터 즉 영상,음성,그림 등등의 데이터 들을 예로 들수 있습니다.

5. 실수를 표현 및 처리하기 위한 일반적인 자료형의 선택
앞서 자료형 테이블에서 실수형의 범위를 보아서 알듯이
실수형 데이터가 표혈할 수 있는 값의 표현범위는 매우 넓습니다.
사실 값의 표현범위는 중요요소가 되지않습니다.

그럼 실수를 표현함에 가장 중요한것은 무엇인가 라는 물음에
실수 자료형의 가장 중요한 요소는 정밀도 입니다.
라고 대답할수 있습니다.

실수 자료형

소수점 이하 정밀도

바이트 수

float 6자리 4
double 15자리 8
long double 18자리 12

위의 표를 보면 double형의 경우, 소수점 15자리까지는
오차를 보장하니 이는 정밀도가 높은 편이라 할 수 있습니다.
이런 double형이 실수에선 int와 같은 역활을 합니다.

6. unsigned를 붙여서 0과 양의 정수만 표현하게 할 수 있습니다.
정수 자료형의 이름에 한해서 unsigned 선언을 추가하면, 0 이상의 값만 표현하는
자료형이 되어서, 표현할 수 있는 양의 정수범위가 두배로 넓어집니다.

[문자의 표현방식과 문자를 위한 자료형]
대부분의 프로그램에서는 사용자와의 상호작용이 필요하다 보니,
문자의 표현은 중요할 수밖에 없습니다.

따라서 문자를 저장하고 표현하는 방법을 알아보도록 하겠습니다.

1. 문자의 표현을 위한 약속! 아스키(ASCII)코드!
컴퓨터는 문자를 숫자로 저장 합니다.
그럼 이를 이용해 문자를 표현하도록 하려면
숫자를 문자에 견결 시키는 것이 유일한 방법 입니다.
즉, 미리 숫자와 문자를 약속해두는 겁니다.

이런 문자와 숫자의 약속은 종류가 다양한대,
그 중 가장 널리 사용되는 것이 ASCII코드 이며 아래와 같이 짜여있습니다.


2. 문자는 이렇게 표현되는 거구나!
그럼 문자를 숫자로 표현한다는 사실과 아스키코드의 존재를 알게 되었으니
이를 코드로 표현해보면 아래과 같이 사용할수 있습니다.

int main(void)
{
char ch1='A', ch2=65;
int ch3='z', ch4=90;

printf("%c %d \n", ch1, ch1);
printf("%c %d \n", ch2, ch2);
printf("%c %d \n", ch3, ch3);
printf("%c %d \n", ch4, ch4);
return 0;
}

우선 위 예제에 처음 보인 서식 문자 %c는 다음의 의미를 지닙니다.
"문자에 형태로 데이터를 출력9또는 입력)하라."

그럼 위 예제의 내용을 살펴보면 다음과 같이 요약할수 있습니다.
- 문자는 입력 방법에 따라서 문자와 숫자 어느것으로도 입력이 가능하다.
- 정수는 출력의 방법에 따라서 문자와 숫자로 출력이 가능하다.

그럼 여기서 나올수 있는 이야기로 앞서 int형 선언이 빠르다는 이야기를 했습니다.
그럼 문자도 int형 변수로 저장해야 하는것이 아닌가 하는 의문이 들수 있는데
이는 한가지 알아야 할점이 있습니다.

int형 선언이 빠른것은 연산을 실행 할때뿐이며
통상 문자를 가산할 일이 없다라는 점 입니다.

즉 문자간의 연산은 수행은 가능 하지만 문자간에
연산을 할일이 없기때문에 용량에 맞춰 사용 하는것 입니다.

[상수에 대한 이해]

상수는 크게 이름이 있는 상수와 이름이 없는 상수로 나뉘며,
상수 역시 앞서 설명한 int, double과 같은 자료형을 근거로 표현됩니다.

1. 이름을 지니지 않는 리터럴(Literal) 상수
상수란, 그 이름 그대로 변경이 불가능한 데이터를 뜻합니다.
상수와 관련해서 다음 코드를 보면

int main(void)
{
int num = 30 + 40;
}
위의 코드에서는 30과 40의 합을 결과를 변수 num에 저장하는 문장이 존재합니다.
그렇다면 대입연산과 덧셈연산중 어느쪽이 우선이겠는가?
당연히 덧셈연산이 우선입니다.

즉, 덧셈이 우선 진행되고, 그 결과값으로 변수 num을 초기화하게 됩니다.
그럼 CPU가 30과 40의 연산을 한다는 뜻인데,
메모리에 존재하지않는 값을 연산할수 없으니
그러기 위해서는 두수 모두 메모리상에 존재해야 합니다.
이런 이름 없는 상수를 가리켜 리터럴 상수 또는 리터럴 이라 합니다.

2. 리터럴 상수의 자료형

자료형은 변수뿐 아니라 상수를 위해서도 존재합니다.
메모라상에 저장되는 모든 데이터는 자료형이 결정되어야
저장하는 방법이 정해지기 때문입니다.
아래 예제를 통해 확인해보도록 합시다.

int main(void)
{
printf("lireral int size: %d \n", sizeof(7));
printf("lireral double size: %d \n", sizeof(7.14));
printf("lireral char size: %d \n", sizeof('A'));
return 0;
}

아마 소스를 보면서 리터럴 상수가 지정해준 변수 타입으로
타입이 잡힐꺼라 생각 했을지도 모르겠지만
리터럴 상수는 값에 상응하는 타입으로 알아서 잡히게 됩니다.

3. 접미사를 이용한 다양한 상수의 표현
정수형에는 int와 실수형 double만 있는 게 아닙니다.
그럼 이 이외의 자료형을 기반으로 상수를 표현하려면
해당 자료형을 의미하는 접미사를 붙여주면 됩니다.

예로 다음과 같이 코딩하면
float num1 = 5.789;

컴파일 에러는 나지 않지만 애러가 발생합니다.
이는 더블형 실수를 플롯형에 그냥 대입 되는 형태이기 때문입니다.

이를 방지하려면 다음과 같이 코딩하면됩니다.
float num1 = 5.789f;

이렇듯 C언어는 다양한 자료형의 상수를 표현할 수 있도록
다음과 같이 접미사를 정의하고 있습니다.

[정수형 상수표현]

접미사

자료형

사용의 예

U unsigned int unsigned int n = 1025U
L long long n = 2467L
UL unsigned long unsinged long n = 3456UL
LL long long long long n = 5768LL
ULL unsgined long long unsigned long long n = 8979ULL

[실수형 상수표현]

접미사

자료형

사용의 예

F float float f = 3.15F
L long double long double f = 5.789L

참고 사항으로 위의 접미사들은 대소문자 구분이 없으니
상황에 알맞게 눈에 잘 띄도록 사용하면 됩니다.

4. 이름을 지니는 심볼릭(Symbolic) 상수 : const 상수
심볼릭 상수는 변수와 마찬가지로 이름을 지니는 상수입니다.
이러한 심볼릭 상수를 표현하는 방법에는 두가지가 있는데,
그 중 하나는 'const 키워드'를 사용하는 방법이고, 또 하나는
매크로를 이용 하는 바업인대 매크로는 Chapter 26에서 언급하므로
여기서는 const 키워드를 사용하는 방법만 알아보겠습니다.

const 키워드를 이용해서 상수를 만드는 방법은 무척이나 쉽습니다.
변수 선언 시 const 선언만 추가하면 되기 때문입니다.
단, 이는 상수이므로 선언과 동시에 초기화 해야 하며
선언후에는 값을 변경시킬 수 없습니다.

컨스트 상수는 다음과 같이 사용하며
const int MAX = 100;
const double PI = 3.1415;

다음과 같이 코딩할수 없습니다.
const int MAX;
MAX = 100;

이경우는 MAX를 쓰레기 값으로 초기화를 시킨후
다시 100으로 대입하려는 경우이기 때문에 안됩니다.

참고로 상수와 관련해서 다음사실도 기억하시기 바랍니다.

상수의 이름은 모두 대문자로 표시하고, 둘 이상의 단어로 연결할 때에는
MY_AGE와 같이 언더바를 이용해서 두 단어를 구분하는 것이 관례입니다.

[자료형의 변환]

char형으로 표현되어 있는 데이터의 표현방식을 int형으로 바꾸거나,
int형으로 표현되어 있는 데이터의 표현방식을 double형으로 바꾸는 것이 바로 자료형의 변환입니다.

즉, 자료형의 변환이라는 것은 데이터의 표현방식을 바꾸는 것입니다.
이러한 자료형의 변환은 다음과 같이 크게 두 종류로 나뉩니다.

- 자동 형 변환(묵시적 형 변환)
- 강게 형 변환(명시적 형 변환)

1. 대입연산의 전달과정에서 발생하는 자동 형 변환
대입 연산자의 왼편과 오른편에 존재하는 두 피연산자의 자료형에 일지하지 않으면,
왼편에 있는 피연산자를 대상으로 형 변환이 자동으로 일어납니다.

이는 저장소의 자료형에 맞춰서 형 변환이 일어나야 값의 저장이
가능 하기 때문 임으로 이와 관련해서 다음 문잔을 보면 다음과 같습니다.

double num1 = 245;

이 경우 대입 연산자의 왼편에 있는 num1은 double형이지만 245는 int형입니다.
따라서 245는 245.0으로 변환되어 저장되게 됩니다.
이어서 다음 문장을 보면

int num2 = 3.1415;

이경우는 double형 상수가 int형 에 저장되기 위해서
정수이외의 수 즉 소수점 .1415를 버리고 3으로 변환되어 저장되게 됩니다.
그렇다면 다음의 경우에는 어떻게 형 변환이 진행되겠는가?

int num3 = 129;
char ch = num3;

참고 사항으로 int형 129의 비트 열은 다음과 같습니다.

00000000 00000000 00000000 10000001

그런데 이른 char형으로 바꾸면 1바이트가 되므로
상위 바이트의 손실이 발생합니다.
따라서 이는 정수로 -127이 됩니다.

이렇듯 상위 바이트의 손실로 인해서 부호가 바뀌는 경우도 있으니 주의해야 합니다.
다음은 위의 사항을 정리한것입니다.

▶ 정수를 실수로 형 변환하는 경우
정수에 해당하는 값을 실수로 표현하게 되는데,
이는 손실이 발생하지 않으나 실수의 표현이기 때문에
오차가 존재하게 됩니다.

▶ 실수를 정수로 형 변환하는 경우
정수는 소수점 이하의 값을 표현하지 못하기 때문에,
소수점 이하의 값은 버려집니다.

▶ 바이트 크기가 큰 정수를 바이트 크기가 작은 정수로 형 변환하는 경우
변환하고자 하는 정수의 바이트 크기에 맞춰서 상위 바이트를 단순히 소멸시킵니다.
그리고 이로 인해서 부호가 바뀔 수도 있으니, 주의가 필요합니다.

2. '정수의 승격(Integral Promotion)'에 의한 자동 형 변환
앞선 자동 형 변환 외에도 다음과같은 방식도 가능합니다.

short num1=15, num2=25;
short num3=num1+num2;

이러한 형태의 형 변환을 가리켜 정수의 승격이라 합니다.
그런데 위의 코드에서는 정수의 승격만 일어난 게 아닙니다.
num1+num2의 계살결과는 4바이트 크기의 int형 정수입니다.
따라서 이 값을 변수 num3에 저장하기 위해서, 앞서 언급한
대입연산 과정에서의 형 변환이 다시 일어나게 됩니다.

3. 피연산자의 자료형 불일치로 발생하는 자동 형 변환
사칙연산과 같은 기본적인 산술연산에는 두 개의 피연산자가 필요합니다.
그런데 이 둘읭 자료형은 일치해야 하며, 만약 일치하지 않을 시에는 자료형의
일치를 목적으로 자동 형 변환이 일어납니다.
그럼 아래 문장을 예로 이야기 해봅시다.

double num1 = 5.15 + 19;

이 문장에서는 실수형 데이터 5.15와 정수형 데이터 19의 합을 요구하고 있습니다.
그런데 정수와 실수는 표현방식이 다르므로 이를 CPU가 연산하기 위해선
어느 한쪽으로 형변환이 이루어져야 합니다.
그렇다면 어떤 쪽의 형변환이 좋은 선택이겠습니까?

만약 5.15를 정수로 반환하면 소수부의 손실이 발생하기 때문에
이럴때에는 다소 오차가 있어도 정수 19가 실수로 변환되어 계산됩니다.

이렇듯, 피연산자의 자료형이 일치하지 않아서 발생하는 자동 형 변환은
데이터의 손실을 최소화하는 방향으로 진행됩니다.
그리고 여기서 말하는 데이터 손실의 최소화 기분은 다음과 같습니다.

int -> long -> long long -> float -> double -> long double

여기서 참고사항이 두가지가 있는대 먼저

char와 short는 왜 생략됬는가 입니다.
char와 short형 정수의 경우는 정수의 승격에 의해
둘 다 int형 정수로 형 변환이 되기때문입니다.

그다음은 long long이 어째서 float보다 우선운위가 낮은가 입니다.
단순히 bit만 두고 보면 lonb lonb이 더 큰수를 표현 할수 있을것 같만
실은 범위로 보면 float형이 더큰수를 표현 할수있으며
또한 정수형 변수는 소수점을 저장하지 못하기 때문에
반드시 손실이 발생하기 떄문입니다.

4. 명시적 형 변환: 강제로 일어키는 형 변환
명시적 형 변환이란, 형 변환 연산자를 이용해서
강제로 형 변환을 명령하는 것을 의미합니다.
다음 예제를 통해 알아보도록 합시다.
{
int num1 = 3, num2 = 4;
double divResult;
divResult = num1 / num2;
printf("나누셈 결과: %f \n", divResult);
}


나눗셈의 결과로 0.75가 출력될 것을 기대한 분들에게는 안타깝지만
상기 문항은 연산결과의 자로형은 피연산자의 자료형과 일치하기 때문에
나눗셈 결과는 0이 되고 이값이 double형으로 자동 형 변환되어
변수 divResult에 저장됩니다.

그럼 상기 내용을 다음과 같이고치면
divResult = (double)num1 / num2;
우리가 원하던 0.75가 출력이 됩니다.

C언어에서의 소괄호는 연산의 순서를 지정하기 위해서도 사용되지만
형 변환을 명령할 때에도 사용이 됩니다.
이렇게 사용되는 소괄호를 가리켜 형 변환 연산자라 하며
연산의 결과로는 변환된 값이 반환됩니다.

즉 위의 변화 과정을 살펴보면 다음과 같습니다.

divResult = (double)num1 / num2;
       ↓
divResult = 3.0 / num2;
       ↓
divResult = 3.0 / 4.0;

이번 포스팅에선
수에대한 개념을 다루었는대요
이것은 굉장히 중요합니다.

프로그램은 죄다 수로 이루어져있기 때문에
정확한 수에대한 개념과 표현을 확실히 하지않으면
만들어진 프로그램들이 엉뚱한 작동을 할수도 있기때문이죠
그러니 이번 포스팅은 반드시 이해하고 넘어가주시면 좋습니다.

저작자 표시 비영리 변경 금지
트랙백 0 댓글 0 위로↑

 
 
 
 
 
 
 
 
 
 
 
 
 
 


1 2 3 4 5 ... 10