Taking baby-developer steps

12. 컴퓨터가 변수를 처리하는 방법 - 프로그램 메모리 주소/전역 변수 / 지역 변수 / 정적 변수 / 레지스터 변수 /함수의 매개변수 처리(값에 의한 전달 / 참조에 의한 전달) 본문

CS 지식/C언어_basic

12. 컴퓨터가 변수를 처리하는 방법 - 프로그램 메모리 주소/전역 변수 / 지역 변수 / 정적 변수 / 레지스터 변수 /함수의 매개변수 처리(값에 의한 전달 / 참조에 의한 전달)

Surin Lee 2021. 3. 26. 20:17

컴퓨터가 변수를 처리하는 방법

C언어에서 다양한 변수를 처리하는 방법을 학습한다. 지역변수, 전역변수, 레지스터 변수등을 학습하며, 특정한 함수에 값을 전달하거나 주소를 전달하는 방법을 이해한다.

 

프로그램 메모리 주소

컴퓨터에서 프로그램이 실행되기 위해서는 프로그램이 메모리에 적재(Load)되야 한다. 당연히 프로그램의 크기를 충당할 수 있을 만큼의 메모리 공간이 있어야 한다. 일반적인 컴퓨터의 운영체제는 메모리 공간을 네 가지로 구분하여 관리하며, 각각의 영역들은 서로 다른 기능들을 가진다.

 

코드 영역 데이터 영역 힙 영역 스택 영역
소스코드 전역 변수
정적 변수
동적 할당 변수 지역 변수
매개 변수

 

먼저 코드 영역에는 한줄 한줄 씩 실행 시킬 수 있는 소스코드가 적재 된다. 데이터 영역엔 전역 변수와 정적 변수가 담겨 있고, 힙 영역엔 곧 학습할 동적 할당 변수를 담는다. 스택 영역에는 함수마다 포함 되어 있는 지역변수나 매개 변수 등이 들어간다.

 

전역변수

전역변수(Global Variable)란 프로그램의 어디서든 접근 가능한 변수를 말한다. 전체를 총괄하는 변수로서, 어떤 부분에서도 접근이 가능하다. main함수가 실행되기도 전에 프로그램의 시작과 동시에 메모리에 할당된다. 프로그램의 크기가 커질 수록 전역변수로 인해 프로그램이 복잡해 질수 있다. 메모리의 데이터(Data) 영역에 적재 된다.

전역 변수의 가장 기본적 사용 방법은 다음과 같다.

#include <stdio.h>

int a = 5; //전역변수 선언 및 초기화

void changeValue(){
	a = 10;
}

int main(void){
	printf("%d\n",a);
    changeValue();
    printf("%d\n",a);
    system('pause');
    return 0;
}

-> 5

     10

a를 main함수 바깥에서 선언되는 전역변수로서 선언했다. 따라서 main함수가 아닌 다른 함수(위의 예제에선 changeValue())에서도 변수에 바로 접근해서 사용할 수 있다.

 

지역변수

지역변수(Local Variable)란 프로그램에서 특정한 블록(Block)에서만 접근할 수 있는 변수를 말한다. 함수가 실행될 때마다 메모리에 할당되어, 함수가 종료되면 메모리에서 해제 된다. 메모리의 스택(Stack)영역에 기록된다.

#include <stdio.h>

int main(void){
    int a = 7;
    if(1){
        int a=5;
    }
    printf("%d\n",a);
    system('pause');
    return 0;
}

-> 7

if 블록 내에서 만들어 진것은 if 블록 내에서만 사용 가능하기 때문에, main함수에서 a 값을 출력할 경우, 7이 출력 된다. 만일 if 함수에서 a값을 선언하는 것이 아니라, main함수와 공통된 a의 값을 바꾸는 식으로 하면, 아웃풋 값이 다음과 같이 달라진다.

#include <stdio.h>

int main(void){
    int a = 7;
    if(1){
        a=5;
    }
    printf("%d\n",a);
    system('pause');
    return 0;
}

-> 5

 

정적변수

정적변수(Static Variable)란, 특정한 블록에서만 접근 할 수 있는 변수이다. 프로그램이 실행될 때 메모리에 할당되어 프로그램이 종료되면 메모리에서 해제된다. 메모리의 데이터(Data)영역에 적재된다. 정적변수는 지역변수와 전역변수의 특징을 모두 가진 변수라고 할 수 있다.

