[C] 기억 클래스

728x90

1. 매개변수 사이의 자료전달 방법

1) 값의 의한 자료전달

기본적인 자료전달 방법이며, 실매개변수와 형식매개변수 사이에 값을 전달합니다. 

그러나 호출한 함수의 실행이 끝난 다음 전달받은 값을 리턴받지는 못합니다.

 

예제)

#include <stdio.h>
void swap(int x, int y);
void main() {
 int a = 3, b=5;
  printf("호출전 a = %d, b= %d\n", a, b); //출력: 호출전 a = 3, b= 5
  swap(a,b); // 함수 호출(실 매개변수)
  printf("호출후 a = %d, b= %d\n", a, b); //출력: 호출후 a = 5, b= 3

}
void swap(int x, int y){ // 함수정의(형식 매개변수)
  int temp;
  temp = x;
  x = y;
  y = temp;
  printf("함수내 x = %d, y = %d\n", x, y); // 출력: 함수내 x = 5, y = 3
}

2) 참조에 의한 자료전달

호출함수와 피 호출함수의 매개변수 값을 서로 교환할 수 있는 자료전달 방법입니다.

이 방법은 실제로 값을 전달한다기 보다는 실매개변수의 값이 들어있는 주소값을 전달합니다.

 

예제)

#include <stdio.h>
void swap(int *x, int *y);
void main() {
 int a = 3, b=5;
  printf("호출전 a = %d, b= %d\n", a, b); //출력: 호출전 a = 3, b= 5
  swap(&a,&b); // 주소값을 전달하기 위해 실 매개변수 앞에 주소연산자 &를 붙임
  printf("호출후 a = %d, b= %d\n", a, b); //출력: 호출후 a = 5, b= 3
}


void swap(int *x, int *y){ // 주소값을 전달받기 위해 포인터변수 int *x, int *y를 선언
  int temp;
  temp = *x;
  *x = *y;
  *y = temp;
  printf("함수내 x = %d, y = %d\n", *x, *y); // 출력: 함수내 x = 5, y = 3
}

 

위 두가지 자료전달 방법의 차이는 실매개변수의 값이 변화유무입니다. 

값에의한 자료전달은 실 매개변수가 변하지 않지만 참조에 의한 자료전달은 실 매개변수가 변할 수 있습니다.

 

2. 기억 클래스

기억클래스란 변수를 기억공간의 특정영역에 할당하는 방법입니다. 즉, 각 변수의 유효범위와 존속기간이 존재하기 때문에 어떠한 기억클래스를 사용하느냐에 따라 유효범위와 존속기간을 설정할 수 있습니다.

 

1) 변수의 사용위치에 따라

1] 지역변수

특정범위내에서만 통용되는 변수입니다. 즉 선언된 블록이나 함수내에서만 사용가능하며, 예로는 함수에서 사용되는 매개변수 등입니다.

2] 전역변수

함수밖이나 외부파일에서 선언되어 프로그램 전체에 걸쳐 사용할 수 는 변수입니다. 참고로 전역변수는 초기화를 하지 않으면 자동으로 0으로 초기화 됩니다.

 

2) 변수의 존속기간에 따라

기억클래스를 이용한 변수 선언방법은 아래와 같습니다.

형식 :  기억클래스 자료형 변수명;

기능 :  기존의 변수선언문에 기억클래스만 기입
        선언된 변수에 저장된 자료는 해당 기억영역에 놓이게 됨
        

사용 예 : auto int a; //자동변수
         static int b; // 정적변수
         extern int c; //외부변수
         register int d; // 레지스터변수

1]자동변수

함수 실행 시 만들어지고 실행이 끝나면 기억공간이 제거됩니다. 예약어 auto를 사용하는데 auto는 생략이 가능합니다.

이 통용범위는 변수가 선언된 블록이나 함수내로 한정됩니다. 즉 지역변수입니다.

그리고 자동변수는 반드시 초기화를 해야합니다.

 

예제)

