# Variable properties and types (1/2)

**Contents**

---

**1️⃣** 변수의 속성과 종류 (Variable Properties and Types)  
**2️⃣** 지역 변수 (Local Variable)  
**3️⃣** 전역 변수 (Global Variable)  
**4️⃣** 변수의 생존 기간(Variable Lifetime)  
**5️⃣** 저장 유형 지정자 (Storage Class Specifier)

---

## Summary

**변수의 속성 (Variable Property)**

* **이름(Name)**: 변수의 고유 식별자입니다.
    
* **타입(Type)**: 변수에 저장할 데이터의 종류(예: int, float).
    
* **크기(Size)**: 타입에 따라 필요한 메모리 공간의 크기.
    
* **값(Value)**: 변수에 저장된 실제 데이터.
    
* **범위(Scope)**: 변수가 사용 가능한 범위, **지역 변수(Local Variable)**와 **전역 변수(Global Variable)**로 구분됩니다.
    
* **생존 시간(Lifetime)**: 변수가 메모리에 존재하는 기간.
    
* **연결(Linkage)**: 다른 파일이나 코드에서 접근 가능한지 여부.
    

**변수의 종류 (Variable Type)**

* **지역 변수(Local Variable)**: 함수나 블록 내에서 선언되어 해당 블록 안에서만 접근 가능한 변수입니다. 자동으로 생성 및 소멸되며, 함수가 종료되면 메모리에서 사라집니다.
    
* **전역 변수(Global Variable)**: 함수 외부에서 선언되어 프로그램 전체에서 접근 가능한 변수입니다. 프로그램이 종료될 때까지 메모리에 유지됩니다.
    

**저장 유형 지정자(Storage Class Specifiers)**

* **auto**: 함수 내부에서 자동으로 생성되는 지역 변수.
    
* **static**: 함수 호출이 끝나도 값이 유지되는 정적 변수. 함수 외부에서 선언 시 파일 범위 전역 변수가 됩니다.
    
* **register**: CPU 레지스터에 저장되어 빠르게 접근 가능한 변수.
    
* **volatile**: 최적화를 방지하여, 값이 외부 요인에 의해 변경될 수 있는 변수(하드웨어 연동).
    
* **extern**: 다른 파일에 선언된 전역 변수를 사용할 때 사용.
    

---

## **1️⃣** 변수의 속성과 종류  
(Variable Properties and Types)

변수는 데이터를 저장하는 기본 단위이며, 아래와 같은 주요 속성들로 구성된다.

* **이름(Name)**: 변수의 고유한 이름
    
* **타입(Type)**: 변수에 저장되는 데이터의 종류(예: 정수, 문자 등).
    
* **크기(Size)**: 변수가 차지하는 메모리 공간의 크기.
    
* **값(Value)**: 변수에 저장된 실제 데이터.
    

이와 함께 **범위(Scope)**, **생존 시간(Lifetime)**, **연결(Linkage)** 이라는 중요한 개념도 있다.

* **범위(Scope)**: 변수가 어디서 사용될 수 있는지를 결정한다. 범위는 보통 변수가 선언된 위치에 따라 결정되며, 코드의 특정 영역에서만 변수를 사용할 수 있다. 예를 들어, 함수 내에서 선언된 변수는 그 함수 안에서만 접근할 수 있다.
    
* **생존 시간(Lifetime)**: 메모리에 존재하는 시간을 의미한다. 예를 들어, 함수 내에서 선언된 변수는 함수가 끝날 때 메모리에서 사라진다. 반면, 전역 변수(Global Variable)는 프로그램이 실행되는 동안 메모리에 계속 남아있게 된다.
    
* **연결(Linkage)**: 다른 파일이나 영역에 있는 변수와 연결될 수 있는 상태를 의미한다. 예를 들어, `extern` 키워드를 사용하여 다른 파일에 선언된 변수를 사용할 수 있다.  
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731138322079/fa0f9e49-cec6-480d-b16d-7c4f3e5bcd8f.png align="center")

**<mark>💡 위 그림은 생존시간, 범위, 연결에 대해서 설명하고 있다.</mark>**

* **생존 시간**: 변수 `x`가 생성되고, 그 변수가 메모리에 존재하는 기간을 나타낸다. 생존 시간이 끝나면 변수는 **소멸**되게 된다.
    
* **범위**: 변수 `x`가 접근 가능한 코드 영역을 의미한다. 즉, 특정 블록 안에서만 사용할 수 있는 지역 변수일 수도 있다.
    
* **연결**: 변수 `x`가 다른 영역의 변수와 어떻게 연결되는지 또는 접근 가능한지를 나타낸다.
    

---

### 변수의 속성과 종류 #1 : 범위(Scope in Variable)

