컴퓨터 공부/© C

[C언어] 10. 컴퓨터가 변수를 처리하는 방법

letzgorats 2021. 2. 14. 02:40

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

 

<프로그램 메모리 주>

 

- 컴퓨터에서 프로그램이 실행되기 위해서는 프로그램이 메모리에 적재(load)되야 한다.

- 프로그램의 크기를 충당 할 수 있을 만큼의 메모리 공간(4기가 ,8기가 ,16기가 등등)이 있어야하는데, 일반적인 컴퓨터의 운영체제는 메모리 공간을 네 가지로 구분하여 관리한다.

코드 영역

    데이터 영역

      힙 영역

      스택 영역

소스 코드

     전역 변수

     정적 변수

   동적 할당 변수

      지역 변수

      매개 변수

(함수마다포함하고음)

 

<전역 변수(Global Variable)>

 

- 프로그램의 어디서든 접근 가능한 변수(전체-Global)

- main 함수가 실행되기도 프로그램의 시작과 동시에 메모리에 할당

- 프로그램의 크기가 커질수록 전역 변수로 인해 프로그램이 복잡해 질 수 있다.

- 메모리의 데이터(Data)영역에 적재된다.

 

(예제1) 전역변수

#include <stdio.h>

int a = 5;

int changeValue() {
        a = 10;
}

void main(void) {

        printf("%d\n",a);

        changeValue();

        printf("%d\n",a);

        system("pause");

        return 0;
}

(해설) 전역변수 같은 경우는 main함수 밖에서 선언이 되는데, 전역변수 이기 때문에 이렇게 main함수가 아닌 다른 함수에서도 바로 접근해서 사용할 수 있는 것이다. 우선, int a=5 로 전역변수 a를 만들어 주었고 changeValue라는 함수에서 해당 a라는 변수의 값을 10으로 바꾸도록 만들었다. pritf문을 통해서는 a5가 출력되는 것을 확인 할 수 있지만 changeValue()를 불러온 이후의 printf문에서는 변경된 a값인 10이 출력된다.

, 전역변수이기 때문에 특정한 변수를 다른 함수(changeValue), 어디에서든 간에 접근할 수 있게 된다는 것이다.

 

<지역변수(Local Variable)>

 

- 프로그램에서 특정한 블록(Block)에서만 접근할 수 있는 변수를 말한다.

- 함수가 실행될 때마다 메모리에 할당되어 함수가 종료되면 메모리에서 해제된다.

- 메모리의 스택(Stack)영역에 기록된다.

 

(예제2)지역변수

#include <stdio.h>

void main(void) {

        int a = 7;

        if (1) {
                int a = 5;
        }

        printf("%d\n",a);

        system("pause");

        return 0;
}

(해설) main 함수 안에서 int a=7 로 선언해주었고, if(1) 안에다 int a= 5 를 써주었다. printf문을 통해 출력해보면 a7이 나온다. 기본적으로 이렇게 블록(Block)안에서 초기화가 된 변수들은 전부 다 지역 변수라고 말할 수 있다. 위 예제에서는 블록이 총 2개인데, 1개는 main함수에 대한 블록{}, 1개는 if 문에 대한 블록{}이 있다.

 즉, int a=5 처럼 if블록 안에서 만들어진 것은 if안에서만 사용할 수 있는 것이다. 그렇기 때문에 if문 바깥쪽 블록에 있는 printf문의 a는 출력이 될 때 똑같이 if문 바깥쪽에서 선언된 int a=7 을 받아서 출력하는 것이다.

 만약에 공통적인 a 변수를 쓰고 싶다면 int a=5 가 아니라 그냥 a=5로 넣어주면 결과적으로 a라는 값이 5가 되어서 5 가 출력 되는 것을 확인 할 수 있다.

 

<정적 변수(Static Variable)>

 

- 특정한 블록에서만 접근할 수 있는 변수(전역변수와 지역변수의 특징을 모두 가진다고 할 수 있다.)  

- 프로그램이 실행될 때 메모리에 할당되어 프로그램이 종료되면 메모리에서 해제된다.

- 메모리의 데이터(Data) 영역에 적재된다.

 

(예제3) 정적변수

#include <stdio.h>

void process() {

        static int a = 5;

        a = a + 1;

        printf("%d\n",a);

}

int main(void) {

        process();
        process();
        process();

        system("pause");

        return 0;
}

(해설) main함수 밖에서 void process()함수를 불러와 그 안에 static 형태로 int a=5 를 선언해준다. 이로써 프로그램이 실행됨과 동시에 메모리상에 a값이 적재가 되는 것이다. 그리고 이제 process()함수를 불러올 때마다 a1을 더하게 되는 것이다. 그 다음 이제 더해진 a값을 출력할 수 있도록 printf문을 적는 것이다. main함수 안에서는 process()함수를 세번 불러 와보자. process()함수를 불러올 때 마다 이미 적재된 a에서 a1씩 증가하기 때문에 6,7,8이 차례대로 나오는 것을 확인 할 수 있다.

 

<레지스터 변수(Register Variable)>

 

