안녕하세요. 명월입니다.
이 글은 C++에서 함수 사용법(가변 파라미터 stdarg.h, 함수 포인터 그리고 범용 포인터 void*)에 대한 글입니다.
C++이라고 함수 사용법이 특별한 건 없습니다.
일반 (반환 자료형) (함수명) (파라미터) 순으로 선언이 가능하빈다.
#include <stdio.h>
// 가변 파라미터를 사용하기 위한 함수.
#include <stdarg.h>
#include <iostream>
using namespace std;
// 일반 함수
// void는 반환 값이 필요없다.
void function(const char* val)
{
// 콘솔 출력
cout << " print function " << endl;
}
// 파라미터 값을 합산 함수
// 첫번째 파라미터는 가변 파라미터 개수, ...은 가변 파라미터.
int sum(int count, ...)
{
// 반환 값 변수
int ret = 0;
// 가변 파라미터를 사용할 포인터
va_list args;
// va_list가 가변 파라미터의 시작 포인터를 찾고, size를 할당한다.
va_start(args, count);
// 가변 파라미터 개수만큼 반복 루프를 돌린다.
for (int i = 0; i < count; i++)
{
// 가변 파라미터로 부터 값을 취득
ret += va_arg(args, int);
}
// 가변 파라미터 포인터 초기화
va_end(args);
// 가변 파라미터 값을 전부 더한 후 반환
return ret;
}
// 실행 함수
int main()
{
// 함수 호출..
function(" hello world ");
// 합산 함수, 첫번째 파라미터는 가변 파라미터 개수, 그리고 그 다음은 함산할 값.
int data = sum(10 ,1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 1부터 10까지 더하면 값은 55
cout << " sum : " << data;
return 0;
}
일반 함수 호출은 다른 java와 C#과 크게 다른게 없습니다.
C++에서 배열은 그 길이를 알 수가 없습니다. 이유는 포인터로 그 값을 받는데, 포인터는 단순히 포인터의 주소값이지 그 크기를 알 수는 없습니다.
그래서 가변 파라미터를 받게 되면 첫 파라미터를 파라미터의 개수를 넣어야 합니다.
c++에서는 함수를 변수로 담아서 사용할 수 있습니다. python이나 javascript에서 함수를 변수(object)하는 방법과 비슷하고, C#에서 델리게이트와 같습니다.
#include <stdio.h>
#include <iostream>
using namespace std;
// 함수
void function1()
{
// 콘솔 출력
cout << " call function - 1 " << endl;
}
// 함수
void function2()
{
// 콘솔 출력
cout << " call function - 2 " << endl;
}
// 실행 함수
int main()
{
// 함수 포인터 선언은 일반 변수 선언과 조금 차이가 있다.
// fp의 변수명에 함수 포인터 선언 (리턴값은 void이고, 파라미터는 없는 함수)
void (*fp) ();
// 함수 포인터에 function1함수를 대입
fp = function1;
// " call function - 1 "이 출력
fp();
// 함수 포인터에 function2함수를 대입
fp = function2;
// " call function - 2 "이 출력
fp();
return 0;
}
c++에서는 다른 언어와 다르게 포인터란 존재가 있습니다. 포인터는 메모리의 주소값을 나타내는 int형 데이터입니다.
링크 - https://nowonbun.tistory.com/716 [C++] 배열과 포인터(메모리 주소) 그리고 할당(new){stack과 heap에 대해서}즉, 포인터 자체의 데이터 사이즈는 4byte입니다.
근데, 포인터는 다른 언어처럼 그 데이터 타입을 표현하는 데이터 타입으로 설정합니다.
#include <stdio.h>
#include <iostream>
using namespace std;
// 실행 함수
int main()
{
// ptr1에 int형 데이터를 선언
int* ptr1 = new int();
// 값 10을 대입
*ptr1 = 10;
// ptr2에 char형 데이터를 선언
char* ptr2 = new char();
// 값 'a'을 대입
*ptr2 = 'a';
// 콘솔 출력
cout << " ptr1 포인터 값 : " << (int)ptr1 << " 값 : " << *ptr1 << endl;
cout << " ptr2 포인터 값 : " << (int)ptr2 << " 값 : " << *ptr2 << endl;
// 메모리 해제
delete ptr1;
delete ptr2;
return 0;
}
위처럼 int형을 할당하면 int*로 char형을 할당하면 char*형을 선언해서 사용해야 합니다. 그런데 이게 불명확할 떄가 있습니다.
#include <stdio.h>
#include <iostream>
using namespace std;
// 파라미터가 true면 int형 값이 리턴되고, false 면 char형이 리턴된다.
void* function(bool param)
{
// param이 true면,
if (param)
{
// int형 값을 선언한다.
int* ptr = new int();
// 값 10을 넣는다.
*ptr = 10;
// 리턴
return ptr;
}
// param이 false이면,
else
{
// char형 값을 선언한다.
char* ptr = new char();
// 값 'a'를 넣는다.
*ptr = 'a';
// 리턴
return ptr;
}
}
// 실행 함수
int main()
{
// 함수에 true를 넣으면 int*형 데이터가 나온다.
int* ptr1 = (int*)function(true);
// 함수에 false를 넣으면 char*형 데이터가 나온다.
char* ptr2 = (char*)function(false);
// 콘솔 출력
cout << " ptr1 포인터 값 : " << (int)ptr1 << " 값 : " << *ptr1 << endl;
cout << " ptr2 포인터 값 : " << (int)ptr2 << " 값 : " << *ptr2 << endl;
// 메모리 해제
delete ptr1;
delete ptr2;
return 0;
}
void*형 타입은 정해지지 않는 데이터 타입의 포인터를 받을 수 있습니다. 어차피 포인터는 주소 값이고 int형 타입의 4byte입니다.
데이터 타입은 크게 중요하지 않기 때문에 그냥 포인터값이면 전부 void*로 받아도 상관 없습니다.
c++ 프로젝트가 커지고 MFC에서 포인터를 윈도우 메시지에 올리고, 포인터 값을 이리 던지고 저리 던지고 할때 이 자료형을 명시하지 않으면 나중에 값의 데이터 타입을 알 수가 없어지기 때문에 형식적으로라도 정확한 타입으로 설정하는게 좋습니다.
여기까지 C++에서 함수 사용법(가변 파라미터 stdarg.h, 함수 포인터 그리고 범용 포인터 void*)에 대한 글이었습니다.
궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.
'Study > C , C++ , MFC' 카테고리의 다른 글
[C++] 클래스 상속 (0) | 2020.03.19 |
---|---|
[C++] 템플렛(Template) (2) | 2020.03.19 |
[C++] 전처리문 (0) | 2020.03.17 |
[C++] 클리스 선언과 사용법 (0) | 2020.03.17 |
[C++] 배열과 포인터(메모리 주소) 그리고 할당(new){stack과 heap에 대해서} (0) | 2020.03.14 |
[C++] 제어문 (0) | 2020.03.12 |
[C++] 연산자 (0) | 2020.03.11 |
[C++] 변수와 상수, 그리고 데이터 타입 (0) | 2020.03.10 |