Core Programming/C for Systems Engineering

C언어 자료형과 변수 완벽 가이드: 데이터 타입 크기부터 정적 변수(static)까지

임베디드 친구 2024. 12. 12. 15:30
반응형

C 언어로 프로그램을 만든다는 것은 결국 '데이터를 가공하고 제어하는 일'이라고 할 수 있습니다. 컴퓨터가 우리가 입력한 데이터를 기억하고 다루려면 메모리라는 공간을 빌려 써야 하는데요. 이때 "이 데이터를 저장하는 데 메모리를 얼마나 쓸 것인가?"를 결정하는 것이 바로 데이터 타입(자료형)이고, 그 데이터를 담는 상자가 바로 변수입니다. C 언어는 하드웨어를 직접 제어하는 만큼 데이터 타입과 변수를 다루는 규칙이 아주 명확하고 엄격합니다. 기초를 단단히 다져두어야 나중에 메모리 낭비나 버그 없는 깔끔한 코드를 짤 수 있으니, 오늘 내용을 집중해서 읽어주세요!

Generated by Gemini AI.

📌 핵심 요약 3줄

  • 메모리를 결정하는 데이터 타입: 자료형(int, char 등)에 따라 컴퓨터가 할당하는 메모리의 크기와 숫자를 해석하는 방식이 달라집니다.
  • 상황에 맞는 변수 선택: 선언 위치에 따라 지역, 전역, 정적(static) 변수로 나뉘며 각각의 생명주기와 접근 범위가 다릅니다.
  • 초기화는 선택이 아닌 필수: 변수를 선언하고 값을 채워두지 않으면 메모리에 남아있던 지저분한 '쓰레기 값' 때문에 프로그램이 오작동할 수 있습니다.

C 언어의 데이터 타입(Data Type) 분류

C 언어의 데이터 타입은 크게 세 가지로 나뉩니다. 가장 기본이 되는 기본 데이터 타입, 이를 묶거나 가공한 파생 데이터 타입(배열, 포인터 등), 그리고 개발자가 직접 이름을 붙여 만드는 사용자 정의 데이터 타입입니다. 이번 글에서는 프로그래밍의 뼈대가 되는 기본형과 사용자 정의형을 집중적으로 살펴보겠습니다.

1. 기본 데이터 타입 한눈에 보기

컴퓨터는 기본적으로 0과 1만 알기 때문에, 우리가 적은 코드가 문자 인지, 정수 인지, 실수 인지 자료형을 통해 명확히 알려주어야 합니다.

데이터 타입 키워드 크기 (Byte) 표현 가능한 값의 범위 주요 용도 및 예시
문자형 char 1 Byte -128 ~ 127 (또는 0 ~ 255) 알파벳 문자 1개 저장

char grade = 'A';
정수형 int 4 Byte -2,147,483,648 ~ 2,147,483,647 소수점 없는 일반 정수

int age = 30;
단정밀도 실수형 float 4 Byte 1.2E-38 ~ 3.4E+38 소수점이 있는 실수 (정밀도 낮음)

float pi = 3.14f;
배정밀도 실수형 double 8 Byte 2.3E-308 ~ 1.7E+308 소수점이 있는 실수 (정밀도 높음)

double e = 2.71828;
  • char 타입 팁: C 언어에서 문자는 내부적으로 아스키코드(ASCII)라는 정수로 저장됩니다. 그래서 아주 작은 범위의 숫자를 저장하는 주머니로 쓰이기도 합니다.
  • float vs double: 실수를 다룰 때 값의 정확도가 중요하다면 float보다는 8바이트짜리 double을 쓰는 것이 기본입니다. float 상수를 대입할 때는 숫자 뒤에 알파벳 f를 꼭 붙여주어야 합니다.

2. 내 입맛대로 만드는 사용자 정의 데이터 타입

기본 자료형 외에도 개발자가 코딩의 가독성을 높이기 위해 새로운 타입을 정의할 수 있습니다.

  • typedef: 기존의 긴 자료형 이름을 내가 원하는 짧고 직관적인 이름으로 바꾸어 줍니다.
  • C
     
    typedef unsigned int uint; // 이제 'unsigned int' 대신 'uint'만 써도 됩니다!
    uint score = 100;
    
  • enum (열거형): 연속된 정수 상수에 이름을 붙여서 코드를 읽기 쉽게 만들어 줍니다.
C
 
  enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }; // 순서대로 0, 1, 2, 3...의 값을 가집니다.
  enum Day today = WED; // today 변수에는 2가 저장됩니다.

데이터를 담는 그릇, 변수(Variable)

변수는 데이터를 저장하기 위해 이름을 붙여놓은 메모리 공간입니다. 변수를 만들 때는 반드시 앞에 어떤 종류의 데이터를 담을지 '데이터 타입'을 먼저 적어주어야 합니다.

1. 변수의 선언과 초기화

변수를 선언하는 것은 메모리에 자리를 선점하는 것이고, 초기화는 그 자리에 처음으로 깨끗한 값을 집어넣는 과정입니다.

C
 
int number;      // 변수 선언 (메모리에 int 크기만큼 자리만 잡음)
number = 10;     // 변수 대입 (선언된 자리에 10을 집어넣음)

float average = 5.75f; // 선언과 동시에 초기화 (가장 추천하는 방식!)

변수를 선언만 하고 초기화하지 않으면, 그 공간에는 이전에 다른 프로그램이 쓰다 버린 무작위의 데이터인 쓰레기 값(Garbage Value)이 들어가 있습니다. 이 상태로 계산을 해버리면 엉뚱한 결과가 나오므로 변수는 항상 선언과 동시에 초기화하는 습관을 들이는 것이 좋습니다.


