C 언어 자료형
자료형(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
실수를 표현 및 처리하기 위한 일반적인 자료형의 선택
실수 자료형의 선택에 있어서 가장 중요한 요소는 “정밀도"
- 정밀도: 오차가 발생하지 않는 소수점 이하의 자릿수
보편적으로 선택하는 자료형:
doublefloat보다 정밀도가 높다.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 intL:
longUL:
unsigned longLL:
long longULL:
unsigned long long
실수형을 위한 접미사
F:
floatL:
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