**<mark>💡 요약:</mark>** **범위(Scope)**는 그 변수가 사용할 수 있는 영역을 의미한다. **범위(Scope)**에 따라 변수를 **전역 변수(Global Variable)**와 **지역 변수(Local Variable)**로 나눈다.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731138600986/ec6b30e5-da42-4686-b4fc-7083ba535eb7.png align="center")

* **전역 변수(Global Variable)**:
    
    * 프로그램의 어디서든 접근할 수 있다.
        
    * 메모리에서 프로그램이 종료될 때까지 존재한다.
        
    * 주로 여러 함수에서 공통으로 사용해야 하는 데이터에 적합하다.
        
    * 예를 들어, 외부에서 공통으로 접근해야 하는 환경 설정 값 등을 저장할 때 사용한다.
        
* **지역 변수(Local Variable)**:
    
    * 변수가 선언된 함수나 블록 내에서만 접근할 수 있다.
        
    * 해당 함수가 실행을 마치면 메모리에서 사라진다.
        
    * 주로 특정 함수 내부에서만 필요한 임시 데이터를 저장할 때 사용다.
        

---

## **2️⃣** 지역 변수 (Local Variable)

**<mark>💡 요약: </mark>** 특정 **블록(Block)** 내에서 선언되고, 그 블록 내에서만 사용할 수 있는 변수이다. 일반적으로 함수나 반복문 내에서 선언되며, 블록을 벗어나면 접근할 수 없게 된다.  

* **지역 변수(Local Variable)**는 함수 또는 코드 블록(예: `if`, `while`) 안에서 선언되며, 해당 블록이 끝나면 메모리에서 사라지게 된다.
    
* 이 때문에 같은 이름의 지역 변수를 다른 함수나 블록에서도 사용할 수 있다. 각각 독립적으로 존재하므로 서로 간섭하지 않는다.
    
* 지역 변수는 주로 임시적으로 필요한 데이터에 적합하다.
    

```c
#include <stdio.h>

void exampleFunction() {
    int x = 10; // 지역 변수 (Local Variable), exampleFunction 내에서만 유효
    printf("exampleFunction의 x 값: %d\n", x);
}

int main() {
    int x = 5; // 지역 변수 (Local Variable), main 함수 내에서만 유효
    printf("main의 x 값: %d\n", x);
    
    exampleFunction(); // exampleFunction 호출
    // exampleFunction의 x는 main에서 접근할 수 없음
    printf("%d\n", x); // 오류 발생

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731139116988/21fb0097-849a-4789-9814-249ccc4bca57.png align="center")

* `main` 함수와 `exampleFunction` 함수 내에서 각각 이름이 같은 `x` 변수를 선언했지만, 이 둘은 서로 다른 변수이다. 각각의 **지역 변수(Local Variable)**로, 해당 함수 내에서만 사용 가능하다.
    
* `main` 함수의 `x`는 `exampleFunction`에서 접근할 수 없고, 반대로 `exampleFunction`의 `x`도 `main` 함수에서는 접근할 수 없다.
    
* `printf("%d\n", x);` 결과로 10이 아니라 지역변수에 의해 5로 나왔다.
    

---

### 지역 변수 #1: 선언 위치(Local Variable Declaration Location)

**<mark>💡 요약: </mark>** 최신 버전의 C에서는 **블록(Block)** 내의 아무 위치에서나 **지역 변수(Local Variable)**를 선언할 수 있다. 예전에는 블록의 맨 처음에서만 변수를 선언할 수 있었지만, 이제는 블록의 중간에서도 변수를 선언할 수 있게 되어 더 유연한 기능을 제공한다.  

* **지역 변수(Local Variable)**는 일반적으로 함수나 반복문, 조건문과 같은 코드 블록 안에서 선언된다.
    
* 이제는 블록 내의 어디에서든 선언할 수 있기 때문에, 변수를 필요로 하는 시점에 맞춰 선언할 수 있어 코드가 더 명확해진다.
    
* 예를 들어, 반복문 중간에 변수를 선언하고 초기화해야 할 경우, 그 위치에서 바로 선언이 가능해져 코드 작성이 더 편리해졌다.
    

**<mark>💡 예제:</mark>**

```c
cCopy code#include <stdio.h>

