다음은 왜 작동합니까?
void foo() {
cout << "Foo to you too!\n";
};
int main() {
void (*p1_foo)() = foo;
void (*p2_foo)() = *foo;
void (*p3_foo)() = &foo;
void (*p4_foo)() = *&foo;
void (*p5_foo)() = &*foo;
void (*p6_foo)() = **foo;
void (*p7_foo)() = **********************foo;
(*p1_foo)();
(*p2_foo)();
(*p3_foo)();
(*p4_foo)();
(*p5_foo)();
(*p6_foo)();
(*p7_foo)();
}
답변
여기에는 이러한 연산자의 모든 조합이 동일한 방식으로 작동 할 수 있도록 몇 가지가 있습니다.
이러한 모든 작업이 수행되는 근본적인 이유는 (와 같은 foo
) 함수가 함수 에 대한 포인터로 암시 적으로 변환 가능하기 때문입니다. 이것이 void (*p1_foo)() = foo;
작동하는 이유 foo
입니다. 암시 적으로 자체에 대한 포인터로 변환되고 해당 포인터가에 할당됩니다 p1_foo
.
단항 &
은 함수에 적용될 때 객체에 적용될 때 객체의 주소를 생성하는 것처럼 함수에 대한 포인터를 생성합니다. 일반 함수에 대한 포인터의 경우 암시적인 함수에서 함수로의 포인터 변환으로 인해 항상 중복됩니다. 어쨌든 이것이 void (*p3_foo)() = &foo;
작동하는 이유 입니다.
단항 *
은 함수 포인터에 적용될 때 객체에 대한 일반 포인터에 적용될 때 지정된 객체를 생성하는 것처럼 뾰족한 함수를 생성합니다.
이 규칙들을 결합 할 수 있습니다. 두 번째에서 마지막 예를 고려하십시오 **foo
.
- 먼저
foo
암시 적으로 자체에 대한 포인터로 변환되고 첫 번째*
는 해당 함수 포인터에 적용되어 함수를foo
다시 생성 합니다. - 그런 다음 결과는 다시 암시 적으로 자신에 대한 포인터로 변환되고 두 번째
*
는 적용되어 다시 함수를 생성합니다foo
. - 그런 다음 암시 적으로 함수 포인터로 다시 변환되어 변수에 할당됩니다.
을 원하는만큼 추가 할 수 *
있으며 결과는 항상 같습니다. *
s가 많을수록 메리 어.
우리는 또한 다섯 번째 예를 고려할 수 있습니다 &*foo
.
- 첫째,
foo
암시 적으로 자신에 대한 포인터로 변환됩니다. 단항*
이 적용되어foo
다시 산출 됩니다. - 그런 다음에
&
가 적용foo
되어에 대한 포인터가 생성foo
되고 이에 변수가 할당됩니다.
은 &
전용은 아니지만 (함수 포인터로 변환 된 함수에 대한 함수에 적용 할 수 물론 함수 포인터 결과가 가리키는 포인터 A-포인터 타입 인 경우의 변수이며, 않으면 기능을 수행합니다 (예 : 목록에 추가 할 수 있음 void (**pp_foo)() = &p7_foo;
).
이것이 &&foo
작동하지 않는 이유입니다 &foo
. 함수가 아닙니다. rvalue 인 함수 포인터입니다. 그러나 &*&*&*&*&*&*foo
마찬가지로, 일하는 것이 &******&foo
있기 때문에 그 표현의 모두에서 &
항상 함수에 아닌를 rvalue의 함수 포인터에 적용됩니다.
*
함수 포인터를 통해 호출 할 때 단항식 을 사용할 필요는 없습니다 . 모두 (*p1_foo)();
와 (p1_foo)();
다시 때문에 함수에 대한 함수 포인터 변환에, 동일한 결과를 갖는다.
답변
C는 기본 시스템에 대한 추상화 일 뿐이며 추상화가 유출되는 곳 중 하나라는 것을 기억하는 것이 도움이된다고 생각합니다.
컴퓨터의 관점에서 볼 때 기능은 메모리 주소 일 뿐이며 실행되면 다른 명령을 수행합니다. 따라서 C의 함수 자체는 주소로 모델링되므로 함수가 가리키는 주소와 “동일한”디자인으로 이어질 수 있습니다.
답변
&
및 *
심볼에 멱등 작업 C의 함수로서 선언하는 수단 func == *func == &func == *&func
이므로*func == **func
이 유형을 의미 int ()
와 동일 int (*)()
기능의 파라미터로서 전달 될 수있는 정의 FUNC로서 *func
, func
또는 &func
. (&func)()
와 동일합니다 func()
. Godbolt 링크.
함수는 따라서 정말 주소 *
와 &
의미가 없으며, 대신 오류를 생산, 컴파일러 선택한다면이 FUNC의 주소로 해석 할 수 있습니다.
&
기호 함수 포인터를 선언하지만 (지금 별도의 목적을 가지고 있기 때문에) 포인터의 주소를 얻을 것이다 반면 funcp
와 *funcp
동일 할 것이다