본문 바로가기

Programming/C

C언어 포인터 활용(C언어 use of pointer) feat. swap함수

반응형

1편 : 2020/10/17 - [Programming/C] - C언어 포인터 기본(C언어 basic pointer)


1편에 이어, 포인터를 어디에 사용하는지에 대해 살펴보자.


포인터는 왜 사용할까?

정답부터 말하면, 변수의 범위(scope)를 확장할 수 있기 때문이다.


범위? scope? 가 뭔데? 라고 물으면 아래 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int global_var;
 
int func1(int a, int b) 
{
    int c;
    double d;
 
    global_var = 10;// OKAY    
    i = j = 5;      // FAIL
 
    ...
}
 
int main()
{
    int i, j;
 
    global_var = 5// OKAY
    a = b = = 3;   // FAIL
    d = 4.3;         // FAIL    
    
    ...
}
 
 
cs

글로벌 변수인 global_var은 main()함수, func1()함수 모두에서 접근이 가능하다.


그러나 지역변수는 해당 변수의 선언을 포함하는 함수 내에서만 접근이 가능하다.

(엄밀히 말하면, 지역변수는 선언이 포함 되어 있는 { } 중괄호 내에서만 유효하다. 이 말이 이해 안 되면 skip해도 됨.) 


즉, main()함수 안에서 지역변수는 i,j가 있고, 그 두 변수는 main함수 내에서만 유효하다.

9번째 줄이 불가능한 이유다. func1()함수에서는 main()함수의 지역변수 i,j에 접근이 불가능하다

반대로 func1()함수 안에 지역변수는 a,b,c,d가 있고 이 변수는 func1()함수 내에서만 유효하다.

즉 19,20번째 줄이 불가능한 이유도 이 때문이다. main()함수에서 func1()함수의 지역변수에 접근하려 했기 때문이다.



지역변수는 선언 된 함수 안에서만 유효하다. 

그러면 함수의 역할이 되게 제한적이게 되는데..? 라는 생각이 들었다면 포인터의 필요성을 깨달은 것이다.


아래 소스코드는 main함수에 있는 두 변수 i,j의 값을 swap함수를 호출함으로써 바꾸는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void swap(int *a, int *b)
{
    int temp = *a;
    *= *b;
    *= temp;
}
 
int main()
{
    int i = 10;
    int j = 20;
 
    printf("i : %d, j : %d \n", i, j);
 
    swap(&i, &j);
    
    printf("i : %d, j : %d \n", i, j);
 
    return 0;
}
cs

코드 실행 결과 :



그림으로 그려보자.

1. int i = 10; int j = 20;

메모리 상 0x1000주소에 4byte int크기의 공간을 할당하고 이름을 i라고 한다. i에 10이라는 값을 넣는다.

메모리 상 0x2000주소에 4byte int크기의 공간을 할당하고 이름을 j라고 한다. j에 20이라는 값을 넣는다.


2. printf("i : %d, j : %d \n", i, j);

i와 j라는 공간에 있는 값을 출력한다.

즉 i : 10, j : 20이 출력된다.


3. swap(&i, &j);

&i, &j 는 i와 j의 주소값을 알려준다. 즉 &i는 0x1000값이, &j는 0x2000 값이 전달된다.

swap()함수에 argument로 main()함수안의 지역변수의 주소값을 넘김으로써

func1()에서도 포인터 변수 a,b를 통해 main()함수의 지역변수에 접근할 수가 있게 된다.



4. swap 함수

swap함수를 살펴보면, 포인터 변수에 *를 붙이면, 그 포인터 변수가 가리키고 있는 곳의 값을 의미한다 했다.


int temp = *a; 는, 지역변수 temp를 하나 만들고, 

포인터변수 a가 가리키고 있는 곳(0x1000번지)의 값을 temp에 넣어라 라는 의미이다.

실행하면 아래 그림처럼 된다.



*a = * b; 는 a가 가리키고 있는 곳의 값(기존 10)을 b가 가리키고 있는 값(20) 으로 바꾸라는 의미이다.




*b = temp; 는 b가 가리키고 있는 곳의 값을 temp가 가진값으로 바꾸어라 라는 얘기이다.



이처럼 포인터를 활용하면, 지역변수의 scope이 넓어지게 된다.

반응형