자료형(Data Type)

  • 데이터를 표현하는 기준(방법)

기본 자료형

  1. 정수형
    • 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)
  2. 실수형
    • float(4 Byte)
    • double(8 Byte)
    • long double(8 Byte 이상)

많은 수의 자료형을 제공하는 이유

  1. 데이터의 표현방식이 다르기 때문에
  2. 메모리 공간의 적절한 사용을 위해서 다양한 크기의 자료형이 필요

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

+ Recent posts