int main() {
    int total = 0;
    
    for (int i = 0; i < 5; i++) {
        if (i % 2 == 0) {
            int even = i; // 블록 중간에 선언된 지역 변수 (Local Variable)
            printf("짝수 값: %d\n", even);
            total += even;
        }
    }

    printf("총합: %d\n", total);

    return 0;
}
```

* 이 코드에서는 `for`문 안에 `if` 조건문이 있고, 그 조건문 안에서 `even`이라는 **지역 변수(Local Variable)**가 선언되었다.
    
* `even` 변수는 `if` 블록 내에서만 사용 가능하며, 그 외에서는 접근할 수 없다.
    
* 이처럼 필요한 곳에서 바로 변수를 선언할 수 있어 가독성이 좋고 관리하기도 편리하다.
    

---

### 지역 변수 #2 :  
같은 이름의 지역 변수(Local Variable with Same Name)

**<mark>💡 요약:</mark>**지역 변수(Local Variable)는 블록 내에서만 유효하기 때문에, 서로 다른 블록에서는 같은 이름의 변수를 선언할 수 있다. 이는 각 블록이 독립적인 범위를 갖고 있기 때문이다.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731139543440/9288d534-c026-4761-941e-95ad14727d28.png align="center")

☑️**같은 이름의 지역 변수(Local Variable with Same Name)**:

* 함수나 블록 내부에서 선언된 **지역 변수(Local Variable)**는 해당 블록이 끝나면 소멸하므로, 서로 다른 블록에서는 같은 이름의 변수를 선언해도 된다.
    
* 예를 들어, `main` 함수와 `sub` 함수 각각에 `count`라는 이름의 변수가 있더라도, 이 변수들은 서로 독립적이다.
    

☑️ **독립적인 메모리 공간**:

* `main` 함수의 `count`와 `sub` 함수의 `count`는 서로 다른 메모리 공간을 사용하므로, 한 쪽에서 값을 변경해도 다른 쪽에 영향을 미치지 않는다.
    

```c
#include <stdio.h>

void sub() {
    int count = 20; // sub 함수 내에서만 유효한 지역 변수 (Local Variable)
    printf("sub 함수의 count 값: %d\n", count);
}

int main() {
    int count = 0; // main 함수 내에서만 유효한 지역 변수 (Local Variable)
    printf("main 함수의 count 값: %d\n", count);
    
    sub(); // sub 함수 호출

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731139631414/dbca000f-001a-47e8-b71a-80e798561d5f.png align="center")

* `main` 함수와 `sub` 함수 모두 `count`라는 이름의 변수를 선언하고 있지만, 서로 독립적인 **지역 변수(Local Variable)**로 동작한다.
    
* `main` 함수의 `count`는 `main` 내에서만 사용 가능하고, `sub` 함수의 `count`는 `sub` 함수 내에서만 사용 가능하다.
    
* 결과적으로 `main`의 `count` 값과 `sub`의 `count` 값은 서로 간섭하지 않는다.
    

---

### 지역 변수 #3  
:생존 기간(Lifetime of Local Variables)

**<mark>💡 요약: </mark>** 지역 변수(Local Variable)는 특정 **블록(Block)** 안에서만 존재하며, 그 블록이 끝나면 자동으로 사라지게 된다. 변수의 **생존 기간(Lifetime)**은 그 변수가 메모리에 존재하는 기간을 의미한다.  

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731139678845/a182011a-49bb-4f40-a64f-02a099910b0e.png align="center")

* *지역 변수(Local Variable)*는 일반적으로 함수나 코드 블록 내에서 선언된다.
    
* 해당 블록이 실행될 때 메모리에 생성되며, 블록이 끝나면 자동으로 메모리에서 사라지게된다.
    
* 따라서 블록이 끝나면 변수의 값은 더 이상 접근할 수 없게 되고, 새로운 값을 할당하려면 다시 변수를 선언해야 한다.
    

---

### 지역 변수 #4: 초기값 예(Initialization of Local Variable)

```c
#include <stdio.h>

int main() {
    int i;
    
    for (i = 0; i < 5; i++) {
        int temp = 1; // 지역 변수 (Local Variable), 반복문이 시작될 때마다 초기화
        printf("temp = %d\n", temp);
        temp++;
    }

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731197317329/50443ea6-6425-4ebf-b382-5411a6a47025.png align="center")

* `for` 반복문 안의 `temp`는 반복이 시작될 때마다 `1`로 초기화된다.
    
* `printf`로 `temp`의 값이 출력되며, `temp++`로 인해 값이 `2`가 되지만, 반복이 끝날 때 사라진다.
    
* 그래서 매 반복마다 `temp`는 다시 `1`로 시작하여 같은 값이 출력되게 된다.
    

---

### 지역 변수 #5: 쓰레기 값 (Garbage Value of Local Variables)

**<mark>💡 요약: </mark>** 지역 변수(Local Variable)는 초기화되지 않으면 쓰레기 값(Garbage Value)을 가진다. C 언어에서는 지역 변수를 선언만 하고 값을 초기화하지 않으면, 그 변수에는 이전에 메모리에 남아있던 불확실한 데이터가 저장되게 된다. 따라서 항상 필요한 값으로 **초기화(Initialization)**해주는 것이 좋다.

```c
e#include <stdio.h>

int main() {
    int temp; // 초기화되지 않은 지역 변수 (Local Variable)
    printf("temp = %d\n", temp); // 쓰레기 값 출력 가능

    temp = 0; // 명시적으로 초기화
    printf("초기화된 temp = %d\n", temp);

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731197496827/ccef2889-f82c-4178-8019-f0ccd43c6cd8.png align="center")

