andrewrk
그는 물었다 12년 전
9

반군지역 더 매개변수입니다 in C 함수 포인터

39, m, s # 39 라고 let& I& 생성하기에 체스 프로그램. I have a 함수

void foreachMove( void (*action)(chess_move*), chess_game* game); 

함수 포인터 작업이든지 security. 이를 각 유효함 움직이십시오. 이게 다 좋아요, 하지만 와일드링이 데릭쉐퍼드와 더 잘 전달하는 매개 변수를 작업이든지 함수은? 예를 들면 다음과 같습니다.

chess_move getNextMove(chess_game* game, int depth){
  //for each valid move, determine how good the move is
  foreachMove(moveHandler, game);
}

void moveHandler(chess_move* move){
  //uh oh, now I need the variables "game" and "depth" from the above function
}

함수 포인터가 재정의하지 최적의 솔루션을 아니다. 이 기능은 여러 곳에 포에라히모프 다용도이면서도 코드 참조 거잖나. # 39, it doesn& 쉽게 이해할 수 없는 것으로 각 선택기에 업데이트하려면 이러한 참조 함수를 don& # 39, 그들은 그들의 포함시키십시오 매개변수입니다 필요한 건 아니다.

39 m, 지나갈 수 있는 방법을 통해 추가 매개 변수를 I& 함수를 호출하는 포인터를?

답변 9 개

아, 수만 있다면 캜 지원 대상 클로저.