변수의 사용 범위와 생명주기 (Scope & Lifetime)

변수는 "어디서 선언되느냐"에 따라 활동할 수 있는 무대(범위)와 메모리에 살아있는 시간(생명주기)이 완전히 달라집니다. 이 개념을 잘 알아두셔야 변수 이름이 겹쳐서 생기는 버그를 막을 수 있습니다.

변수 종류 선언 위치 접근 가능한 범위 (Scope) 메모리 생명주기 (Lifetime)
지역 변수 (Local) 함수 내부 선언된 함수나 중괄호 { } 블록 안에서만 가능 함수가 호출될 때 태어나고, 함수가 끝나면 소멸
전역 변수 (Global) 함수 외부 프로그램 내부의 모든 함수에서 접근 가능 프로그램이 시작될 때 태어나고, 프로그램이 꺼질 때 소멸
정적 변수 (Static) 함수 내부 선언된 함수 내부에서만 접근 가능 프로그램 시작 시 태어나서 끝날 때까지 값을 계속 유지

💻 코드로 보는 변수들의 실제 작동 방식

세 가지 변수의 차이점을 명확히 보여주는 예제 코드입니다.

C
 
#include <stdio.h>

int global_var = 100; // 1. 전역 변수: 프로그램 어디서나 사용 가능

void counter() {
    int local_var = 0;       // 2. 지역 변수: 함수가 호출될 때마다 0으로 새로 리셋됨
    static int static_var = 0; // 3. 정적 변수: 함수가 끝나도 죽지 않고 이전 값을 기억함

    local_var++;
    static_var++;

    printf("지역 변수: %d | 정적 변수: %d\n", local_var, static_var);
}

int main() {
    printf("전역 변수 호출: %d\n", global_var);
    
    printf("--- 첫 번째 함수 호출 ---\n");
    counter();
    
    printf("--- 두 번째 함수 호출 ---\n");
    counter();
    
    printf("--- 세 번째 함수 호출 ---\n");
    counter();

    return 0;
}

📉 실행 결과

Plaintext
 
전역 변수 호출: 100
--- 첫 번째 함수 호출 ---
지역 변수: 1 | 정적 변수: 1
--- 두 번째 함수 호출 ---
지역 변수: 1 | 정적 변수: 2
--- 세 번째 함수 호출 ---
지역 변수: 1 | 정적 변수: 3
  • 결과 해석: 지역 변수 local_var는 함수가 끝나면 사라지기 때문에 부를 때마다 항상 1이 되지만, 정적 변수 static_var는 메모리에 살아남아 값이 1씩 계속 누적되는 것을 볼 수 있습니다.

💡 C 언어 개발을 위한 꿀팁 (Tip)

  1. 변수 이름은 의미 있게 지으세요: int a, b, c; 처럼 지으면 나중에 이 변수가 무엇을 하는지 본인도 잊어버립니다. int user_age;, float total_score; 처럼 역할을 명확히 알 수 있는 이름을 쓰세요.
  2. 전역 변수 사용은 최소한으로 줄이세요: 프로그램 전체에서 아무나 바꿀 수 있는 전역 변수가 많아지면, 어디서 값이 꼬였는지 찾기가 매우 힘들어집니다. 가급적 지역 변수를 사용하고 함수 매개변수로 값을 넘겨주는 것이 안전합니다.
  3. 정적 변수(static)는 상태 기억에 딱입니다: 함수가 실행된 횟수나, 이전 단계의 작업 상태를 보관해야 할 때 전역 변수를 쓰지 말고 함수 내부에 static 변수를 선언해 보세요. 데이터 오염을 막는 훌륭한 캡슐화 기법이 됩니다.

⚠️ 초보자가 흔히 하는 실수 (Mistakes)

  • 초기화 없는 변수로 연산하기: 앞서 말씀드렸듯 int sum; sum = sum + 10; 처럼 초기화하지 않은 상태에서 연산을 시도하면 쓰레기 값에 10이 더해져 수십억 단위의 엉뚱한 숫자가 나올 수 있습니다. 항상 int sum = 0;으로 시작하세요.
  • 자료형의 범위를 넘어서는 '오버플로우': 1바이트짜리 char 변수에 300이라는 숫자를 넣으려고 하면, 방이 넘쳐서 엉뚱한 숫자로 변해버립니다. 다루고자 하는 데이터의 최댓값을 고려해서 int나 long long 같은 넉넉한 자료형을 선택해야 합니다.
  • 블록 밖에서 지역 변수 호출하기: if 문이나 for 문 내부에서 선언한 변수를 블록 외부에서 출력하려고 하면 컴파일러는 "그런 변수는 모른다"며 에러를 뿜어냅니다. 변수의 유효 주소(Scope)를 늘 의식하며 코딩해 주세요.

🔚 마무리하며

오늘 다룬 데이터 타입과 변수의 개념은 메모리를 효율적으로 쪼개 쓰는 C 언어의 핵심 철학을 담고 있습니다. 내가 만든 변수가 컴퓨터 메모리의 어디쯤에, 얼마나 큰 자리를 차지하고, 언제 사라지는지 머릿속으로 그려보면서 코딩하는 습관을 지니면 실력이 정말 빠르게 늘어날 것입니다.

공부하시다 막히는 부분이 있다면 언제든 댓글로 질문을 던져주세요!

반응형