전공/C

[C 언어] 함수와 변수

BBungyaLog 2022. 9. 27. 23:26

# 변수의 속성

- 범위(scope)

'어떤 범위에서 사용이 가능한가?'이다. 범위는 가시성(visibility)라고도 한다. 범위 속성은 주로 변수가 정의되는 위치에 따라서 결정된다.

 

- 생존 시간(linkage)

'변수가 메모리 상에 얼마나 오랫동안 존재하는지'를 뜻한다.

 

- 연결(linkage)

'서로 다른 영역에 있는 변수를 연결하는데 쓰이는 속성'이다.

 

# 지역변수

- 지역변수(local variable)

함수 또는 블록 안에서 정의되는 변수

int main(void)
{
 	int x = 3;
}

지역변수는 블록 안에서 선언되는 변수이다. 블록이란 중괄호로 둘러싸인 영역이다. 함수의 몸체, 반복문 안 등...

지역변수는 변수가 선언된 블록 안에서만 접근과 사용이 가능하다. 블록이 다르면 이름이 같아도 다른 변수로 취급한다.

 

- 지역변수의 생존 시간

전역변수는 프로그램이 시작되기 전에 만들어지고 프로그램이 끝날 때까지 존재한다. 그러나 지역변수는 변수가 선언된 블록이 시작할 때 시스템 스택(stack)이라 불리는 메모리 공간에 만들어지며 동시에 초기화된다. 지역변수에 할당된 메모리 공간은 블록 끝에서 반환 된다. 즉 선언된 블록이 끝나면 자동으로 소멸된다.

 

예제>>

#include <stdio.h>

int main(void)
{
    int i;
    
    for (i = 0; i < 5; i++) {
    	int temp = 1;
        printf("%d\n", temp);
    }
}

for문 안에 선언된 지역변수 temp는 for문이 끝나면 사라진다.

 

- 지역변수의 초기 값

지역변수의 초기 값을 정해주지 않았다면 의미 없는 값이 들어가 있는데 이러한 값을 쓰레기 값(garbage value)이라고한다. 

 

- 함수의 매개변수

 함수의 헤더 부분에 정의되어 있는 매개변수도 일종의 지역변수이다. 다만 다른 점은 함수 호출 시의 인수 값으로 초기화되어있다는 점이다. 

# 전역변수

- 전역변수(global variable)

함수의 외부에서 선언되는 함수

int x;

int main(void)
{
	...
}

 

- 전역변수의 초기 값과 생존 기간

프로그래머가 전역 변수를 초기화하지 않으면 컴파일러에 의해 0으로 초기화된다.

#include <stdio.h>

int num;

int main(void)
{
    printf("num = %d\n", num);
    return 0;
}

실행 결과 >>

 

- 전역변수의 사용

스파게티 코드 : 전역변수들로 인해 코드가 꼬이는 현상

어디서나 접근 가능하다는 것이 장점이자 단점. 따라서 전역변수로 데이터 교환을 하기보다는 잘 정의된 인터페이스를 통해 데이터를 교환하는 편이 낫다.

모듈화 프로그래밍 : 특정 작업을 수행하는 독립된 모듈로 분리하는 것

모듈화 프로그래밍에서 각각의 모듈들은 독립적이어야 한다. 독립적이란 의미 -> 함수는 자신의 작업에 필요한 데이터와 코드를 모두 포함하여야 한다는 뜻. 그러나 전역변수를 사용하면 모듈 밖의 데이터를 사용하게 되어 각 모듈의 독립성을 위반하게 된다.

그러나 상황에 따라서 효율성을 위해 전역변수를 사용하기도 한다.

  • 거의 모든 함수에서 사용하는 공통적인 데이터는 전역변수로 할 수 있다.
  • 일부의 함수들만 사용하는 데이터는 전역변수로 하지 말고 함수의 인수로 전달한다.

 

# 정적 할당 & 자동 할당

- 정적 할당(static allocation)

프로그램이 실행되는 동안에는 계속하여서 변수에 저장 공간이 할당되어 있는 방법

 

- 자동 할당(automatic allocation)

블록이 시작되면서 변수에 저장 공간이 할당되고 블록이 종료되면 저장 공간이 회수되는 방법

 

- 변수의 생존 시간이 결정되는 요인

   1. 변수가 선언되는 위치

전역변수 - 정적 할당

지역변수 - 자동 할당, 앞에 저장 유형 지정자를 붙이면 정적 할당으로도 가능 

 

   2. 저장 유형 지정자(storage class specifier)

auto 지정자

함수나 블록 내에 선언되는 지역변수는 기본적으로 자동 할당이 된다. "자동"이라고 하는 이유는 변수를 선언한 위치에서 생성되고 블록을 벗어나면서 자동으로 소멸되기 때문이다. 자동 변수로 선언하려면 원칙적으로 auto 키워드를 붙여야한다. 그러나 함수나 블록 안 변수는 키워드를 안붙여도 자동 할당.

 

static 지정자

블록을 벗어나도 자동으로 제거되지 않는 변수 지정

 

예제>>

#include <stdio.h>

void f()
{
    static int a = 0;
    int b = 0;
    printf("a = %d\t", a);
    printf("b = %d\n", b);
    a++;
    b++;
}

int main(void)
{
    f();
    f();
    f();
    return 0;
}

실행 결과>>

register 지정자

레지스터 : CPU의 일부분, CPU만 사용 -> 데이터를 읽고 쓰는 속도가 매우 빠르다.

 

volatile 지정자

하드웨어가 변수의 값을 수시로 변경하는 경우에 사용

 

# 연결

전역변수만이 연결을 가질 수 있다.

- 외부 연결

여러 개의 소스 파일로 이루어져 있는 경우. extern 키워드를 붙여 사용. 

 

- 내부 연결

전역변수 앞에 static이 붙으면 내부 연결이 된다. 즉 하나의 소스 파일 안에서만 사용 가능하다.

 

 

<참고 서적>쉽게 풀어 쓴 C언어 EXPRESS