안토니오 바로. # 39, ll, 필요할 경우 추가 매개변수입니다 you& 너회의 재정의하려면 전달해야 하는 함수 포인터 수락하려면 추가 인수. # 39 don& 경우, 필요한 것이 무엇인지 정확히 모르는 you& 매개변수입니다, ll, 그럼 # 39 가 적어도 3 가지 선택.

  1. 프로토타입 (prototype) 에 있는 마지막 인수가 박스트롤의 void *. 하지만 이 수 있는 유연성을 필요로 하는 다른 사항은요 반군지역 말해둘꼐요 isn& # 39, t 안전하다구요 유형.
  2. 바리아디스 매개변수입니다 사용하여 (.). # 39 m, C 에서, 내 경험 부족이 바리아디스 매개변수입니다 I& 때 함께 사용할 수 있는지 확신하지 못하고 있지만, 이를 통해 보다 더 유연도를 함께 이 함수 포인터, 비록 첫 번째 해결책을 함께 여전히 부족한 타입 안전.
  3. 업그레이드합니다 c++컴파일러는 및 사용 [함수 객체] (http://en.wikipedia.org/wiki/Function_object).

D # 39 를 추가 인수를 시행하십시오 함수 포인터 재정의하려면 you& 할 것이다.

void foreachMove( void (*action)(chess_move*, int), chess_game* game )

39, re 사용할 수 있다는 일부 c++컴파일러는 you& 경우, 함수, &quot object&quot 사용할 수 있습니다.

struct MoveHandler {
    chess_game *game;
    int depth;

    MoveHandler(chess_game *g, int d): game(g), depth(d) {}

    void operator () (chess_move*) {
         // now you can use the game and the depth
    }
};

네,, /code&gt foreachMove&lt code&gt 및 선반가공 &lt. 붙여넣습니다 템플리트를:

template <typename T>
void foreachMove(T action, chess_game* game);

이와 같이 선고하게 수 있습니다.

chess_move getNextMove(chess_game* game, int depth){
    //for each valid move, determine how good the move is
    foreachMove(MoveHandler(game, depth), game);
}

하지만, t # 39 의 다른 용도, 중단, MoveHandler&lt code&gt won& 너회의 &lt /code>;).

39 이 경우, d, m 판독값 I& 오른쪽맞춤, # 39 는 어떤 함수를 만들 수 있는 시행하십시오 I& 제안하세요 포인터입니다 구조체입니다 인수로. 그 후, game&quot 너회의 구조체입니다 &quot 가질 수 있습니다. 및 &quot depth"; 필요할 때 바로 그 때 그 남겨두십시오 설정되었습니다 0 또는 Null # 39 don& 저들이요 필요한 건 아니다.

어떤 일이 진행되고 있는 함수은? Do you have a 조건부 한다고

if (depth > -1) //some default
  {
  //do something
  }

항상 필요한 기능을 높여줍니까 &quot game"; 그리고 depth&quot ";? 그들은 항상 인수, 들어갈 수 있는 너회의 프로토타입.

가끔 필요한 기능만 제환자의 찼음을 나타내는 &quot game"; 그리고 depth&quot ";? 뭐, 아마 각각 두 가지 기능을 사용할 수 있도록 할 때.

그러나 인수로 갖는 구조를 요소라고 할 수 있는 가장 쉬운 일이다.

D # 39 를 사용하여 제안하세요 i& void * 배열입니다 항상 마지막 엔트리여야 void. 이 3 매개변수입니다 할 수 있다고 합니다.

void MoveHandler (void** DataArray)
{
    // data1 is always chess_move
    chess_move data1 = DataArray[0]? (*(chess_move*)DataArray[0]) : NULL; 
    // data2 is always float
    float data1 = DataArray[1]? (*(float*)DataArray[1]) : NULL; 
    // data3 is always char
    char data1 = DataArray[2]? (*(char*)DataArray[2]) : NULL; 
    //etc
}

void foreachMove( void (*action)(void**), chess_game* game);

다음

chess_move getNextMove(chess_game* game, int depth){
    //for each valid move, determine how good the move is
    void* data[4];
    data[0] = &chess_move;
    float f1;
    char c1;
    data[1] = &f1;
    data[2] = &c1;
    data[3] = NULL;
    foreachMove(moveHandler, game);
}

만약 모든 매개변수입니다 유형이 같은 그런 피할 수 있는 모든 유형 및 그냥 전송하십시오 어레이입니다 void * 어레이입니다 null 종료 합니다.

대신 '구조' 로 또 다른 옵션은 약간만이라도 수정하십시오 chess_move 함수은 프로토타입. 이미 정의된 배치하십시오 구조는 단 한 것이다. 추가 멤버 구조에 대한 적절한 구조 및 칠합니다 전에 데이터를 사용하는 모든 호출하십시오 거잖나.

메리 페데프 사용하여 함수에 대한 포인터. [답변] [1] 의 이 질문 보러

9421 [1]:

아니, 차라리 선언은 함수 포인터를 사용하여 변경할 경우 매개변수입니다 변경하십시오 &quot ."; 기법을 셋업하기 수를 가변적입니다 인수만. 또한 변경할 수 있는 됐을 수도 있다고 가독성 및 각 매개변수입니다 전달할 필요가 있다. 그것은 확실히 많이유 훨씬 더 안전해 반군지역 무효가 되어 있다.

http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html

그냥 오버클로킹된 FYI, 정보 예제 코드 있는 링크: 그들은 "이는 n_args" 와 "n args" 및 기타 일부 묘지에는 밑줄. 모두 밑줄 한다. 구문은 약간 이상한 걸 보니 생각해봤죠 때까지 자신들이 떨어트림 밑줄 일부 있다.

+1 을 안토니오씨 함수 포인터 변경하십시오 수락하려면 선언을 할 때 추가 매개변수입니다.

또한 void 포인터 또는 desktopplatforms don& # 39 의 void 포인터 (특히), t start 반군지역 수립하였습니다 어레이에는. # 39 의 그냥 that& 묻는 문제입니다. Void 포인터, you& 반군지역 시작하면 # 39, re) 로 하고 또 어떤 메시지를 전달해야 함정이거나 나타내십시오 포인터입니다 유형은 (또는 유형은). 이 기법은 거의 적절한.

항상 같은 경우, 함수 포인터 그들을 추가하기만 매개변수입니다 데이터베이스에구성원을 인수 (또는 기타 팩과도 묶습니다 인수로 구조체입니다 및 사용하는 경우에는 많은 매개변수). 함수 포인터를 사용하여 변경할 경우 매개변수입니다 관심용 여러 콜 대신 반군지역 void 포인터 대한 여러 고려해보십시오 시나리오용으로.