[C언어 스터디 - 10] 반환값을 이용하는 함수 (function using return)
2020. 6. 30. 11:00ㆍ03. Resources/C, C++
728x90
반응형
C언어 함수 정리
참고 문헌 (Ch 61): https://dojang.io/mod/page/view.php?id=527
함수에서 반환값 사용하기
함수에서 반환값을 사용하기 위해서는 함수를 정의할 때 반환값의 자료형을 지정해주고, 함수 안에서 return 키워드로 값을 반환하면 된다.
반환값자료형 함수이름()
{
return 반환값;
}
중요한 점: 반환값과 반환값의 자료형이 일치해야한다.
/*
↓ 반환값 자료형 */
int one() // 반환값이 int형인 one 함수 정의
{
return 1; // 1을 반환 => 1은 int 형
} // ↑ 반환값
#include <stdio.h>
int one() // 반환값이 int형인 one 함수 정의
{
return 1; // 1을 반환
}
int main()
{
int num1;
num1 = one(); // int형을 반환했으므로 int형 변수에 저장
printf("%d\n", num1); // 1
return 0;
}
int 가 아닌 다른 자료형 반환 예시
#include <stdio.h>
#include <stdbool.h> // bool, true, false가 정의된 헤더 파일
float realNumber() // 반환값이 float형인 realNumber 함수 정의
{
return 1.234567f; // 1.234567: float형을 반환
}
bool truth() // 반환값이 bool형인 truth 함수 정의
{
return true; // true: bool형을 반환
}
int main()
{
float num1;
bool b1;
num1 = realNumber(); // float형을 반환했으므로 float형 변수에 저장
b1 = truth(); // bool형을 반환했으므로 bool형 변수에 저장
printf("%f\n", num1); // 1.234567
printf("%d\n", b1); // 1
return 0;
}
물론 return 값의 자료형을 강제로 변환해주면 이용할 수 있긴 하다.
#include <stdio.h>
int one() // 반환값이 int형인 one 함수 정의
{
float a = 1.1f;
return (int)a; // a를 int로 변환하여 반환
}
int main()
{
int num1;
num1 = one(); // int형을 반환했으므로 int형 변수에 저장
printf("%d\n", num1); // 1
return 0;
}
또한 함수 반환값의 자료형을 함수를 이용할 때 강제로 바꿔줄 수도 있다.
#include <stdio.h>
float onePointOne() // 반환값이 float형인 onePointOne 함수 정의
{
return 1.1f; // 실수 1.1을 반환
}
int main()
{
int num1;
num1 = (int)onePointOne(); // onePointOne의 반환값을 int로 변환하여 저장
printf("%d\n", num1); // 1
return 0;
}
포인터 반환하기
일반적인 자료형을 반환하는 것과 비슷하지만, *를 추가적으로 붙여준다.
반환값자료형 *함수이름()
{
return 반환값;
}
예시 (잘못된 코드)
#include <stdio.h>
int *ten() // int 포인터를 반환하는 ten 함수 정의
{
int num1 = 10; // num1은 함수 ten이 끝나면 사라짐
return &num1; // 함수에서 지역 변수의 주소를 반환하는 것은 잘못된 방법
} // ↑ warning C4172: 지역 변수 또는 임시 변수의 주소를 반환하고 있습니다.
int main()
{
int *numPtr;
numPtr = ten(); // 함수를 호출하고 반환값을 numPtr에 저장
printf("%d\n", *numPtr); // 10: 값이 나오긴 하지만 이미 사라진 변수를 출력하고 있음
return 0;
}
지역변수의 주소를 반환하는 경우, 함수에서 이용된 다음 값이 사라지기 때문에 좋은 방법이 아님. 메모리를 할당한 다음, 해당 주소를 반환해야 한다.
예시 (제대로 된 코드)
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
int *ten() // int 포인터를 반환하는 ten 함수 정의
{
int *numPtr = malloc(sizeof(int)); // int 크기만큼 동적 메모리 할당
*numPtr = 10; // 역참조로 10 저장
return numPtr; // 포인터 반환. malloc으로 메모리를 할당하면 함수가 끝나도 사라지지 않음
}
int main()
{
int* numPtr;
numPtr = ten(); // 함수를 호출하고 반환값을 numPtr에 저장
printf("%d\n", *numPtr); // 10: 메모리를 해제하기 전까지 안전함
free(numPtr); // 다른 함수에서 할당한 메모리라도 반드시 해제해야 함
return 0;
}
대신 이용한 다음에는 꼭 할당된 동적 메모리를 해제해주어야한다. 그렇지 않은 경우 메모리 누수가 발생한다.
또 다른 예시 (문자열 반환)
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
#include <string.h> // strcpy 함수가 선언된 헤더 파일
char *helloLiteral() // char 포인터를 반환하는 helloLiteral 함수 정의
{
char *s1 = "Hello, world!";
return s1; // 문자열 Hello, world!는 메모리에 저장되어 있으므로 사라지지 않음
// 문자열 포인터 리턴
}
char *helloDynamicMemory() // char 포인터를 반환하는 helloDynamicMemory 함수 정의
{
char *s1 = malloc(sizeof(char) * 20); // char 20개 크기만큼 동적 메모리 할당
strcpy(s1, "Hello, world!"); // Hello, world!를 s1에 복사
return s1; // 문자열 포인터 리턴
}
int main()
{
char *s1;
char *s2;
s1 = helloLiteral();
s2 = helloDynamicMemory();
printf("%s\n", s1); // Hello, world!
printf("%s\n", s2); // Hello, world!
free(s2); // 동적 메모리 해제
return 0;
}
void 포인터 반환하기
자료형에 상관없이 값을 꺼내오고 싶을 때 이용하는 방법
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
#include <string.h> // strcpy 함수가 선언된 헤더 파일
void *allocMemory() // void 포인터를 반환하는 allocMemory 함수 정의
{
void *ptr = malloc(100); // 100바이트만큼 동적 메모리 할당
return ptr; // void 포인터 반환
}
/* 코드 줄이는 방법
void *allocMemory()
{
return malloc(100); // malloc 함수를 호출하면서 바로 반환
}
*/
int main()
{
char *s1 = allocMemory(); // void 포인터를 char 포인터에 넣어서 문자열처럼 사용
strcpy(s1, "Hello, world!"); // s1에 Hello, world! 복사
printf("%s\n", s1); // Hello, world!
free(s1); // 동적 메모리 해제
int *numPtr1 = allocMemory(); // void 포인터를 int 포인터에 넣어서 정수 배열처럼 사용
numPtr1[0] = 10; // 첫 번째 요소에 10 저장
numPtr1[1] = 20; // 두 번째 요소에 20 저장
printf("%d %d\n", numPtr1[0], numPtr1[1]); // 10 20
free(numPtr1); // 동적 메모리 해제
return 0;
}
구조체와 구조체 포인터 반환하기
함수의 반환값으로 구조체를 이용하는 방법!
struct 구조체이름 함수이름()
{
return 구조체변수;
}
예시
#include <stdio.h>
#include <string.h> // strcpy 함수가 선언된 헤더 파일
struct Person {
char name[20];
int age;
char address[100];
};
struct Person getPerson() // Person 구조체를 반환하는 getPerson 함수 정의
{
struct Person p;
strcpy(p.name, "홍길동");
p.age = 30;
strcpy(p.address, "서울시 용산구 한남동");
return p; // 구조체 변수 반환
}
int main()
{
struct Person p1;
p1 = getPerson(); // 반환된 구조체 변수의 내용이 p1로 모두 복사됨
// getPerson에서 저장한 값이 출력됨
printf("이름: %s\n", p1.name); // 홍길동
printf("나이: %d\n", p1.age); // 30
printf("주소: %s\n", p1.address); // 서울시 용산구 한남동
return 0;
}
구조체 변수를 반환하여 다른 변수에 저장하면, 반횐된 구조체의 내용을 모두 복사하게 되는데, 이는 구조체 크기가 커지면 메모리를 많이 잡아먹게 된다.
따라서 구조체 복사가 일어나지 않도록 malloc 함수로 동적 메모리를 할당한 뒤 구조체 포인터를 반환하는 것이 좋음
struct 구조체이름 *함수이름()
{
return 구조체포인터;
}
예시
#include <stdio.h>
#include <string.h> // strcpy 함수가 선언된 헤더 파일
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
struct Person {
char name[20];
int age;
char address[100];
};
struct Person *allocPerson() // Person 구조체 포인터를 반환하는 allocPerson 함수 정의
{
struct Person *p = malloc(sizeof(struct Person)); // 구조체 포인터에 동적 메모리 할당;
strcpy(p->name, "홍길동");
p->age = 30;
strcpy(p->address, "서울시 용산구 한남동");
return p; // 구조체 포인터 반환
}
int main()
{
struct Person *p1;
p1 = allocPerson(); // 포인터를 반환하여 p1에 메모리 주소 저장
// allocPerson에서 저장한 값들이 출력됨
printf("이름: %s\n", p1->name); // 홍길동
printf("나이: %d\n", p1->age); // 30
printf("주소: %s\n", p1->address); // 서울시 용산구 한남동
free(p1); // 동적 메모리 해제
return 0;
}
만약 구조체 별칭을 사용하는 경우라면
typedef struct _Person {
char name[20];
int age;
char address[100];
} Person, *PPerson; // 구조체 별칭 Person, 구조체 포인터 별칭 PPerson
PPerson allocPerson() // Person 구조체 포인터의 별칭을 반환값 자료형으로 지정
{
PPerson p = malloc(sizeof(Person)); // 구조체 포인터에 동적 메모리 할당
strcpy(p->name, "홍길동");
p->age = 30;
strcpy(p->address, "서울시 용산구 한남동");
return p; // 구조체 포인터 반환
}
반응형
'03. Resources > C, C++' 카테고리의 다른 글
[C언어 스터디 - 12] 포인터를 입력으로 이용하는 함수 (function using pointers as inputs) (0) | 2020.07.02 |
---|---|
[C언어 스터디 - 11] 함수 입력 이용하기 (function input variables) (0) | 2020.07.01 |
[C언어 스터디 - 09] 기본적인 함수 내용 (function basic) (0) | 2020.06.29 |
[C언어 스터디 - 08] 열거형 (enum)] (0) | 2020.06.28 |
[C언어 스터디 - 07] 구조체 배열 (struct array) (0) | 2020.06.27 |