* 지역 변수는 선언된 블록 내에서만 존재하고, 초기화되지 않으면 쓰레기 값을 갖게 됨
    
* 쓰레기 값을 갖는 변수는 **<mark> 예측할 수 없는 데이터</mark>**를 담고 있기 때문에, 프로그램의 실행 중에 오류가 발생할 수 있다.
    
* 특히 디버깅 모드에서 이러한 변수를 사용할 때 **런타임 오류(Runtime Error)**가 발생할 수 있다. 이 문제를 피하려면 변수를 선언할 때 초기값을 설정하는 것이 좋다.
    

---

### 지역 변수 #6  
: 함수의 매개 변수 (Function Parameters)

**<mark>💡 요약: </mark>** 함수 헤더 부분에 정의되며, 함수 내에서만 사용 가능한 일종의 **지역 변수(Local Variable)**이다. 즉, 매개 변수도 함수가 실행되는 동안에만 존재하며, 함수가 끝나면 매개변수도 사라지게 된다. 매개 변수는 함수가 호출될 때 전달된 **인수(Argument)** 값으로 **초기화(Initialized)**되게 된다.

```c
#include <stdio.h>

void inc(int counter) { // 매개 변수로 값 전달
    counter++; // counter 값 증가
}

int main() {
    int i = 10;
    printf("함수 호출 전 i = %d\n", i);
    inc(i); // inc 함수 호출, i의 값이 복사되어 전달됨
    printf("함수 호출 후 i = %d\n", i); // i의 값은 여전히 10

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731197823322/853fa6b0-fe8f-4ec9-b364-b3177f7a0ba4.png align="center")

* `inc` 함수는 매개 변수 `counter`를 받아 1 증가시키지만, `counter`는 `i`의 복사본이므로 `i` 자체는 변하지 않는다.
    
* `printf` 출력 결과로 `함수 호출 전 i = 10`과 `함수 호출 후 i = 10`이 출력된다. 이는 값에 의한 호출 방식으로 인해 원래 변수 `i`가 변하지 않음을 보여준다.
    

---

## **3️⃣** 전역 변수 (Global Variable)

**<mark>💡 요약: </mark> 전역 변수(Global Variable)**는 함수 외부에서 선언된 변수로, 프로그램의 모든 함수에서 접근할 수 있다. **전역 변수(Global Variable)**는 프로그램이 실행되는 동안 메모리에 유지되며, 소스 파일 전체에서 사용할 수 있는 범위를 가진다.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731197939187/e4d9c2cc-70b0-41f0-81e1-185dc9fe0de9.png align="center")

* 전역 변수는 함수 외부에서 선언되며, 소스 파일 전체에서 접근할 수 있는 범위를 가진다.
    
* 프로그램이 종료될 때까지 메모리에 유지되므로, 여러 함수에서 데이터 공유가 가능하다.
    
* 하지만 전역 변수를 남발하면 프로그램의 복잡성이 증가하고, 유지보수가 어려워질 수 있다.
    

---

### 전역 변수 #1 : 초기값과 생존 기간  
(Initial Value and Lifetime of Global Variables)

**<mark>💡 요약: </mark>** 전역 변수(Global Variable)는 프로그램이 시작할 때 자동으로 **초기화(Initialized)**되며, 별도로 초기화하지 않으면 `0`으로 설정된다. 전역 변수는 프로그램 전체에서 사용할 수 있으며, 프로그램이 종료될 때까지 메모리에 유지된다.

```c
#include <stdio.h>

int A; // 전역 변수 (Global Variable), 초기값은 0
int B; // 전역 변수 (Global Variable), 초기값은 0

int add() {
    return A + B;
}

int main() {
    int answer;
    A = 5;
    B = 7;
    answer = add(); // 전역 변수 A와 B의 합을 계산
    printf("%d + %d = %d\n", A, B, answer);

    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731198179115/82b69e02-797c-4c47-be5a-e1d2ad6f0b08.png align="center")

* `A`와 `B`는 Global Variable로 프로그램 시작 시 `0`으로 초기화된다.
    
* `main` 함수에서 `A`와 `B`의 값을 각각 `5`와 `7`로 설정한 후, `add` 함수에서 이 두 값을 더하여 반환한다.
    
* 전역 변수는 프로그램 전체에서 접근할 수 있어, `main`과 `add` 함수 모두 `A`와 `B`에 접근하여 사용할 수 있다.
    

---

### 전역 변수 #2: 초기값 (Initial Value of Global Variables)

**<mark>💡 요약: </mark>** 별도로 초기화하지 않아도 **기본값(Default Value)**으로 `0`이 설정된다. 프로그램이 시작될 때 자동으로 초기화되므로, 필요시 추가적인 초기화 코드 없이 사용할 수 있다.

