본문 바로가기
수업 복습/C 복습 노트

[C언어] C언어 수업 7차시

by LimitLog 2021. 4. 20.

1. 포인터

포인터란 실행중인 프로세스의 임의의 주소를 의미한다. C언어에서는 포인터를 이용하여 프로세스의 원하는 영역에 접근할 수 있다. 이는 기계어나 어셈블리 언어처럼 메모리를 직접 조작하는 것을 가능하게 해준다.

 

포인터 자료형에는 여러 가지가 있으며, 메모리에 접근할 대상의 종류에 따라 선언하는 방법과 사용하는 방법이 다르다.

 

 

 

2. 포인터 변수

변수의 주소(메모리상의 위치) 데이터를 갖는 변수를 말한다. 즉 변수는 값을 저장하지만, 포인터 변수는 실행중인 어떤 변수의 시작주소를 받아 이를 활용할 수 있도록 한다. 포인터 변수는 변수명 앞에 * 을 추가하여 선언한다.

1
2
3
int* i;
char * ch;
double *dp;
cs

* 의 위치는 어디에 있던 큰 상관은 없다.

 

 

 

3. Call by Value, Call by Reference 그리고 Call by Pointer

우선, Call by Value 예제부터 살펴보자. Call by Value란 값에 의한 참조를 뜻하며 원본 값을 그대로 복사하여 매개변수로 전달하는 방식이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int swap(int x, int y); //Call by Value
int main(void) {
    int a = 10, b = 20;
    swap(a, b);
    printf("a=%d   b=%d\n", a, b); //10 20
    return 0;
}
int swap(int x, int y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
    printf("x=%d   y=%d\n", x, y); //20 10
    return x, y;
}
cs

우선 a와 b값을 인자로 swap함수에 넘겼다. temp에 a값을 받아온 인자 x의 값을 대입했으므로 10이 들어간다. 그리고 x의 값을 y의 값으로 바꾼다. 매개변수 y는 b값을 인자로 받아왔으므로 x는 20이 된다. 그 후 y에는 temp에 저장되어있던 10이 대입된다. 이 예제같은 경우, a와 b, 그리고 x와 y는 그저 x와 y가 a와 b의 값만 가져왔을 뿐, 서로 아무런 상관관계가 없다.

 

다음은 Call by Reference 와 Call by Pointer 예제이다. Call by Reference와 Call by Pointer란 주소값에 의한 참조를 뜻하며 원본의 주소값을 매개변수를 통해 전달하여 함수 내에서 원본의 값을 직접 바꿀 수 있게 하는 방식이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void swap(int& x, int& y); // Call by Reference --> C에는 없는 문법이라 오류가 뜬다.
int main(void) {
    int a = 10, b = 20;
    swap(a, b);
    printf("a=%d   b=%d\n", a, b); //20 10
    return 0;
}
void swap(int& x, int& y) {
    int temp;
    temp = x;
    x = y;
    y = temp;
    printf("x=%d   y=%d\n", x, y); //20 10
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void swap(int* x, int* y); //Call by Point --> C++에서는 Call by Reference로
int main(void) {
    int a = 10, b = 20;
    swap(&a, &b);
    printf("a=%d   b=%d\n", a, b); //20 10
    return 0;
}
void swap(int* x, int* y) {
    int temp;
    temp = *x;
    *= *y;
    *= temp;
    printf("x=%d   y=%d\n"*x, *y); //20 10
}
cs

 

C언어에서는 Call by Reference 방식을 지원하지 않는다. 따라서 같은 역할을 하는 Call by Pointer 방식을 사용하면 된다.

이 방식은 매개 변수를 포인터 변수로 받아와 a와 b의 메모리 주소에 직접 접근해 해당 변수의 값을 조작한 것이다. x와 y는 a와 b의 메모리상 주소의 값을 가지고 있다.(4번째 줄) swap함수 내에서는 이 주소가 가리키는 위치의 값을 직접 조작하고 있기에 a와 b의 값이 바뀌게 된다.

 

 

 

4. 전역 변수

특정 지역(중괄호 {}) 내에 선언된 변수를 지역 변수라 하고, 이 중괄호 내부에 선언되지 않은 변수를 전역 변수라고 한다. 지역 변수는 해당 지역(중괄호) 내에서만 사용이 가능하지만, 전역 변수는 모든 지역에서 참조하여 사용할 수 있다. 또한 지역 변수는 해당 지역이 끝날 경우 메모리에서 소멸하지만 전역 변수는 프로그램이 종료될때까지 메모리에 남아 있게 된다. 또 전역 변수는 특별한 선언이 없을 경우 0부터 시작한다. 이는 전역 변수가 데이터 세그먼트에 선언된 변수라 그런데, 이 부분에 관한 내용은 8차시에서 좀 더 자세하게 다룰 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
int counter; //전역 변수
void set_counter(int i) {
    counter = i;
}
int main(void) {
    printf("counter = %d\n", counter); //0
    counter = 100;
    printf("counter=%d\n", counter);
    set_counter(20);
    printf("counter=%d\n", counter);
    return 0;
}
cs

 

한 프로그램 내에 동일한 이름의 전역 변수와 지역 변수가 존재할 경우, 지역 변수가 우선 참조된다.

1
2
3
4
5
6
7
8
int sum = 1//동일한 이름의 전역 변수와 지역 변수
int main(void) {
    int sum = 0;
    for (int i = 0; i <= 3; i++) {
        sum += i;
    }
    printf("sum = %d\n",sum); //6
}
cs

 

지역 변수와 코드 블럭을 이용해 다음과 같은 장난도 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
int main() { //코드 블럭
    int a = 100, b = 200;
 
    printf("Outer block : %d, %d\n",a,b); //100, 200
    { 
        int a = 300//지역변수 선언 (block 내에서만 사용)
        b = 400//선언한 게 아니므로 2행의 지역변수를 가져다 사용
        printf("Inner block : %d, %d\n",a,b); //300,400
    }
    printf("Outer block : %d, %d\n", a, b); //100,400
    return 0;
}
cs

 

 

 

5. 정적 변수와 동적 변수

우리가 흔히 선언하는 변수는 동적 변수로, 변수 사용이 모두 끝남(지역이 끝났을 경우)과 동시에 메모리에서 해제된다. 하지만 정적 변수는 컴파일 시 메모리에 할당되며, 프로그램이 종료될 때 메모리에서 해제된다. 이러한 특성은 전역 변수와도 동일하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//정적 변수와 동적 변수
void sub(void);
int main(void) {
    for (int i = 0; i < 3; i++) {
        sub();
    }
    return 0;
}
void sub(void) {
    int auto_count = 0//동적 변수. 호출될 때마다 값이 초기화된다.
    static int static_count = 0//정적 변수. 값이 초기화되지 않고 유지된다. 첫 선언 시에만 초기화.
    auto_count++;
    static_count++;
    printf("auto_count = %d\n", auto_count); //1 1 1
    printf("static_count = %d\n", static_count); //1 2 3
}
cs

'수업 복습 > C 복습 노트' 카테고리의 다른 글

[C언어] C언어 수업 9차시  (0) 2021.05.11
[C언어] C언어 수업 8차시  (0) 2021.05.04
[C언어] C언어 수업 6차시  (0) 2021.04.13
[C언어] C언어 수업 5차시  (0) 2021.04.06
[C언어] C언어 수업 4차시  (0) 2021.03.30

댓글