함수로 배열을 전달하는 방법은 함수를 호출할 때 전달인자(argument)에 배열의 시작주소를 전달하는 것입니다.
하지만, 이제 함수에서 전달 받게 되면 방법이 두가지로 나뉘어지게 됩니다.
- 배열명[]로 받는 방법과
- 포인터로 받는 방법
#include <cstring>
//배열의 길이를 같이 전달 해줘야 한다.
int findMaxValue(int a[], int len) {
int maxVal = a[0];
for (int i = 1; i<len; i++)
if (maxVal < a[i]) maxVal = a[i];
return maxVal;
}
//문자열의 경우 길이를 전달할 필요가 없다 이것은 문자열 뒤에 '\0'문자를 사용하여 문자의 끝을
//표시하였기 때문이다.
char findMaxChar(char a[]) {
char maxChar = a[0];
//strlen()함수로 '\0'문자까지의 문자 길이를 알 수 있음
for (int i = 1; i<strlen(a); i++)
if (maxChar < a[i]) maxChar = a[i];
return maxChar;
}
void main() {
int arr[10] = { 3, 24, 82, 12, 34, 7, 53, 17, 26, 51 };
char str[] = "geme over !";
printf("max val = %d\n", findMaxValue(arr, 10));
printf("max char = %c\n", findMaxChar(str));
}
위의 방법을 저는 책을 다 볼 때까지 이해를 못했습니다. 전달인자로 배열의 시작 주소 값 arr를 주는 건 알겠는데 왜 포인터로 안 받고 a[]로 받는지를 아무리 생각해도 몰랐습니다. 그런데 이것이 궁금하여 인터넷에 검색을 해보고 그 결과에 살짝 허탈함과 간단 명료함을 동시에 느꼈습니다.
결론은, 전달인자가 배열이라는걸 명확히 하기 위해 배열명[] 이라는 매개변수 형식으로 받는 거였습니다...
책을 읽으면서 왜 저러지 했는데 이런 이유였다니 왜인지 엄청 고민했는데 살짝 허탈하네요.
그래도 지금이라도 알아서 좋습니다. (❁´◡`❁)
#include <cstdio>
//배열의 시작 주소를 포인터로 받는다.
void findMinMax(int* a, int len, int* pmin, int* pmax) {
if (pmin != NULL) {
*pmin = a[0];
for (int i = 1; i < len; i++)
if (*pmin > a[i]) *pmin = a[i];
}
if (pmax != NULL) {
*pmax = a[0];
for (int i = 1; i < len; i++)
if (*pmax < a[i]) *pmax = a[i];
}
}
void main()
{
int arr[10] = { 3, 24, 82, 12, 34, 7, 53, 17, 26, 51 };
int min, max;
findMinMax(arr, 10, &min, &max);
printf("최소~최대: %2d~ %2d\n", min, max);
findMinMax(arr, 10, &min, NULL);
printf("최솟값: %2d\n", min);
findMinMax(arr, 10, NULL, &max);
printf("최댓값: %2d\n", max);
}
- 배열을 반환하는 함수
만약 배열의 역순을 구하여 반환하는 함수를 구현할려면 어떻게 해야할까?
int[] copyArray(const int a[], int len); //오류!
이런 식으로 함수를 만들면 안된다.
배열은 한꺼번에 대입연산자를 이용해 복사할 수 없는 것처럼 이 문장은 허용되지 않습니다.
역순으로 반환하기 위해서는 두 개의 배열을 인수로 전달해야 합니다.
#include <cstdio>
#include <cstring>
void printArray(const int a[], int len, char msg[] = "Array") {
printf("%s: ", msg);
for (int i = 0; i < len; i++)
printf("%3d", a[i]);
printf("\n");
}
void reverseArray(const int a[], int b[], int len) {
for (int i = 0; i < len; i++)
b[len - i - 1] = a[i];
}
void reverseString(const char src[], char dst[]) {
int len = strlen(src);
for (int i = 0; i < len; i++)
dst[len - i - 1] = src[i];
dst[len] = '\0';
}
void main()
{
int a[10] = { 3, 24, 82, 12, 34, 7, 53, 17, 26, 51 };
int b[10];
char src[] = "game over !", dst[40];
reverseArray(a, b, 10);
reverseString(src, dst);
printArray(a, 10, "배열 a");
printArray(b, 10, "배열 b");
printf("src = %s\n", src);
printf("dst = %s\n", dst);
}
- 주소를 반환하는 함수
함수가 주소를 직접 반환할 수 있습니다. 이때 반환형은 자료형* 이여야 합니다.
#include <cstdio>
#include <cstring>
void printArray(const int a[], int len, char msg[] = "Array") {
printf("%s: ", msg);
for (int i = 0; i < len; i++)
printf("%3d", a[i]);
printf("\n");
}
void reverseArray(const int a[], int b[], int len) {
for (int i = 0; i < len; i++)
b[len - i - 1] = a[i];
}
int* reverseArray1(const int a[], int len) {
int b[100];
for (int i = 0; i < len; i++)
b[len - i - 1] = a[i];
return b; // 잘못된 구현 방법
}
int* reverseArray2(const int a[], int len) {
static int b[100];
for (int i = 0; i < len; i++)
b[len - i - 1] = a[i];
return b; // 여전히 문제가 있는 방법
}
void main()
{
int a[10] = { 3, 24, 82, 12, 34, 7, 53, 17, 26, 51 };
int b[10], *c, *d;
reverseArray(a, b, 10);
c = reverseArray1(a, 10);
d = reverseArray2(a, 10);
printArray(a, 10, "배열 a");
printArray(b, 10, "배열 b");
printArray(c, 10, "배열 c");
printArray(d, 10, "배열 d");
}
하지만 문제가 있습니다. reverseArray1에서 b배열이 지역변수라는 점입니다.
즉, 함수가 종료되면 사라지는 변수이고, 반환되어 출력하려고 할 때에는 이미 없어진 변수입니다.
이 문제를 해결하기 위해 사라지지 않게 b를 전역변수로 변경해도 잠재적인 문제가 있습니다.
a 배열의 길이가 b 배열의 길이보다 큰 경우 실행 오류를 발생시킵니다.
따라서 이와 같은 함수의 구현을 위해 가장 좋은 방법은 원래의 함수(reverseArray()함수)와 같이 결과를 저장할 배열을
매개변수에 추가하는 것입니다.
'C++ 프로그래밍 > 함수' 카테고리의 다른 글
참조자의 반환 (0) | 2022.07.21 |
---|---|
C++의 Static을 알아보자 (0) | 2022.07.11 |
변수의 가시 범위와 생존기간 (0) | 2022.07.11 |
디폴트 매개변수 (0) | 2022.06.30 |
라이브러리 함수와 사용자 정의 함수 (0) | 2022.06.29 |