Programming/C

C언어 - 상수, 자료형

JunsuKim 2021. 9. 14.
728x90

자료형이란?

데이터를 표현하는 기준 -> 변수, 상수 모두 자료형에 근거한다.

위의 사진을 보면 같은 정수 또는 실수 자료형이라도 사용되는 바이트 크기가 클수록 표현할 수 있는 값의 범위가 넓어진다.

 

자료형의 크기가 헷갈릴 때는 sizeof 연산자를 사용하면 된다.

sizeof 연산자 : 메모리 공간에서 소모하는 메모리의 크기를 바이트 단위로 계산해서 반환해주는 연산자로 변수와 상수뿐만 아니라 자료형의 이름도 올 수 있다.

#include<stdio.h>

int main(){
    char c = 9;
    int n = 10;
    double dn = 1.2;
    
    printf("변수 c의 크기 : %d\n", sizeof(c));
    printf("변수 n의 크기 : %d\n", sizeof(n));
    printf("변수 dn의 크기 : %d\n", sizeof(dn));
    
    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));
    return 0;
}

/*출력
변수 c의 크기 : 1
변수 n의 크기 : 4
변수 dn의 크기 : 8;
char 의 크기 : 1
int의 크기 : 4
long의 크기 : 4
long long의 크기 : 8
float의 크기 : 4
double의 크기 : 8
*/

실수에서는 어떠한 자료형을 쓰냐에 따라 정밀도가 달라진다.

정수 자료형에선 int를 보편적으로 사용한다면, 실수 자료형에서는 double을 보편적으로 사용한다. 이는 float보다 정밀도가 높으면서 long double보단 부담이 덜 되기 때문이다.

#include<stido.h>

int main(){
    double radius = 0;
    double area = 0;
    
    printf("원의 반지름 입력 : ");
    scanf("%lf", &radius);
    
    area = radius * radius * 3.1415;
    printf("원의 넓이 : %f", area);
    return 0;
}

/*
원의 반지름 입력 : 2.4
원의 넓이 : 18.095040
*/

unsigned

정수 자료형에 한해서 unsigned 선언을 추가하게 되면, 0 이상의 값만 표현하는 자료형이 된다. 또한 표현할 수 있는 범위가 양의 정수 방향으로 두배 늘어난다.

예를 들어 char형 변수의 앞에 unsigned를 붙여 unsigned char가 되면 표현할 수 있는 범위가 0 이상 +255 이하가 되는 것이다.

  • 정수 자료형의 이름 앞에만 붙일 수 있다.
  • 표현할 수 있는 값이 양의 범위로 두배가 된다.

형 변환

대입 연산의 전달 과정에서 발생하는 자동 형 변환

double num1 = 234;
int num2 = 3.14;

우선 첫행을 보자.

int형 정수인 234를 double형 num1에 대입을 함으로 인해 234는 자동으로 double형으로 형 변환이 된다. 출력을 하게 되면 234.0으로 변환된 것을 확인할 수 있다.

두 번째 행에서는 3.14라는 double형 실수를 in형인 num2에 대입을 한다. double형에서 int형으로 자동 형 변환이 될 때 소수점 뒷자리는 버리고 정수 부분만 가져오게 된다. 따라서 3으로 대입이 된다.

 

정수의 승격(Integral Promotion)에 의한 자동 형 변환

short num1 = 15, num2 = 25;

일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형을 int로 정의한다.

따라서 int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 더 빠르기 때문에 int보다 작은 크기의 정수형 데이터는 int형 데이터로 형 변환이 된다.

 

명시적 형 변환 : 강제로 일으키는 형 변환

#include<stdio.h>

int main(){
    int num1 = 3, num2 = 4;
    double divResult = 0;
    divResult = num1 / num2;
    printf("나눗셈 결과 : %f\n", divResult);
    return 0;
}

// 나눗셈 결과 : 0.000000

3 / 4 = 0.75가 나와야 하지만 정수 / 정수였기 때문에 정수 값이 나오게 되어 0이 출력된 것이다.

이를 해결하기 위해

divResult = (double)num1/num2;

/*
= divResult = 3.0 / num2;
=divResult = 3.0 / 4.0
*/

자료형을 명시하여 강제로 형 변환을 시켜주면 된다.

상수

리터럴(Literal) 상수(이름을 지니지 않은 함수)

int main(){
    int num = 3 + 4;
    ....
}

위 코드에서 3과 4의 합의 결과를 변수 num에 저장한다. 여기서 3과 4는 상수이지만 이를 할당하는 메모리 공간에 이름이 없다. 이를 리터럴(Literal) 상수 또는 리터럴이라고 한다.

 

리터럴 상수의 자료형은 정수로 표현 가능하면 int형으로 메모리 공간에 저장하고, 실수형으로 표현이 가능하면 double형으로 저장하기로 약속되어 있다. char형은 정수형 자료형이기 때문에 아스키코드로 변경되어 4바이트의 크기가 나오게 된다.

#include<stdio.h>

int main(){
    printf("literal int size : %d\n", sizeof(5));
    printf("literal double size : %d\n", sizeof(3.14));
    printf("literal char size : %d\n", sizeof('A'));
    return 0;
}

/*
literal int size : 4
literal double size : 8
literal char size : 4
*/

심볼릭(Symbolic) 상수(이름을 지니는 상수) : const 상수

심볼릭 상수를 표현하는 방법은 변수 선언 시 앞에 const 키워드를 추가하면 된다.

int main(){
    const int MAX = 100; // const를 붙여 MAX가 상수가 되었기 때문에 값 변경이 불가능하다.
    const int PI = 3.1415;
    ....
}

심볼릭 상수는 일단 초기화가 되면 그 값을 변경시킬 수 없고, 선언과 초기화를 분리시킬 수도 없다.

 

* 상수의 이름은 모두 대문자로 표시하고, 둘 이상의 단어로 이루어져 있다면 언더바(_)를 통해 MY_GRADE와 같이 구분하는 것이 관례이다.

접미사를 이용한 다양한 상수의 표현

int main(){
    float num1 = 5.789;
    float num2 = 3.24 + 5.12;
    return 0;
}

위의 코드는 컴파일이 가능하지만 초기화할 때, "double형 데이터를 float형 변수에 저장하여 데이터가 잘려나갈 수 있다."는 경고 메시지도 확인이 될 것이다. 실수형 상수는 double형으로 할당되도록 약속이 돼있기 때문이다.

이를 위해 C언어에서는 접미사를 정의하고 있다.

float num1 = 5.789f
float num2 = 3.24f + 5.12f;

위와 같이 접미사를 붙이면 경고 메시지가 뜨지 않을 것이다. 접미사는 대소문자를 구분하지 않으므로 확인하기 쉽도록 선택하여 쓰면 된다.

728x90

댓글