함수 포인터 정의가 앰퍼샌드 '&' 또는 아스터리스크 '*'의 수에 관계없이 작동하는 이유는 무엇입니까?
왜 다음 기능이 작동합니까?
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
- 다음, 그 는 다시 으로 그 와 두 번째 됩니다.
*
is. function. function. function. . is. is. is. is. is. is. is. is.foo
. - 그런 다음 함수의 포인터로 암묵적으로 변환되어 변수에 할당됩니다.
개라도 수 요.*
이치 .*
스스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스 스
사례인 '하다'도 해 볼 수 .&*foo
:
- ㅇㅇㅇㅇㅇ,
foo
그 자체에 은 단항으로 변환됩니다.*
foo
- 다음, '우리'는
&
적용되다foo
foo
이것은 변수에 할당됩니다.
&
할 수 이 포인터에 대한 에 추가할 수 있습니다. 을 사용하다void (**pp_foo)() = &p7_foo;
를 참조해 주세요.
★★★★★&&foo
하지 않습니다.&foo
함수가 아니라 r값인 함수 포인터입니다. ★★★★★★★★★★★★★★.&*&*&*&*&*&*foo
있을 &******&foo
는 두 표현 '''가 이기 때문입니다.&
는 항상 함수에 적용되며 rvalue 함수 포인터에는 적용되지 않습니다.
하시기 바랍니다.*
포인터를 둘 다 '기능 포인터'입니다.둘다(*p1_foo)();
★★★★★★★★★★★★★★★★★」(p1_foo)();
기능-기능 변환으로 인해 동일한 결과를 얻을 수 있습니다.
C는 기본 머신에 대한 추상화일 뿐이며, 이 추상화가 누출되고 있는 장소 중 하나임을 기억하는 것도 도움이 될 것 같습니다.
컴퓨터의 관점에서 함수는 실행되면 다른 명령을 실행하는 메모리 주소일 뿐입니다.따라서 C의 함수는 그 자체가 주소로 모델링되며, 이는 함수가 가리키는 주소와 "동일"한 설계로 이어질 수 있습니다.
&
★★★★★★★★★★★★★★★★★」*
연산입니다.즉, C의 함수로 선언된 는 C의 등가 입니다.func == *func == &func == *&func
, 「」입니다.*func == **func
해요, 하다, 하다, 하다, 하다, 하다, 하다.
은 '함수'로 할 수 .int ()
★★★★★★★★★★★★★★★★★」int (*)()
, , , , , , , , , , , , , , , , , , , , , , , , , .*func
,func
★★★★★★★★★★★★★★★★★」&func
. 에 전화하고 있습니다부르기(&func)()
is is is is is와 func()
★★★★★★★★★★★★★★★★★」(*func)()
. Godbolt 링크.
*
★★★★★★★★★★★★★★★★★」&
함수 기호에는 아무런 의미가 없으며, 컴파일러는 오류를 생성하는 대신 두 경우 모두 func의 주소로 해석합니다.기호와 포인터로 , 이 함수는 배열 기호와 같이 별도의 포인터로 존재하지 않습니다.&arr
is is is is is와 arr
실행 시 주소가 있는 물리 포인터가 아니기 때문에 컴파일러 수준의 논리 포인터입니다. ★★★★★★★★★★★★★★★★.*func
코드 섹션인 함수 코드의 첫 번째 바이트를 읽고, 컴파일러 오류를 발생시키거나 런타임 오류 분할 장애를 허용하는 대신, 컴파일러에 의해 함수의 주소로 해석됩니다.
&
가 취득됩니다( 또는 섹션에 입니다)., 이 경우, 「Pointer」는 「Pointer」의 주소를 취득합니다.funcp
★★★★★★★★★★★★★★★★★」*funcp
는 여전히 함수의 주소로 해석됩니다.
" " 를 할 foo
호출하는 수 (*p1_foo)()
pi_foo()
.
아직도 @JamesMcNellis의 답변에 납득이 가지 않는다면, 여기 그 증거가 있다.Clang 컴파일러의 AST(추상 구문 트리)입니다.추상 구문 트리는 컴파일러 내부의 프로그램 구조의 내부 표현입니다.
void func1() {};
void test() {
func1();
(*func1)();
(&func1)();
void(*func1ptr)(void) = func1;
func1ptr();
(*func1ptr)();
//(&func1ptr)();//error since func1ptr is a variable, &func1ptr is its address which is not callable.
}
아스트:
//func1();
|-CallExpr //call the pointer
| `-ImplicitCastExpr //implicitly convert func1 to pointer
| `-DeclRefExpr //reference func1
//(*func1)();
|-CallExpr //call the pointer
| `-ImplicitCastExpr //implicitly convert the funtion to pointer
| `-ParenExpr //parentheses
| `-UnaryOperator //* operator get function from the pointer
| `-ImplicitCastExpr //implicitly convert func1 to pointer
| `-DeclRefExpr //reference func1
//(&func1)();
|-CallExpr //call the pointer
| `-ParenExpr //parentheses
| `-UnaryOperator //& get pointer from func1
| `-DeclRefExpr //reference func1
//void(*func1ptr)(void) = func1;
|-DeclStmt //define variable func1ptr
| `-VarDecl //define variable func1ptr
| `-ImplicitCastExpr //implicitly convert func1 to pointer
| `-DeclRefExpr //reference func1
//func1ptr();
|-CallExpr //call the pointer
| `-ImplicitCastExpr //implicitly convert func1ptr to pointer
| `-DeclRefExpr //reference the variable func1ptr
//(*func1ptr)();
`-CallExpr //call the pointer
`-ImplicitCastExpr //implicitly convert the function to pointer
`-ParenExpr //parentheses
`-UnaryOperator //* get the function from the pointer
`-ImplicitCastExpr //implicitly convert func1ptr to pointer
`-DeclRefExpr //reference the variable func1ptr
언급URL : https://stackoverflow.com/questions/6893285/why-do-function-pointer-definitions-work-with-any-number-of-ampersands-or-as
'programing' 카테고리의 다른 글
Python의 eval()은 무엇을 합니까? (0) | 2023.01.29 |
---|---|
MySQL Like 다중값 (0) | 2023.01.29 |
Spring MVC 3 컨트롤러에서 문자열 메시지만 반환 (0) | 2023.01.29 |
명령줄 인수를 npm 스크립트로 보내는 중 (0) | 2023.01.29 |
Mesos 또는 Core에서 MariaDB 및 Redis의 고가용성 클러스터를 설정하는 방법OS (0) | 2023.01.29 |