자료형(Data Type)
- 데이터를 표현하는 기준(방법)
기본 자료형
- 정수형
- char(1 Byte): -128 이상 127 이하
- short(2 Byte): -32,768 이상 32,767 이하
- int(4 Byte): -2,147,483,648 이상 2,147,483,647 이하
- long(4 Byte): int와 동일
- long long(8 Byte)
- 실수형
- float(4 Byte)
- double(8 Byte)
- long double(8 Byte 이상)
많은 수의 자료형을 제공하는 이유
- 데이터의 표현방식이 다르기 때문에
- 메모리 공간의 적절한 사용을 위해서 다양한 크기의 자료형이 필요
sizeof 연산자를 이용하여 자료형의 크기 확인
#include <stdio.h>
int main(void)
{
char ch=9;
int inum=1052;
double dnum = 3.1415;
printf("변수 ch의 크기: %d \n", sizeof(ch));
printf("변수 inum의 크기: %d \n", sizeof(inum));
printf("변수 dnum의 크기: %d \n", sizeof(dnum));
printf("char의 크기: %d \n", sizeof(char));
printf("int의 크기: %d \n", sizeof(int));
printf("long의 크기: %d \n", sizeof(long));
printf("long long의 크기: %d \n", sizeof(long long));
printf("float의 크기: %d \n", sizeof(float));
printf("double의 크기: %d \n", sizeof(double));
}
// %d 는 10진수 정수형태의 출력을 의미
// 결과
변수 ch의 크기: 1
변수 inum의 크기: 4
변수 dnum의 크기: 8
char의 크기: 1
int의 크기: 4
long의 크기: 8
long long의 크기: 8
float의 크기: 4
double의 크기: 8
정수를 표현 및 처리하기 위한 일반적인 자료형의 선택
#include <stdio.h>
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));
/* 두 결과가 모두 4 Byte인 이유:
일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형을 int로 정의
-> int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 빠르다
이로 인해, int보다 작은 크기의 데이터는 int형 데이터로 바꿔서 연산이 진행된다. -> 형 변환
따라서, 연산의 대상이 되는 변수를 선언하는 경우, 특히 연산의 횟수가 빈번한 경우에는 저장되는 값의 크기가
작더라도 int형 변수를 선언
char, short가 사용되는 경우:
데이터의 양이 많아서 연산속도보다 데이터의 크기를 줄이는 것이 더 중요한 데이터들 */
result1=num1+num2;
result2=num3+num4;
printf("size of result1 & result2: %d, %d \n", sizeof(result1), sizeof(result2));
return 0;
}
// 결과
size of num1 & num2: 1, 1
size of num3 & num4: 2, 2
size of char add: 4
size of short add: 4
size of result1 & result2: 1, 2
실수를 표현 및 처리하기 위한 일반적인 자료형의 선택
- 실수 자료형의 선택에 있어서 가장 중요한 요소는 “정밀도"
- 정밀도: 오차가 발생하지 않는 소수점 이하의 자릿수
- 보편적으로 선택하는 자료형: double
- float보다 정밀도가 높다.
- long double보다 부담이 적다.
#include <stdio.h>
int main(void) // int는 입력 형태, void는 출력 형태
{
double rad;
double area;
printf("원의 반지름 입력: ");
scanf("%lf", &rad);
area = rad*rad*3.1415;
printf("원의 넓이: %f \n", area);
return 0; // 0은 운영체제에게 전달되는 데, 정상적인 종료의 상황에서 전달되는 값을 의미
}
// 결과
원의 반지름 입력: 2.4
원의 넓이: 18.095040
양의 정수만 표현하게 하는 unsigned
- 정수 자료형의 이름 앞에만 unsigned를 붙일 수 있음
- unsinged가 붙으면, MSB도 데이터의 크기를 표현하는데 사용
- char는 예외일 수 있음(Default가 unsigned인 경우도 존재)
문자의 표현방식과 문자를 위한 자료형
아스키(ASCII) 코드
- 숫자를 문자에 mapping해 놓은 코드
문자의 표현
- 프로그램상에서의 문자표현에는 작은 따옴표가 사용
#include <stdio.h>
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);
/*
%c 는 문자의 형태로 데이터를 출력(또는 입력)하라 라는 의미
8 ~ 11행을 통해 정수는 출력의 방법에 따라서 문자의 형태로도, 숫자의 형태로도 출력이 가능하다는 것을 알게 됌
아스키 코드는 0 이상 127 이하이다. 따라서 char형 변수로 저장하는 것이 메모리 효율적으로도 좋다.
int형은 연산에 이점이 있지만, 문자열을 연산에 사용하지 않으므로, char형이 더 적합하다.
*/
return 0;
}
// 결과
A 65
A 65
Z 90
Z 90
상수에 대한 이해
- 이름이 있는 상수와 이름이 없는 상수로 나뉨
- 자료형을 근거로 표현
이름을 지니지 않는 리터럴(Literal) 상수
int main(void)
{
int num = 30 + 40 // 30과 40은 상수이다!
/*
단계 1: 정수 30과 40이 메모리 공간에 상수의 형태로 저장된다.
단계 2: 두 상수를 기반으로 덧셈이 진행된다.
단계 3: 덧셈의 결과로 얻어진 정수 70이 변수 num에 저장된다.
이 때, 상수 30과 40이 할당된 메모리 공간에 이름이 없는데 이를 '리터럴 상수' 혹은 '리터럴'이라 한다.
*/
}
리터럴 상수의 자료형
- int형으로 표현 가능한 정수형 상수는 int형으로 저장하기로 약속
- double형으로 표현 가능한 실수형 상수는 double형으로 저장하기로 약속
- 문자형 상수와 같은 경우로는 char 필드로 선언을 하더라도 아스키 코드에 해당 한다면 int형으로 저장된다.
접미사를 이용한 다양한 상수의 표현
int main(void)
{
float num1 = 5.789; // 경고 메세지 발생
float num2 = 3.24 + 5.12; // 경고 메세지 발생
return 0;
}
/*
경고 메세지: 초기화 할 때, double형 데이터를 float형 변수에 저장하였으니, 데이터가 잘려나갈 수 있습니다.
5.789는 8 Byte의 double형 상수이고, 변수 num1은 4 Byte의 float형 변수이므로, 경고 메세지가 나타남.
*/
float num1 = 5.789f; // 경고 메세지 발생 안 함
float num2 = 3.24F + 5.12F; // 대소문자 구분 없음
- 정수형을 위한 접미사
- U: unsigned int
- L: long
- UL: unsigned long
- LL: long long
- ULL: unsigned long long
- 실수형을 위한 접미사
- F: float
- L: long double
이름을 지니는 심볼릭(Symbolic) 상수: const 상수
- 상수의 이름은 모두 대문자로 표시하고, 둘 이상의 단어로 연결할 때에는 _를 이용하는 것이 관례
int main(void)
{
const int MAX=100; // MAX는 상수, 따라서 값의 변경 불가
}
자료형의 변환
- 데이터의 표현 방식을 바꾸는 것
- 자동 형 변환(묵시적 형 변환)
- 강제 형 변환(명시적 형 변환)
대입연산의 전달과정에서 발생하는 자동 형 변환
- 대입 연산자에서 두 피연산자의 자료형이 일치하지 않으면, 왼편에 있는 피연산자를 대상으로 형 변환이 자동으로 일어난다.
double num1 = 245; // int형 정수 245를 double형으로 자동 형 변환 -> 245.0
int num2 = 3.1415; // double형 실수 3.1415를 int형으로 자동 형 변환 -> 3
// 이로 인해 '소수부의 손실'이 발생
int num3 = 129;
char ch = num3; // int형 변수에 num3에 저장된 값이 char형으로 자동 형 변환 -> -127
/*
129가 저장된 변수 num3의 비트 열:
00000000 00000000 00000000 10000001
하지만, char 필드는 1 Byte기 떄문에 변수 ch에 저장하기 위해선 크기를 줄여야 한다.
따라서, 이 경우에는 '상위 Byte의 손실'이 발생하여,
10000001 // 이는 정수로 -127
부호가 바뀌는 결과가 나오게 된다.
*/
- 데이터의 표현범위가 보다 넓은 자료형으로의 형 변환은, 그 과정에서 데이터 손실이 발생하지 않지만, 반대로는 발생할 수 있다.
#include <stdio.h>
int main(void)
{
double num1=245;
int num2=3.1415;
int num3=129;
char ch=num3;
printf("정수 245를 실수로: %f \n", num1);
printf("실수 3.1415를 정수로: %d \n", num2);
printf("큰 정수 129를 작은 정수로: %d \n", ch);
return 0;
}
// 결과
정수 245를 실수로: 245.000000
실수 3.1415를 정수로: 3
큰 정수 129를 작은 정수로: -127
명시적 형 변환: 강제로 일으키는 형 변환
#include <stdio.h>
int main(void)
{
int num1=3, num2=4;
double divResult;
divResult = num1 / num2;
printf("나눗셈 결과: %f \n", divResult);
return 0;
}
// 결과
나눗셈 결과: 0.000000
/*
이같이 나온 이유: 연산결과의 자료형은 피연산자의 자료형과 일치하기 때문에 피연산자인 num1, num2가 int형 이므로
3과 4의 나눗셈의 몫인 0이 double형으로 형 변환되어 divResult에 저장되서 위와 같은 결과가 나오게 되었다.
*/
#include <stdio.h>
int main(void)
{
int num1=3, num2=4;
double divResult;
divResult = (double)num1 / num2; // (double) '형 변환 연산자': 제일 먼저 형 변환 연산이 진행되도록 함
printf("나눗셈 결과: %f \n", divResult);
return 0;
}
// 결과
나눗셈 결과: 0.750000
'C' 카테고리의 다른 글
변수의 존재기간과 접근범위 (0) | 2025.03.12 |
---|---|
조건에 따른 흐름의 분기 (0) | 2025.03.12 |
반복 실행을 명령하는 반복문 (0) | 2025.03.12 |
printf, scanf (3) | 2025.03.12 |
자료형 및 Byte 개념 (0) | 2025.03.12 |