윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 14. 포인터와 함수에 대한 이해
Chapter 14-1. 함수의 인자로 배열 전달하기 윤성우의 열혈 C 프로그래밍 Chapter 14-1. 함수의 인자로 배열 전달하기 윤성우 저 열혈강의 C 프로그래밍 개정판
인자전달의 기본방식은 값의 복사이다! 윤성우의 열혈 C 프로그래밍 age에 저장된 값이 매개변수 num에 복사가 된다. 배열을 함수의 매개변수에 전달하는 이유는 함수 내에서 배열에 저장된 값을 참조하도록 하기 위함이다. 그런데 배열을 통째로 전달하지 않아도 이러한 일이 가능하다. 실제 전달되는 것은 age가 아니라 age에 저장된 값이다. 위의 코드에서 보이는 바와 같이, 배열을 함수의 인자로 전달하려면 배열을 통째로 복사할 수 있도록 배열이 매개변수로 선언되어야 한다. 그러나 C언어는 매개변수로 배열의 선언을 허용하지 않는다. 결론! 배열을 통째로 복사하는 방법은 C언어에 존재하지 않는다. 따라서 배열을 통째로 복사해서 전달하는 방식 대신에, 배열의 주소 값을 전달하는 방식을 대신 취한다.
배열을 함수의 인자로 전달하는 방식 윤성우의 열혈 C 프로그래밍 int main(void) { 배열의 이름은 int형 포인터! 따라서 int형 포인터 변수에 배열의 이름이 지니는 주소 값을 저장할 수 있다. 배열의 이름은 int형 포인터! 위의 예제를 통해서 다음과 같은 코드의 구성이 가능함을 유추할 수 있다. int main(void) { int arr[3]={1, 2, 3}; SimpleFunc(arr); . . . . } 배열이름 arr읜 int형 포인터이므로 매개변수는 int형 포인터 변수! void SimpleFunc(int * param) { printf(“%d %d”, param[0], param[1]); } 포인터 변수를 이용해서도 배열의 형태로 접근가능! 배열이름 arr이 지니는 주소 값의 전달
윤성우의 열혈 C 프로그래밍 배열을 함수의 인자로 전달하는 예제 실행결과 실행결과
배열을 함수의 인자로 전달받는 함수의 또 다른 선언 윤성우의 열혈 C 프로그래밍 배열을 함수의 인자로 전달받는 함수의 또 다른 선언 동일한 선언 매개변수의 선언에서는 int * param과 int param[]이 동일한 선언이다. 따라서 배열을 인자로 전달받는 경우에는 int param[]이 더 의미있어 보이므로 주로 사용된다. 하지만 그 이외의 영역에서는 int * ptr의 선언을 int ptr[]으로 대체할 수 없다.
Chapter 14-2. Call-by-value vs. Call-by-reference 윤성우의 열혈 C 프로그래밍 Chapter 14-2. Call-by-value vs. Call-by-reference 윤성우 저 열혈강의 C 프로그래밍 개정판
값을 전달하는 형태의 함수호출: Call-by-value 윤성우의 열혈 C 프로그래밍 값을 전달하는 형태의 함수호출: Call-by-value 함수를 호출할 때 단순히 값을 전달하는 형태의 함수호출을 가리켜 Call-by-value라 하고, 메모리의 접근에 사용되는 주소 값을 전달하는 형태의 함수호출을 가리켜 Call-by-reference라 한다. 즉, Call-by-value와 Call-by-reference를 구분하는 기준은 함수의 인자로 전달되는 대상에 있다. call-by-value call-by-value와 call-by-reference라는 용어를 기준으로 구분하는 것이 중요한 게 아니다. 중요한 것은 각 함수의 특징을 이해하고 적절한 형태의 함수를 정의하는 것이다. call-by-value 형태의 함수에서는 함수 외부에 선언된 변수에 접근이 불가능하다. 그러나 call-by-reference 형태의 함수에서는 외부에 선언된 변수에 접근이 가능하다. call-by-reference
call-by-value가 적절치 않은 경우 윤성우의 열혈 C 프로그래밍 잘못 적용된 Call-by-value Swap 함수 내에서의 값의 교환 call-by-value가 적절치 않은 경우 실행결과 Swap 함수 내에서의 값의 교환은 외부에 영향을 주지 않는다.
주소 값을 전달하는 형태의 함수호출: Call-by-reference 윤성우의 열혈 C 프로그래밍 주소 값을 전달하는 형태의 함수호출: Call-by-reference Swap 함수 내에서 함수 외부에 있는 변수간 값의 교환 실행결과 Swap 함수 내에서의 *ptr1은 main 함수의 num1 Swap 함수 내에서의 *ptr2는 main 함수의 num2 를 의미하게 된다.
scanf 함수호출 시 & 연산자를 붙이는 이유는? 윤성우의 열혈 C 프로그래밍 scanf 함수호출 시 & 연산자를 붙이는 이유는? 변수 num 앞에 & 연산자를 붙이는 이유는? scanf 함수 내에서 외부에 선언된 변수 num에 접근 하기 위해서는 num의 주소 값을 알아야 한다. 그래서 scanf 함수는 변수의 주소 값을 요구한다. 배열 이름 str 앞에 & 연산자를 붙이지 않는 이유는? str은 배열의 이름이고 그 자체가 주소 값이기 때문에 & 연산자를 붙이지 않는다. str을 전달함은 scanf 함수 내부로 배열 str의 주소 값을 전달하는 것이다.
Chapter 14-3.포인터 대상의 const 선언 윤성우의 열혈 C 프로그래밍 Chapter 14-3.포인터 대상의 const 선언 윤성우 저 열혈강의 C 프로그래밍 개정판
포인터 변수의 참조대상에 대한 const 선언 윤성우의 열혈 C 프로그래밍 포인터 변수의 참조대상에 대한 const 선언 왼편의 const 선언이 갖는 의미 포인터 변수 ptr을 이용해서 ptr이 가리키는 변수에 저장된 값을 변경하는 것을 허용하지 않겠습니다! 그러나 변수 num에 저장된 값 자체의 변경이 불가능한 것은 아니다. 다만 ptr을 통한 변경을 허용하지 않을뿐이다.
포인터 변수의 상수화 윤성우의 열혈 C 프로그래밍 const int * ptr=# 포인터 변수 ptr에 저장된 값을 상수화 하겠다. 즉, ptr에 저장된 값은 변경이 불가능하다. ptr이 가리키는 대상의 변경을 허용하지 않는다. const int * ptr=# const int * const ptr=# int * const ptr=# 두 가지 const 선언을 동시에 할 수 있다.
const 선언이 갖는 의미 윤성우의 열혈 C 프로그래밍 안전성이 높아진 코드 const 선언은 추가적인 기능을 제공하기 위한 것이 아니라, 코드의 안전성을 높이기 위한 것이다. 따라서 이러한 const의 선언을 소홀히하기 쉬운데, const의 선언과 같이 코드의 안전성을 높이는 선언은 가치가 매우 높은 선언이다.
Chapter 14가 끝났습니다. 질문 있으신지요?