함수는 사용하는 목적이 있기에 함수마다 기능이 있어야 한다.
이 때 중요한 부분은 호출할 때 전달해주는 인수와 함수에서 전달받는 매개변수인데
어떤 종류의 매개변수들이 있는지 살펴볼 것이다.
void helloNumber(int num1) { printf("Hello, %d\n", num1); } int main() { helloNumber(123); return (0); } 결과값 : Hello, 123
위 코드를 보자.
main함수에서 helloNumber함수를 호출하는데
이 때 중괄호 안에 있는 123를 함수를 호출할 때 전달해주는
인수
라고 한다.
매개변수는 무엇인가
helloNumber함수를 정의할 때 중괄호 안에 있는 int num1 이 매개변수인데
정의로는 함수 바깥에서 전달받는 값이 저장되는 변수
가 매개변수
이다.
위와 같은 매개변수는 함수 안에서만 적용이 되고 함수 바깥에서 정의된 변수를 매개변수로 전달하지 않은체 사용할 수는 없다.
(같은 말로 함수에 값을 "그저 전달하기 위해" 사용했던 것)
함수에서 값을 여러 개 반환하고 싶을 때 아래와 같이 할 수 있을까?
return 10 20 30;
정답은 안된다. C에서는 함수의 반환값은 하나만 반환할 수 있다.
그에 대한 대책이 포인터 매개변수이다.
#include <stdio.h> void swapNumber(int *first, int *second) { int temp; temp = *first; *first = *second; *second = temp; } int main() { int num1 = 10; int num2 = 20; swapNumber(&num1, &num2); printf("%d %d\n", num1, num2); return 0; }
위와같이 num1의 값과 num2의 값을 함수를 통해 바꾸고 싶을 때는
포인터 변수를 매개변수로 받는 함수를 사용함으로서 메모리 주소에 접근하는 방법
이 있다.
포인터 매개변수를 사용하면 역참조*(에너리스크)
하여 값에 접근할 수 있기 때문이다.
위에서 매개변수로 포인터를 받을 수 있다면 배열 또한 받을 수 있다는 말이다.
아래는 그 사용예시이다.
#include <stdio.h>
void printArray(int *arr, int count) // 매개변수를 포인터로 지정하여 배열을 받음
{
for (int i = 0; i < count; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int numArr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printArray(numArr, sizeof(numArr) / sizeof(int)); // 배열과 요소의 개수를 넣음
return 0;
}
주의할 점은 포인터로는 배열의 크기를 알 수 없음으로 크기를 같이 전달해주어야 한다.
함수에 전달해야 할 매개변수가 이름, 나이, 전화번호처럼 정보가 많을 떄는 어떻게 해야할까?
이 때 떠오르는 것이 있다. 구조체이다.
구조체를 매개변수로 쓰는 함수를 선언할 때 형식은 아래와 같다.
반환값자료형 함수이름(struct 구조체이름 매개변수)
{
}
함수를 호출할 때 구조체 변수를 인수로 전달하면 구조체 안에 멤버가 모두 복사되어 전달된다.
한데 구조체가 커진다면 어떻게 될까? 복사해야하는 양이 많아지므로 비효율적이다.
불필요하게 복사되는 양을 줄일 수 있도록 포인터를 전달해주는 것이 베스트이다(주소값만 복사되기 떄문에)
반환값자료형 함수이름(struct 구조체이름 *매개변수)
{
}
위와 같이 구조체 매개변수 앞에 *(에스터리스크)를 추가해주면 구조체 포인터를 매개변수로 받는 함수가 된다.
이로서 구조체 전체가 불필요하게 복사되는 경우를 막아주고
메모리의 주소값을 전달해주었기에 멤버들의 값을 함수 내에서 변경했음에도 불구하고 함수바깥에서 똑같이 바뀌는 것을 볼 수 있다.