인자전달의 기본방식은 값의 복사이다
- "함수호출 시 전달되는 인자의 값은 매개변수에 복사가 된다"
- 위 문장에서 가장 중요한 단어는 '복사'이다.
- 즉, 복사가 되는 것 뿐이기 때문에 함수가 호출되고 나면, 전달되는 인자와 매개변수는 별개가 된다.
int simplefunc(int num){......}
int main(void)
{
int age=17;
simplefunc(age); // age에 저장된 값이 매개변수 num에 복사됨
}
- 위 코드의 simplefunc 함수 호출을 통해서 인자로 age를 전달하고 있음.
But..
- "실제로 전달되는 것은 age가 아닌, age에 저장된 값임"
- 그리고 그 값이 매개변수 num에 복사되는 것.
- age와 num은 값을 주고받은 사이일 뿐 그 이상은 아무런 관계도 아니다.
- "simplefunc 함수 내애서 매개변수 num에 저장된 값을 1 증가시킬 경우, 변수 age의 값은 얼마가 증가하는가"
→ 변수 age의 값은 증가하지 않는다.
→ 왜??? num과 age는 별개의 변수이기 때문이다.
그럼 이어서...
함수호출 시 인자로 배열을 통째로 전달하는 방법에 대해서 생각.
그러나... 함수를 호출하면서 매개변수에 배열을 통째로 넘겨주는 방법은 존재하지 않는다.
왜? → "매개변수로 배열을 선언할 수 없음"
배열을 통째로 넘겨받으려면 매개변수로 배열을 선언할 수 있어야 한다.
→ 이것이 허용되지 않기 때문에 배열을 통째로 넘기는 것은 불가능
대신!
함수 내에서 배열에 접근할 수 있도록 배열의 주소값을 전달하는 것은 가능
(여기까지 보면 포인터의 존재 이유가 배열을 편하게 다루려고 만든 것 같다는 생각이.....)
배열을 함수의 인자로 전달하는 방식
- 아파트를 보고 싶어 하는 사람 앞에 아파트를 복사해다 놓을 수 없다면, 아파트의 주소를 가르쳐줘서 직접 찾아가게 하면 됨.
즉...
- 배열을 통째로 전달하는 것이 불가능하다면, 배열의 주소값을 인자로 전달해서 이를 통해서 접근하도록 유도하는 방법을 생각해볼 수 있다.
다음과 같은 배열이 있다면,
int arr[3]={1,2,3};
다음의 형태로 함수를 호출하면서 배열의 주소 값을 전달할 수 있음
SimpleFunc(arr); // SimpleFunc 함수를 호출하면서 배열 arr의 주소 값 전달
그렇다면 SimpleFunc 함수의 매개변수 선언?
int main(void)
{
int arr[3] = {1,2,3};
int* ptr= arr; // 배열이름 arr은 int형 포인터
}
따라서 SimpleFunc 함수의 매개변수는 다음과 같이 int형 포인터 변수로 선언되어야 한다.
void SimpleFunc(int* param) {......}
param을 이용해서 배열 접근?
printf("%d %d", param[1], param[2]);
예제.
#include <stdio.h>
void showarr(int*, int);
int main(void)
{
int arr1[] = { 1,2,3 };
int arr2[] = { 4,5,6,7,8 };
showarr(arr1, sizeof(arr1) / sizeof(int));
showarr(arr2, sizeof(arr2) / sizeof(int));
}
void showarr(int* param, int len)
{
for (int i = 0; i < len; i++)
printf("%d ", param[i]);
printf("\n");
}
그렇다면 출력아닌 값의 변경도 가능?
가능하다!
예제.
#include <stdio.h>
void showarr(int*, int);
void addarr(int*, int, int);
int main(void)
{
int arr[] = { 1,2,3 };
addarr(arr, sizeof(arr) / sizeof(int), 1);
showarr(arr, sizeof(arr) / sizeof(int));
addarr(arr, sizeof(arr) / sizeof(int), 10);
showarr(arr, sizeof(arr) / sizeof(int));
addarr(arr, sizeof(arr) / sizeof(int), 100);
showarr(arr, sizeof(arr) / sizeof(int));
}
void showarr(int* param, int len)
{
for (int i = 0; i < len; i++)
printf("%d ", param[i]);
printf("\n");
}
void addarr(int* param, int len, int add)
{
for (int i = 0; i < len; i++)
param[i] += add;
}
- 이렇듯 배열의 주소 값만 안다면 어디서든 배열에 접근하여 저장된 값을 참조하고 변경할 수 있다.
배열을 함수의 인자로 전달하는 함수의 또 다른 선언
int형 배열의 주소 값을 인자로 받을 수 있도록 int형 포인터 변수 선언
void showarr(int* param, int len) {....}
void addarr(int* param, int len, int add) {....}
아래처럼 선언하는 것도 가능
void showarr(int param[], int len) {....}
void addarr(int param[], int len, int add) {....}
int param[] 과 int *param은 동일한 선언
다만, 전자의 선언이, 배열이 인자로 전달된다는 느낌을 더 강하게 주는 선언
일반적으로 배열의 주소 값이 인자로 전달될 때는 int param[] 형태의 선언을 주로 많이 씀
하지만, 이 둘이 같은 선언으로 간주되는 경우에는 매개변수의 선언으로 제한된다.
int main(void)
{
int arr[3]={1,2,3};
int* ptr=arr; // int ptr[]=arr;로 대체 불가능
}
참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.
'Language&Framework&Etc > C' 카테고리의 다른 글
포인터와 함수에 대한 이해(14-3) 포인터 대상의 const 선언 (0) | 2020.12.08 |
---|---|
포인터와 함수에 대한 이해(14-2) Call-by-value vs Call-by-reference (0) | 2020.12.08 |
포인터와 배열! 함께 이해하기(13-4) 포인터 변수로 이뤄진 배열: 포인터 배열 (0) | 2020.12.08 |
포인터와 배열! 함께 이해하기(13-3) 상수 형태의 문자열을 가리키는 포인터 (0) | 2020.12.08 |
포인터와 배열! 함께 이해하기(13-2) 포인터 연산 (0) | 2020.12.08 |