우리가 어떻게 여기
기능 점을 선언하기위한 C 구문은 사용법을 반영하기위한 것입니다. 다음과 같은 정규 함수 선언을 고려하십시오 <math.h>
.
double round(double number);
점 변수를 가지려면 다음을 사용하여 유형 안전으로 지정할 수 있습니다
fp = round;
fp
이 방법으로 해당 점 변수를 선언해야합니다 .
double (*fp)(double number);
따라서 함수를 사용하는 방법을 살펴보고 해당 함수의 이름을 포인터 참조 round
로 바꾸십시오 *fp
. 그러나 여분의 파렌 세트가 필요합니다.
아마도 이것은 원래 C에서 더 쉬웠습니다. 기능 서명조차 없었지만 다시 돌아 가지 않습니까?
특히 불쾌한 곳은 인수로 사용하거나 함수에 대한 포인터를 반환하는 함수를 선언하는 방법 또는 둘 다를 결정하는 방법을 파악하는 것입니다.
기능이 있다면 :
void myhandler(int signo);
이 방법으로 신호 함수 (3)에 전달할 수 있습니다.
signal(SIGHUP, myhandler);
또는 이전 핸들러를 유지하려면
old_handler = signal(SIGHUP, new_handler);
꽤 쉽습니다. 아주 쉽고도 쉬운 것도 선언을 올바르게하는 것입니다.
signal(int signo, ???)
글쎄, 당신은 함수 선언으로 돌아가서 포인트 참조를 위해 이름을 바꾼다.
signal(int sendsig, void (*hisfunc)(int gotsig));
선언하지 않기 때문에 gotsig
생략하면 더 쉽게 읽을 수 있습니다.
signal(int sendsig, void (*hisfunc)(int));
아니면 아닐 수도 있습니다. :(
signal (3)도 다음과 같이 이전 핸들러를 반환하기 때문에 충분하지 않습니다.
old_handler = signal(SIGHUP, new_handler);
이제 모든 것을 선언하는 방법을 알아야합니다.
void (*old_handler)(int gotsig);
할당하려는 변수에 충분합니다. gotsig
여기서 실제로 선언하지는 않습니다 old_handler
. 그래서 이것으로 충분합니다.
void (*old_handler)(int);
그러면 signal (3)에 대한 올바른 정의가 나타납니다.
void (*signal(int signo, void (*handler)(int)))(int);
구조에 Typedefs
이번에는 모든 사람들이 그것이 엉망이라는 데 동의 할 것이라고 생각합니다. 때로는 추상화의 이름을 지정하는 것이 좋습니다. 종종, 정말로. right를 사용하면 typedef
이해하기가 훨씬 쉬워집니다.
typedef void (*sig_t) (int);
이제 자신의 핸들러 변수가됩니다.
sig_t old_handler, new_handler;
signal (3)에 대한 선언은
sig_t signal(int signo, sig_t handler);
갑자기 이해할 수 있습니다. *를 제거하면 혼란스러운 괄호도 제거됩니다 (그리고 그들은 parens가 항상 이해 하기 쉬워집니다 . 사용법은 여전히 동일합니다.
old_handler = signal(SIGHUP, new_handler);
그러나 이제 old_handler
,에 대한 선언을 이해하고 처음 접하게되거나 작성해야 할 때 new_handler
조차 이해할 signal
수 있습니다.
결론
아주 소수의 C 프로그래머, 알고 보니, 참고 자료상의없이 자신의 이러한 것들에 대한 올바른 선언을 고안 할 수있다.
커널과 장치 드라이버 작업을하는 사람들을위한 인터뷰 질문에이 질문이 있었기 때문에 알고 있습니다. :) 물론, 우리는 그들이 화이트 보드에 충돌하고 불에 타는 방식으로 많은 후보자를 잃었습니다. 그러나 우리는 또한이 분야에서 이전에 경험이 있다고 주장했지만 실제로는 일을 할 수없는 사람들을 고용하지 않았습니다.
그러나 이러한 광범위한 어려움으로 인해 더 이상 현명하지는 않지만 실제로는 이것을 사용하는 평균보다 세 시그마 위에 앉아있는 트리플 알파 괴짜 프로그래머가 아니어야하는 모든 선언에 대해 갈 수있는 방법을 갖는 것이 합리적입니다. 편안하게
f :: (Int -> Int -> Int) -> Int -> Int