```c
#include <stdio.h>

int counter; // 전역 변수 (Global Variable), 초기값은 자동으로 0

int main(void) {
    printf("counter = %d\n", counter); // 초기값 0 출력
    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731198300359/9d29cc63-9f5f-4b8e-ad7f-c9d0cfc7a956.png align="center")

* `counter`는 함수 외부에 선언된 **전역 변수(Global Variable)**이다.
    
* 이 전역 변수는 초기화하지 않았지만, 컴파일러가 프로그램 시작 시 자동으로 `0`으로 설정한다.
    
* 따라서 `main` 함수에서 `counter`를 출력하면 `0`이 출력된다.
    

---

### 전역 변수 #3 : 사용 (Using Global Variables)

**<mark>💡 요약: </mark>** 아래 코드에서는 `x`라는 **전역 변수(Global Variable)**가 사용되며, `main` 함수와 `sub` 함수에서 공유된다. 전역 변수는 프로그램 전체에서 공유되기 때문에, 함수들 간에 데이터가 유지되며 서로 영향을 미칠 수 있다.

```c
#include <stdio.h>

int x; // 전역 변수 (Global Variable)

void sub() {
    for (x = 0; x < 10; x++) {
        printf("*");
    }
}

int main(void) {
    for (x = 0; x < 10; x++) {
        sub();
    }
    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731198434630/53d725c3-cb87-4e4d-95c2-a5dd3bed8287.png align="center")

* `main` 함수의 `for` 루프는 `sub` 함수를 10번 호출하지만, `sub` 함수에서 `x`가 초기화되어 매번 `0`부터 시작한다.
    
* `sub` 함수 내의 `for` 루프가 `10`번 실행되면서 `*`가 총 `10`개 출력된다.
    

---

### 전역 변수 #4: 사용 (Using Global Variables)

**<mark>💡 요약: </mark> 전역 변수(Global Variable)**는 프로그램 전체에서 공통적으로 사용하는 데이터를 저장하는 데 유용하다. 하지만 모든 데이터가 전역 변수로 선언되어야 하는 것은 아니다. 일부 함수에서만 사용하는 데이터는 전역 변수로 선언하기보다는 **함수의 인수(Arguments)**로 전달하는 것이 좋다.  

* 프로그램 전체에서 공유되어야 하는 데이터는 Global Variable로 선언하여 여러 함수가 접근하도록 할 수 있다.
    
* 하지만 특정 함수에서만 필요한 데이터는 그 함수의 인수(Argument)로 전달하여, 불필요하게 전역 변수를 사용하지 않도록 한다.
    
* 이는 코드의 가독성과 유지보수성을 높이고, 전역 변수로 인한 예기치 않은 오류를 줄이는 데 도움이 되기 때문이다.
    

---

### 전역변수 #5: 같은 이름의 전역 변수와 지역 변수  
(Global and Local Variables with the Same Name)

**<mark>💡 요약: </mark>** C 언어에서는 **전역 변수(Global Variable)**와 **지역 변수(Local Variable)**가 같은 이름으로 선언될 수 있다. 이런 경우, **지역 변수(Local Variable)**가 우선되며, 지역 변수가 선언된 블록 내에서는 전역 변수가 가려져 보이지 않게 된다.

```c
#include <stdio.h>

int sum = 1; // 전역 변수

int main(void) {
    int sum = 0; // 지역 변수
    printf("sum = %d\n", sum); // 출력: sum = 0
    return 0;
}
```

* `int sum = 1;`은 전역 변수로 선언되고, `int main` 함수 안의 `int sum = 0;`은 지역 변수로 선언되었다.
    
* `printf` 함수는 `main` 함수의 지역 변수 `sum`을 출력하여, 결과적으로 `0`이 출력되게 된다.
    

---

## 중간 점검 (MidCheck Point)

범위(Scope)와 생존 기간(Lifetime), 초기값(Initial Value)과 같은 기본 개념을 점검할 수 있는 질문들이다.

* **변수의 범위에는 몇 가지의 종류가 있는가?**
    
    * 변수의 범위는 **전역 변수(Global Variable)**와 **지역 변수(Local Variable)**로 구분된다.
        
* **파일 범위를 가지는 변수는 무엇이라고 하는가?**
    
    * 파일 범위를 가지는 변수는 주로 **전역 변수(Global Variable)**이다. 파일 내의 모든 함수에서 접근할 수 있다.
        
* **블록 범위를 가지는 변수는 무엇이라고 하는가?**
    
    * 블록 범위를 가지는 변수는 **지역 변수(Local Variable)**로, 특정 블록(예: 함수, 조건문 등) 내에서만 유효하다.
        
* **똑같은 이름의 지역 변수가 서로 다른 함수 안에 정의될 수 있는가?**
    
    * 가능하다. 각 함수 내의 지역 변수는 독립적이므로 같은 이름을 사용할 수 있다.
        
* **지역 변수가 선언된 블록이 종료되면 지역 변수는 어떻게 되는가?**
    
    * 지역 변수는 블록이 종료되면 메모리에서 **소멸(Destroyed)**한다.
        
