일련의 데이터에서 매개 변수가 전달한 함수를 수행하는 함수를 만들고 싶습니다. C에서 함수를 매개 변수로 어떻게 전달합니까?
void funcA(void(*funcB)(int))
와 void (*funcA())()
에 typedef void funcB(); void funcA(funcB)
와 funcB funcA()
? 나는 거꾸로 보지 않는다.
일련의 데이터에서 매개 변수가 전달한 함수를 수행하는 함수를 만들고 싶습니다. C에서 함수를 매개 변수로 어떻게 전달합니까?
void funcA(void(*funcB)(int))
와 void (*funcA())()
에 typedef void funcB(); void funcA(funcB)
와 funcB funcA()
? 나는 거꾸로 보지 않는다.
답변:
선언
함수 매개 변수를 사용하는 함수의 프로토 타입은 다음과 같습니다.
void func ( void (*f)(int) );
이것은 매개 변수 f
가 void
리턴 유형 을 가지며 단일 int
매개 변수 를 취하는 함수에 대한 포인터가된다고 표시합니다 . 다음 함수 ( print
)는 func
올바른 유형이므로 매개 변수로 전달 될 수있는 함수의 예입니다 .
void print ( int x ) {
printf("%d\n", x);
}
함수 호출
함수 매개 변수로 함수를 호출 할 때 전달 된 값은 함수에 대한 포인터 여야합니다. 이를 위해 함수 이름 (괄호없이)을 사용하십시오.
func(print);
func
인쇄 함수를 전달하여 호출 합니다.
기능 바디
다른 매개 변수와 마찬가지로 func
이제 함수 본문에서 매개 변수 이름을 사용하여 매개 변수 값에 액세스 할 수 있습니다. func
0-4에 전달 된 함수를 적용 한다고 가정 해 봅시다 . 먼저 루프가 print를 직접 호출하는 모습을 고려하십시오.
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
func
의 매개 변수 선언은 그것이 f
원하는 함수에 대한 포인터의 이름 이라고 말하고 있기 때문에 f
, 포인터라면 포인터 *f
가 f
가리키는 것 (즉, print
이 경우 함수) 임을 먼저 상기합니다 . 결과적으로 위의 루프에서 인쇄가 발생할 때마다 *f
다음 과 같이 바꿉니다 .
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
f
함수 호출 모두 f
*없이 그대로 사용할 수 있습니다 . 그러나 매개 변수 f가 함수 포인터라는 것을 분명히하기 위해 수행하는 것이 좋습니다. 그러나 가독성이 자주 손상됩니다.
typedef
for 함수 포인터 사용에 대한 단일 참조를 만들지 않습니까? 죄송합니다. 투표해야합니다.
이 질문에는 이미 함수 포인터를 정의하는 대답이 있지만 특히 응용 프로그램 주위에 전달할 경우 매우 혼란 스러울 수 있습니다. 이 불쾌감을 피하기 위해 함수 포인터를 더 읽기 쉬운 것으로 typedef하는 것이 좋습니다. 예를 들어.
typedef void (*functiontype)();
void를 반환하고 인수를받지 않는 함수를 선언합니다. 이 유형에 대한 함수 포인터를 작성하려면 다음을 수행하십시오.
void dosomething() { }
functiontype func = &dosomething;
func();
int를 반환하고 char을 취하는 함수의 경우
typedef int (*functiontype2)(char);
그것을 사용하기 위해
int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');
함수 포인터를 읽기 쉬운 형식으로 바꾸는 데 도움이되는 라이브러리가 있습니다. 부스트 기능 라이브러리는 위대하고 잘 노력 가치가 있습니다!
boost::function<int (char a)> functiontype2;
위의 것보다 훨씬 좋습니다.
typedef
; 더 간단하고 추가 라이브러리가 필요하지 않습니다.
C ++ 11부터는 기능 라이브러리 를 사용하여 간결하고 일반적인 방식으로이 작업을 수행 할 수 있습니다 . 구문은 예를 들어
std::function<bool (int)>
여기서 bool
첫 번째 인수가 유형 인 1 인수 함수의 리턴 유형 int
입니다.
아래에 예제 프로그램이 포함되어 있습니다.
// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
그러나 때로는 템플릿 함수를 사용하는 것이 더 편리합니다.
// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
합격 다른 함수 매개 변수 함수의 주소를 아래와 같이
#include <stdio.h>
void print();
void execute(void());
int main()
{
execute(print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void f()) // receive address of print
{
f();
}
또한 함수 포인터를 사용하여 함수 를 매개 변수로 전달할 수 있습니다
#include <stdio.h>
void print();
void execute(void (*f)());
int main()
{
execute(&print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void (*f)()) // receive address of print
{
f();
}
기능에 따라, 함수 포인터로 "전달"할 수 있습니다 ISO C11 6.7.6.3p8 : " ''기능 반환 형식 포인터 ''로 조정해야한다 ''기능 유형을 반환 '과 같은 매개 변수의 선언 , 6.3에서와 같이 .2.1. ". 예를 들면 다음과 같습니다.
void foo(int bar(int, int));
이것과 같습니다 :
void foo(int (*bar)(int, int));
함수 포인터 를 전달해야합니다 . 문법은 약간 번거롭지 만 일단 익숙해지면 정말 강력합니다.
실제로는 기능이 아니지만 지역화 된 코드입니다. 물론 결과 만 코드를 전달하지는 않습니다. 이벤트 디스패처로 전달되어 나중에 실행될 수 있도록 작동하지 않습니다 (이벤트가 발생할 때가 아니라 결과가 지금 계산되므로). 그러나 그것이 당신이하려는 모든 것이라면 코드를 한 곳으로 현지화합니다.
#include <stdio.h>
int IncMultInt(int a, int b)
{
a++;
return a * b;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 7;
printf("%d * %d = %d\n", a, b, IncMultInt(a, b));
b = 9;
// Create some local code with it's own local variable
printf("%d * %d = %d\n", a, b, ( { int _a = a+1; _a * b; } ) );
return 0;
}
IncMultInt
하겠습니까?
typedef
.