#include <stdio.h>

void process(){
    static int a = 5;
    ++a;
    printf("%d\n", a);
}

int main(void){
    process();
    process();
    process();
    system('pause');
    return 0;
}

-> 6 7 8 (각 출력값은 줄 바꿈으로 구별 된다.)

이때 정적변수로 선언된 a에 대해서,

static int a = 5;

이라고 작성한 코드에 의해, 초기에 프로그램 상에 a가 적재되고, 그 이후에 process()를 호출 할 때마다, 이미 적재 시킨 이 구문은 무시하고 아래 코드가 진행된다.

 

레지스터 변수

레지스터 변수(Register Variable)란 메인 메모리 대신 CPU의 레지스터를 사용하는 변수이다. 레지스터는 매우 한정되어 있으므로, 실제로 레지스터에서 처리될 지는 장담할 수 없다. 레지스터에서 처리할 지는 최종적으로 컴파일러가 결정하기 때문이다. 일반적으로, 메인 메모리 보다 레지스터가 훨씬 CPU에 가까워서 처리속도가 더 빠르다. 따라서 레지스터 변수 사용시, 처리속도가 보다 빠를 것이라는 '기대'를 할 수 있다.

#include <stdio.h>

int main(void){
    register int a = 10, i;
    for (i = 0; i < a ; i++){
        printf("%d", i);
    }
    system('pause');
    return 0;
}

-> 0123456789

 

함수의 매개변수 처리

매개변수는 함수에 어떤 값을 넘겨주기 위해서 사용한다. 함수를 호출할 때 함수에 필요한 데이터를 매개변수로 전달한다. 전달 방식은 다음과 같다.

  1. 값에 의한 전달 방식
  2. 참조에 의한 전달 방식

값에 의한 전달 방식은 단지 '값'을 전달하므로 함수 내에서 변수가 새롭게 생성되는데, 지역 변수라고 이해하면 된다.

참조에 의한 전달 방식은 주소를 전달하므로, 원래의 변수 자체에 접근할 수 있다. 전역 변수에 가까운 개념이다.

 

값에 의한 전달 방식(ADD함수)

ADD 함수로 두개의 값을 넣으면 새롭게 두 변수가 메모리 내에 할당되어 처리 된다. 따라서 원래의 변수의 값에는 영향을 미치지 못한다.

#include <stdio.h>

void add(int a, int b){
    a = a + b;
}

int main(void){
    int a = 7;
    add(a,10);
    printf("%d\n",a);
    system('pause');
    return 0;
}

-> 7

add함수에 들어가는 a는 이 함수의 '매개변수'로서만 존재 한다.

만일, 다음과 같이 add함수에 출력 기능을 추가한다면 합계값을 출력받을 수 있으나, main함수의 a값은 변하지 않고 그대로 7이다.

#include <stdio.h>

void add(int a, int b){
    a = a + b;
    printf("%d\n",a);
}

int main(void){
    int a = 7;
    add(a,10);
    system('pause');
    return 0;
}

-> 17

 

참조에 의한 전달 방식(ADD함수)

참조에 의한 전달 방식은 함수의 매개변수로 값을 전달하는 것이 아니라 변수의 주소(즉, 포인터 값)를 전달한다. 이러한 방식을 이용하면 원래 변수의 값에 접근하여 값을 변경할 수 있다. 참조에 의한 전달 방식은 단지, 매개변수로 '포인터(Pointer)' 변수를 보낼 뿐 딱히 특별한 건 아니다.

 

#include <stdio.h>

void add(int *a){
	*a = *a + 10 ;
}

int main(void){
	int a = 7;
    add(&a);
    printf("%d\n", a);
	system('pause');
	return 0;
}

이 경우, add함수를 정의 할 때 간접 참조 연산자를 이용 했다.(참조에 의한 전달 방식의 가장 큰 특징이다.) 그후, main 함수에서 add함수를 호출할 때 a라는 변수의 주소 값을 넘겨 주었다.('*a = &a'로 초기화를 해준 것이다.)

 

요약

  1. C언어에서는 전역 변수, 지역 변수 등의 다양한 종류의 변수가 사용 된다.
  2. 함수에 데이터를 전달하는 방법은 값에 의한 전달 방식과 참조에 의한 전달 방식(포인터를 사용해 주소를 전달하는 방식)으로 두 가지가 있다. 

 

 

Comments