* **지역 변수의 초기값은 얼마인가?**
    
    * 초기화하지 않으면, **쓰레기 값(Garbage Value)**을 가질 수 있다. 초기화가 필요하다.
        
* **함수의 매개 변수도 지역 변수인가?**
    
    * 매개 변수 역시 함수 내에서만 사용 가능한 **지역 변수(Local Variable)**이다.
        
* **전역 변수의 생존 기간과 초기값은?**
    
    * 전역 변수는 프로그램이 시작할 때 생성되고 종료할 때까지 존재한다. 초기값이 설정되지 않으면 **0**으로 자동 초기화된다.
        

---

## **4️⃣** 변수의 생존 기간(Variable Lifetime)

**<mark>💡 요약: </mark>** 변수의 **생존 기간(Lifetime)**은 변수가 메모리에 존재하는 기간을 의미한다. C 언어에서는 변수를 **정적 할당(Static Allocation)**과 **자동 할당(Automatic Allocation)** 방식으로 관리한다.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731219985003/de0c5052-96b0-40ca-8f03-c94f298ed87f.png align="center")

☑️ **정적 할당(Static Allocation)**:

* 전역 변수(Global Variable)와 `static` 키워드로 선언된 변수가 이에 해당한다.
    
* 프로그램이 실행되는 동안 메모리에 유지되며, 프로그램이 종료될 때까지 소멸되지 않습는다.
    
* 예를 들어, `total`이라는 정적 변수는 프로그램이 실행되는 동안 메모리에 계속 남아 있게된다.
    

☑️ **자동 할당(Automatic Allocation)**:

* 함수나 블록 내에서 선언된 일반적인 **지역 변수(Local Variable)**가 이에 해당한다.
    
* 블록이 실행될 때 생성되고, 블록을 벗어나면 메모리에서 소멸된다.
    
* 예를 들어, `sum`이라는 지역 변수는 블록 안에서만 존재하고, 블록이 끝나면 사라지게 된다.
    

### 변수의 생존 기간(Variable Lifetime) #1:  
변수의 생존 기간을 결정하는 요인

**<mark>💡 요약: </mark>** 변수의 **생존 기간(Lifetime)**은 변수의 메모리 상에서 존재하는 기간을 의미한다. 이 생존 기간은 **변수의 선언 위치**와 **저장 유형 지정자(Storage Class Specifier)**에 의해 결정된다.

  
**생존 기간(Lifetime)**: 변수가 메모리에 유지되는 시간이다.

**생존 기간을 결정하는 요소 2가지:**

* **변수의 선언 위치(Location of Declaration)**: 전역 변수인지, 지역 변수인지에 따라 생존 기간이 달라진다.
    
* **저장 유형 지정자(Storage Class Specifier)**: 변수의 저장 방식을 지정하는 키워드로, 변수의 생존 기간과 범위를 설정하는 데 사용된다.
    

---

### **5️⃣** 저장 유형 지정자 (Storage Class Specifier)

변수의 생존 기간과 범위를 설정하는데 사용되는 저장 유형 지정자는 변수의 저장 방식을 지정하는 키워드로 크게 5가지가 있다.  

☑️**auto**

* **예제 유형**: 기본 지역 변수 (Local Variable)
    
* **설명**: `auto`는 지역 변수에 기본으로 지정되므로, 사실상 `auto` 키워드를 명시적으로 사용할 필요는 없다. 예제에서는 단순히 함수 내부에서 선언된 지역 변수를 사용하여, 함수가 종료될 때 변수의 값이 사라지게 된다.
    
* **예제**: 함수 내부에서 `auto` 지역 변수를 선언하여 함수 호출이 끝난 후 메모리에서 사라지는 변수의 생명주기를 설명할 수 있다.
    

☑️**static**

* **예제 유형**: 정적 지역 변수 (**Static local Variable)**
    
* **설명**: `static`으로 선언된 지역 변수는 함수가 종료되어도 값이 유지된다. 예제에서는 같은 함수가 여러 번 호출될 때 `static` 변수의 값이 이전 호출 이후에도 유지되는 것을 볼수있다.
    
* **예제**: 함수가 호출될 때마다 `static` 변수가 증가하도록 설정하고, 값이 매번 유지되는 것을 확인하는 예제를 작성할 수 있다.
    

☑️**register**

* **예제 유형**: 빠른 접근이 필요한 반복문 변수
    
* **설명**: `register`는 CPU 레지스터에 변수를 저장하여 빠르게 접근할 수 있도록 한다. 반복문에서 `register` 변수를 사용하여 성능을 최적화하는 상황을 보여줄 수 있다.
    

☑️ **volatile**

* **예제 유형**: 외부에서 변경될 수 있는 하드웨어 레지스터 또는 플래그 변수 (I/O device)
    