#include <stdio.h>
void main() {

  int i = 1;
  auto int j = 2;
  { //블록1
    int i =3; // 자동변수로서 블록1에서만 사용가능
    { //블록2
      int i =4; //자동변수로서 블록2에서만 사용가능
      printf("블록2의 i=%d\n",i); //출력: 블록2의 i=4
      printf("블록2의 j=%d\n",j); //출력: 블록2의 j=2
    }
    printf("블록1의 i=%d\n",i); //출력: 블록1의 i=3
  }
  printf("메인함수내의 i=%d\n",i); //출력: 메인함수내의 i=1
}

위 예제에서 변수 i의 값이 계속 바뀌는 것을 확인할 수 있습니다. 그 이유는 선언함수가 다르면 변수 이름이 같아도 서로 다른 변수를 의미하게 되며 작은 범위의 변수를 우선하게 됩니다.

2]정적변수

기억영역이 프로그램이 끝날때까지 유지됩니다. 예약어는 static을 사용하며 전역변수에 해당합니다.

따라서 변수의 값은 프로그램 실행중에는 계속 유지가 되며 초기화를 하지 않았다면 0으로 초기화됩니다.

예제1)

#include <stdio.h>
void main() {

  int a = 10;
  static int b = 20;
  {
    int a = 5; //자동변수이기 때문에 이 블록을 벗어나면 다시 10으로 되돌아옴
    printf("a = %d, b = %d\n",a,b);  //출력: a = 5, b = 20  
  }
  printf("a = %d, b = %d\n",a,b); //출력: a = 10, b = 20
}

 

예제2)

#include <stdio.h>
test();
void main() {
  int i;
  i=0;
  while(i<3){
    test();
    i++;
  }
  //처음 출력: auto = 0, static = 0
  //두번째 출력: auto = 0, static = 1
  //세번째 출력: auo = 0, static = 2
   
}
test(){
  auto int a = 0;
  static int s = 0;
  printf("auto = %d, static = %d\n", a, s);
  ++a;
  ++s;
}

 

위에서 자동변수인 a는 값이 계속 0이지만 s는 값이 계속 변하는 이유는 자동변수는 호출할때마다 값이 초기화되지만, 정적변수는 함수를 빠져나가더라도 프로그램이 종료되지않았기 때문에 값을 유지합니다. 즉 처음한번만 초기화합니다.

따라서 s의 값은 계속 변하게 됩니다.

3]외부변수

함수의 외부에서 선언하며 예약어는 extern을 사용합니다. 그리고 전역변수이며 초기화를 하지않았다면 0으로 초기화합니다.

외부 변수의 특징으로는 다른 파일에서 외부변수로 선언된 변수의 값을 참조할 수 있다는 것입니다.

 

예제)

#include <stdio.h>

int i = 10;
int j = 20;
void main() {

  extern int i; // 예약어 생략 가능 -> 왜냐하면 메인함수 앞에 전역변수로 i를 선언했기 때문
  extern int k; //외부 변수 선언 -> 예약어 생략불가 -> 변수 k가  메인함수 아래에 있음

  int j= 100;
  printf("i=%d, j=%d, k=%d\n", i, j, k); //출력: i=10,j=100,k=50
   
}
  
int k = 50;

 

4]레지스터변수

CPU 내의 레지스터에 자료를 저장하고자 할때 사용합니다. 예약어는 register를 사용하며 자동변수와 동일한 속성을 가지고 있습니다.

이 레지스터 변수는 프로그램의 실행속도 증가를 목적으로 사용하며, 주로 반복문에서 카운터 변수로 사용됩니다. 

 

예제)

#include <stdio.h>
void main() {

  register int i;
  int sum = 0;
  for(i = 0; i < 10; ++i) //레지스터 변수를 반복문의 카운터 변수로 사용
    sum+=i;
   i -=1;
  printf("i=%d, sum = %d\n", i, sum); //출력: i=9, sum = 45
}

 

 

 

 

 

'C Programming > C' 카테고리의 다른 글

[C] 포인터  (0) 2024.05.17
[C] 배열  (1) 2024.05.02
[C] 함수  (0) 2024.04.26
[C] goto문  (0) 2024.04.26
[C] 연산자  (1) 2024.04.26