포인터와 함수
- 값의 복사 인자 전달 방식 ( 기본 인자 전달 방법 )
먼저, 기본적으로 함수에서 인자를 전달할 때는 값의 복사 방법으로 인자가 매개변수로 전달이 된다.
위의 예제에서 num 변수를 func 함수의 인자로 넣어 값을 전달하는데 이 때 전달되는 것은 num 변수가 아니라 num 변수의 값이 전달되어 arg 변수에 저장된 것이다. 결국, 지역 변수 num과 함수의 매개 변수 arg는 서로 전혀 관련 없는 별개의 변수이다. ( arg 매개 변수 값을 아무리 변경하더라도 num 지역 변수의 값의 변화는 일어나지 않는다. )
- 배열을 함수의 인자로 전달하는 방법
배열을 기본 인자 전달 방법인 값의 복사 방법으로 통째로 복사하여 전달하는 방법은 존재하지 않는다.
위와 같은 소스는 컴파일 가능하지 않다. 왜냐하면 매개 변수로 배열을 선언하는 것은 허용되지 않기 때문이다. 그러나 gcc 컴파일러 6.4.0 version을 기준으로 위의 소스가 실행이 되고 정확한 결과가 나와서 가능한 것처럼 보였으나,
위와 같이 지역 변수의 배열과 매개 변수의 배열의 배열 이름의 값을 출력해 보았다. 그 결과는 다음과 같다.
두 배열 이름이 같은 주소를 지니고 있다. 이 뜻은 지역 변수의 배열 arr는 문제 없이 정상적인 방법으로 메모리 할당이 이루어져 배열을 이루고 있는 것이지만, 매개 변수의 배열 arg는 외형과 다르게 포인터 변수로서 선언되어 있다.
포인터 변수이기 때문에 arg의 값의 변경이 가능하다. 그리고 다음은 그 결과이다.
아파트를 보고 싶어 하는 사람 앞에 아파트를 통째로 복사해 놓을 수 없다면, 아파트를 직접 찾아가도록 주소를 알려주듯이 배열을 통째로 복사가 불가능하다면 배열의 시작 주소 값을 전달하고, 그에 맞는 포인터 형을 매개 변수를 이용하여 포인터 연산으로 각각의 배열 요소에 접근하여 원하는 값을 참조하면 된다.
18번 라인에서 넘겨주는 배열 이름(배열의 시작 주소)을 5번 라인에서 포인터 변수를 통하여 받고 포인터 연산을 통하여 ( arg[i] = *(arg+i) ) 각각의 요소를 참조하여 출력을 한다. 매개 변수 한정으로 5번 라인에서 주석 친 부분과 같은 형식으로 매개 변수를 선언하고 주소를 받을 수 있다.
- Call by value 그리고 Call by reference
두 방법에 대해 정리하기 이전에 두 변수의 값을 서로 교환하는 “SWAP” 문제에 대해서 두 방법을 적용해보고 해결하는 과정으로 두 방법을 정리할 것임.
먼저 call by value이다. 이 방법은 함수 인자 전달의 기본 방식이다.
swap 함수 내에서는 값이 변경되었으나, 정작 바뀌어야 할 main 함수 내의 변수들은 swap이 이루어지지 않았다 이는 복사에 의한 인자 전달이기 때문에 변경이 되지 않는 것은 당연한 일이다. 변경된 것은 swap 함수 내의 매개 변수끼리 값이 변경된 것이다. 이러한 swap은 진정한 의미의 swap이라고 할 수 없다. 이를 해결하기 위해선 주소가 주어지고 해당 주소를 직접 참조하여 값을 변경하는 방식으로 전개를 해야 한다.
다음은 call by reference이다.
주소를 전달하고, 전달된 주소를 참조하여 값을 변경하는 방법으로 값이 성공적으로 swap 되었음을 확인할 수 있다. scanf 함수 또한 call by reference 방법으로 인자를 전달하는 형태이고, 문자열(%s)을 입력 받을 때 ‘&’ 를 붙이지 않는 이유와 그 외의 값을 받을 때 ‘&’ 를 붙이는 이유를 call by reference 방법으로부터 알아낼 수 있다.
- 포인터에서의 const 키워드
다음과 같은 변수가 선언되어 있는 상황이다.
이러한 상황에서 const 키워드를 어느 위치에 사용하는지에 따른 결과들을 분석할 것.
1. 포인터 변수가 참조하는 대상을 상수화(const 화)한다.
포인터 변수 p를 통하여 number의 값이 변경되는 것을 허용하지 않는다.
2. 포인터 변수를 상수화(const 화)한다.
포인터 변수 p를 상수화 하여 포인터 변수 p의 값이 변경되는 것을 허용하지 않는다.
3. 둘 다 상수화(const 화)한다.
p를 통한 number의 값의 변경, p의 값 변경 모두 허용하지 않는다.
4. 일반 변수를 상수화(const 화) 한다.
변수 n을 상수화 하여 n의 값을 변경할 수 없다.
Const 키워드는 C++에서만 제공했던 키워드, 표준을 재정립하는 과정에서 C언어서도 지원을 해준다. Const 키워드는 값이 바뀌어서는 안 되는 변수의 변경을 막아준다. 이러한 경우는 프로그램을 실행하는데 있어서는 치명적인 오류로 작용할 수 있지만 문법 상으로는 문제가 없기 때문에 컴파일 오류 하나 받아볼 수 없다. 그렇기 때문에 효율적이고 현명한 프로그램을 원한다면 const 키워드를 자주 사용하는 습관을 들여놓아야 함.
'컴퓨터 언어 정리 > C 언어' 카테고리의 다른 글
12 포인터의 포인터 (0) | 2020.09.15 |
---|---|
11 다차원 배열 (0) | 2020.09.14 |
09 포인터와 배열 (0) | 2020.09.12 |
08 포인터 기본 (0) | 2020.09.11 |
07 1차원 배열 (0) | 2020.09.11 |