* **설명**: `volatile` 키워드는 외부 요인(예: 하드웨어 인터럽트)에 의해 변경될 수 있는 변수에 사용된다. 예제에서는 외부에서 값이 변경될 수 있는 상황을 모사하여, 변수를 `volatile`로 선언해 최적화를 방지하는 방식으로 작성할 수 있다.  
    

☑️**extern**

* **예제 유형**: 여러 파일 간의 전역 변수(Global Variable) 공유
    
* **설명**: `extern` 키워드는 다른 파일에 선언된 변수를 참조할 때 사용된다. 예제에서는 두 개의 소스 파일을 작성하여, 한 파일에서 전역 변수를 정의하고 다른 파일에서 `extern`을 통해 참조하는 방법을 보여줄 수 있다.
    
* **예제**: `file1.c`에서 전역 변수를 선언하고 초기화하고, `file2.c`에서 이 변수를 `extern`으로 선언하여 두 파일 간에 전역 변수를 공유한다.
    

---

### 저장 유형 지정자 #1 : auto (Storage Class Specifier: auto)

1. 함수 내부에서 변수를 선언할 때, `auto` 키워드를 사용하면 해당 변수가 자동으로 할당된다.
    
2. 지역 변수는 기본적으로 `auto` 속성을 가지므로, 일반적으로 `auto` 키워드를 생략할 수 있다.
    
3. `auto` 변수가 선언된 블록이 끝나면 메모리에서 사라지기 때문에 다른 블록에서 같은 이름의 변수를 선언해도 문제가 발생하지 않게 된다.
    

```c
int main(void) {
    auto int sum = 0; // 지역 변수 sum 선언, auto로 자동 할당됨
    int i = 0;        // auto 키워드를 생략한 기본 지역 변수 선언

    ...
}
```

* `main` 함수 내부에서 `auto int sum = 0;`이라는 코드로 **지역 변수(Local Variable)** `sum`을 선언하고 초기화하고 있다. `auto`는 지역 변수의 기본 저장 유형이므로, `auto`를 생략해도 `sum`은 자동으로 할당된다.
    
* `int i = 0;`는 `i`라는 지역 변수를 선언하며, `auto` 키워드를 생략한 예제이다. `auto`는 기본 저장 유형이기 때문에 생략해도 동일하게 작동하게 된다. 즉, `i`도 자동으로 할당되며 `main` 함수가 실행되는 동안에만 존재하고, 함수가 끝나면 메모리에서 사라진다.
    
* `sum`과 `i`는 **자동 변수(Automatic Variable)**로, `main` 함수가 시작될 때 메모리에 생성되고, 함수가 종료되면 자동으로 소멸된다. 따라서 이 변수들은 `main` 함수 내에서만 유효하며, 함수가 끝나면 사용할 수 없게 된다.
    

### 저장 유형 지정자 #2: static  
(Storage Class Specifier: static)

* **static**을 사용하여 선언된 변수는 함수가 종료되어도 값이 유지된다.
    
* **일반 지역 변수(Local Variable)**는 함수가 호출될 때마다 새로 초기화되지만, **static** 지역 변수는 처음 한 번만 초기화된다.
    
* **static** 변수는 함수가 끝난 후에도 이전 호출의 값을 기억한다.
    

```c
#include <stdio.h>

void sub() {
    static int scount = 0; // static 키워드로 선언된 정적 지역 변수
    int acount = 0;        // 일반 지역 변수

    printf("scount = %d\t", scount); // scount 값을 출력
    printf("acount = %d\n", acount); // acount 값을 출력

    scount++; // scount 값을 증가시킴
    acount++; // acount 값을 증가시킴
}

int main(void) {
    sub(); // 첫 번째 호출
    sub(); // 두 번째 호출
    sub(); // 세 번째 호출
    return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731221533026/26d2c15f-689f-4939-9831-865ff529ca6f.png align="center")

* `sub` 함수에서 `scount`는 **static** 키워드로 선언되어 정적 지역 변수가 된다. 이 변수는 `sub` 함수가 호출될 때마다 초기화되지 않고, 이전에 변경된 값을 계속 유지한다.
    
* `acount`는 일반적인 **지역 변수(Local Variable)**로, `sub` 함수가 호출될 때마다 `0`으로 초기화된다.
    
* `main` 함수에서 `sub` 함수를 세 번 호출한다. 호출할 때마다 다음과 같은 동작이 일어난다.
    
    * 첫 번째 호출: `scount`와 `acount` 모두 `0`으로 시작한다. `scount`는 `1`로, `acount`는 `1`로 증가된다.
        
    * 두 번째 호출: `scount`는 이전 호출에서 증가한 `1`을 유지하고 시작하며, `acount`는 다시 `0`으로 초기화된다. 호출 후 `scount`는 `2`, `acount`는 `1`이 된다.
        
    * 세 번째 호출: `scount`는 이전 호출에서 증가한 `2`를 유지하고 시작하며, `acount`는 다시 `0`으로 초기화된다. 호출 후 `scount`는 `3`, `acount`는 `1`이 된다.
        

---

### 저장 유형 지정자 #2: register  
(Storage Class Specifier: register)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731222045159/123c8103-dace-4f2d-9fcb-143a9ef9f93b.png align="center")

* **register** 키워드는 변수를 CPU 레지스터에 저장하도록 요청한다.
    
* 레지스터에 저장된 변수는 메모리보다 빠르게 접근할 수 있어, 반복문에서 자주 사용하는 변수에 유리하다.
    
* 컴파일러가 반드시 레지스터에 저장하지 않을 수도 있지만, `register`를 사용하면 최적화에 도움을 줄 수 있다.
    

```c
#include <stdio.h>