- 메인 메모리 대신 CPU의 레지스터를 사용하는 변수

- 레지스터는 매우 한정되어 있으므로 실제로 레지스터에서 처리될 지는 장담할 수 없다.

(레지스터는 프로세서가 바로 사용할 수 있는 데이터를 담고 있는 영역)

 

(예제4)레지스터 변수

#include <stdio.h>

void main(void) {

        register int a = 10,i;

        for (i = 0; i < a; i++){

        printf("%d\n",i);

}
        system("pause");
        return 0;
}

(해설) main함수 안에서 register int a= 10,i를 선언 해주고 for문을 이용해 i 0부터 하나씩 증가하면서 i a보다 작을 때까지 i를 출력하라고 만들어주고 printf문을 통해 i를 출력하면 0,1,2,3,4,5,6,7,8,9까지 차례대로 출력되어 나온다. 레지스터 변수를 사용했기 때문에 일반적인 변수를 사용했을 때보다 더 빠르게 처리가 될 것이라는 기대를 할 수 있는 것이다.

 

 

<함수의 매개변수가 처리될 때>

 

1) 함수를 호출할 때 함수에 필요한 데이터를 매개변수로 전달한다.

2) 전달 방식은 <값에 의한 전달><참조에 의한 전달> 방식이 있다.

3) 값에 의한 전달 방식은 단지 을 전달하므로 함수 내에서 변수가 새롭게 생성 ex) 지역변수

4) 참조에 의한 전달 방식주소를 전달하므로 원래의 변수 자체에 접근 가능 ex) 전역변수

 

<값에 의한 전달 방식 (add함수)>

- add함수로 두개의 값을 넣으면 새롭게 두 변수가 메모리 내에 할당되어 처리된다.

- 원래 변수의 값에는 영향을 미치지 못한다.

 

(예제5)값에 의한 전달 방식

#include <stdio.h>

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

void main(void) {

        int a = 7;

        add(a, 10);

        printf("%d\n",a);

        system("pause");

        return 0;
}

(해설) main 함수 밖에서 void add()함수를 불러와 각 매개변수에 int a, int b 를 선언해주고, a= a+b라고 초기화를 시켜준다. main함수 안에서 int a=7 이고 add(a,10)add함수를 불러주되 b인자에 10을 넣어주고 printf문을 통해 출력해보면 17이 아닌 7이 나오는 것을 확인 할 수 있다.

 즉, 함수가 처리가 되었음에도 불구하고 그대로 a값에는 7이 담겨져 있다는 뜻인데, 이제 이것은 값에 의한 전달방식을 사용했기 때문이다. add(a,10)처럼 함수로 넘겨준 매개변수함수 안에서만 사용되는 함수 전용 변수이기 때문에 원래 기존에 존재했던 a(int a=7)라는 변수에는 값의 영향을 미칠 수가 없다는 것이다. 그렇기 때문에 add함수를 불러와도 기본적으로 함수가 종료되면 a라는 변수는 그대로 7이기 때문에 값으로 7을 가지고 있어서 그대로 7이 출력이 되는 것이다. 만약 printf(%d\n,a)add함수 블록 안에 있다면 a17이라는 값을 출력 할 수 있었을 것이다.

 

<참조에 의한 전달 방식(add함수)>

- 함수의 매개변수로 값을 전달하는 것이 아니라 변수의 주소(포인터 값)를 전달

- 원래 변수의 값에 접근하여 값을 변경할 수 있다.

 

(예제6)참조에 의한 전달 방식(add함수)

#include <stdio.h>

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

void main(void) {

        int a = 7;

        add(&a);

        printf("%d\n",a);

        system("pause");

        return 0;
}

(해설) add함수를 불러와 매개변수로 포인터를 이용해 int *a로 주소를 불러들이고, 그 주소값 자체에다가 10을 더해주는 *a=(*a)+10을 선언해준다. main함수안에서 int a=7이라고 하고 add함수를 불러오되 인자로 (&a)라고 해주고 printf문을 통해 출력시켜보면 17이 나오는 것을 확인 할 수 있다. 참조에 의한 전달 방식은 값에 의한 전달 방식과는 다르게 포인터를 이용해 주소를 전달하기 때문에 이러한 방식으로 접근하면 원래의 변수의 값도 변경할 수 있다.

-참조에 의한 전달 방식(*)은 단지 매개변수로 포인터변수를 보낼 뿐 딱히 특별한게 아니다.

 

(정리)

1)   C언어에서는 전역 변수, 지역 변수 등의 다양한 종류의 변수가 사용된다.

2)   함수에 데이터를 전달하는 방법은 을 전달하는 방식주소를 전달하는 방식 두가지가 있다.

반응형

'컴퓨터 공부 > © C' 카테고리의 다른 글

[C언어] 12. 동적 메모리 할당  (0) 2021.02.14
[C언어] 11. 다차원 배열과 포인터 배열  (0) 2021.02.14
[C언어] 9. 문자열  (0) 2021.02.13
[C언어] 8. 문자  (0) 2021.02.13
[C언어] 7. 포인터  (0) 2021.01.28