int sum = 0;
void rego() {
register int i; // register 키워드로 변수 i를 레지스터에 저장 요청
for (i = 0; i < 100; i++) {
    sum += i; //0부터 99까지의 수를 모두 더한 값 계산
}
};

int main(void) {
  rego();
  printf("this is result %d", sum);
  return 0;
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1731221957266/421911c0-56a9-46f9-b9e5-8200eddf8e70.png align="center")

* `register int i;`는 **register** 키워드를 사용하여 변수 `i`를 CPU 레지스터에 저장하도록 요청하였다. 이로 인해 `i`는 메모리에 저장되는 것이 아니라, CPU 레지스터에 저장되어 더 빠르게 접근할 수 있게 된다.
    
* `for` 반복문에서 `i`는 `0`부터 `99`까지 증가하며, 각 단계에서 `sum`에 `i`의 값을 더해간다.
    
* 이 반복문에서 `i`는 반복문을 수행하는 동안 계속해서 사용되므로, `register` 키워드를 사용하여 성능을 최적화하려는 의도가 있다.
    

---

### 저장 유형 지정자 #3: volatile  
(Storage Class Specifier: volatile)

* **volatile**은 하드웨어에 의해 변할 수 있는 변수에 사용된다.
    
* **컴파일러 최적화(Compiler Optimization)**를 방지하여, 변수의 값이 외부에서 변경될 수 있다는 것을 명시한다.
    
* 하드웨어와 연결된 변수에 주로 사용된다.
    

```c
volatile int io_port; // 하드웨어와 연결된 변수로 volatile 지정

void wait(void) {
    io_port = 0;       // io_port를 0으로 설정
    while (io_port != 255) // io_port가 255가 될 때까지 대기
        ;
}
```

* `volatile int io_port;`로 선언된 `io_port` 변수는 **volatile** 키워드를 사용하여, 하드웨어에 의해 값이 변경될 수 있음을 명시하고 있다. 이 변수는 하드웨어 장치와 연결되어 있으므로 외부에서 값을 변경할 수 있다.
    
* `wait` 함수에서 `io_port`를 `0`으로 설정한 뒤, `while` 루프에서 `io_port`가 `255`가 될 때까지 대기한다. 만약 **volatile** 키워드를 사용하지 않았다면, 컴파일러가 `io_port`의 값을 캐시하고 반복적으로 읽어오지 않을 수 있다. **volatile**로 선언하면, 매번 메모리에서 최신 값을 읽어오게 되어, 하드웨어가 값을 변경하면 즉시 반영된다.
    

---

### 중간 점검(MidPoint Check)

* **저장 유형 지정자에는 어떤 것들이 있는가?**
    
    * 저장 유형 지정자는 변수의 생명주기와 범위를 결정하는 키워드이다. 대표적인 저장 유형 지정자에는 **auto**, **static**, **register**, **volatile**, **extern**이 있다.
        
* **지역 변수를 정적 변수로 만들려면 어떤 지정자를 붙여야 하는가?**
    
    * 지역 변수를 정적 변수로 만들려면 **static** 지정자를 사용한다. **static**으로 선언된 지역 변수는 함수가 여러 번 호출되더라도 값이 유지된다.
        
* **변수를 CPU 내부의 레지스터에 저장시키는 지정자는?**
    
    * **register** 지정자를 사용하면 변수를 CPU 레지스터에 저장하도록 요청한다. 반복문에서 자주 사용하는 변수에 사용하면 성능이 향상될 수 있다.
        
* **컴파일러에게 변수가 외부에 선언되어 있다고 알리는 지정자는?**
    
    * **extern** 지정자는 변수가 다른 파일에 선언되어 있음을 컴파일러에 알린다. 다른 파일에서 선언된 전역 변수를 사용할 때 주로 사용된다.
        
* **static 지정자를 변수 앞에 붙이면 무엇을 의미하는가?**
    
    * **static** 지정자는 변수의 생명주기를 프로그램 전체로 설정하게 된다. 함수 내부에서 사용되면 정적 지역 변수(**Static Local Variable)**가 되고, 함수 외부에서 사용되면 파일 범위의 전역 변수(Global Variable)가 된다.
        

---
