int main(void)
{
return('yes', *"no", **main, *********printf) ("hello world!\n") *0;
}
Run Code Online (Sandbox Code Playgroud)
输出hello world!,但它如何实际工作?
可能重复:
如何解除引用函数指针?
void myprint(char* x) {
printf("%s\n", x);
}
int main() {
char* s = "hello";
void (*test)(char*);
void (*test2)(char*);
test = myprint;
test2 = &myprint;
test(s);
(*test)(s);
test2(s);
(*test2)(s);
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释为什么以上所有代码都有效?"你好"打印四次.通过应用函数指针,它是否隐式解除了?基本上我想知道函数指针是如何实际存储的,因为上面的内容有点令人困惑.
在下面的代码中,函数指针和我认为的"函数引用"似乎具有相同的语义:
#include <iostream>
using std::cout;
void func(int a) {
cout << "Hello" << a << '\n';
}
void func2(int a) {
cout << "Hi" << a << '\n';
}
int main() {
void (& f_ref)(int) = func;
void (* f_ptr)(int) = func;
// what i expected to be, and is, correct:
f_ref(1);
(*f_ptr)(2);
// what i expected to be, and is not, wrong:
(*f_ref)(4); // i even added more stars here like (****f_ref)(4)
f_ptr(3); // everything just works!
// all …Run Code Online (Sandbox Code Playgroud) 我写了一些代码来了解函数指针是如何工作的.我在一些IDE上运行以下C++代码,结果是一样的.
#include "stdafx.h"
int *function(){
static int a=1;
return &a;
}
typedef struct{
int *(*pt_1)();
int *(*pt_2)();
}x_t;
int _tmain(int argc, _TCHAR* argv[])
{
x_t s;
s.pt_1 = function;
s.pt_2 = &function;
printf("%x\n",s.pt_1); //Result: 0x013011a9
printf("%x\n",*s.pt_1); //Result: 0x013011a9
printf("%x\n",**s.pt_1); //Result: 0x013011a9
printf("%x\n",s.pt_1()); //Result: 0x01307000
printf("%x\n",*s.pt_1()); //Result: 1
printf("%x\n",s.pt_2); //Result: 0x013011a9
printf("%x\n",*s.pt_2); //Result: 0x013011a9
printf("%x\n",**s.pt_2); //Result: 0x013011a9
printf("%x\n",s.pt_2()); //Result: 0x01307000
printf("%x\n",*s.pt_2()); //Result: 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
s.pt_1 == s.pt_2 == *s.pt_1 = **s.pt_1 ?s.pt_1()指向何处?它在内存中的位置?我想知道*当我们想要将函数分配给函数指针时,可以多次使用解除引用运算符的具体原因.
作为示例,以下代码完美地编译并运行:
#include <iostream>
void f() { std::cout << "Hello World!" << std::endl; }
int main() {
void(*f_ptr)(void) = ***************************************f;
f_ptr();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 可能重复:
如何解除引用函数指针?
如果我们有
void f() {
printf("called");
}
Run Code Online (Sandbox Code Playgroud)
然后,以下代码将导致"calledcalled"的输出:
f();
(*f)();
Run Code Online (Sandbox Code Playgroud)
我真的不明白这是怎么回事...... *f和之间的区别是f什么?为什么要使用后一种语法调用函数?
void f()
{}
void test()
{
auto fn_1 = f;
auto fn_2 = &f;
assert(fn_1 == fn_2); // OK
fn_1(); // OK
fn_2(); // OK
(*fn_1)(); // OK
(*fn_2)(); // OK
(**fn_1)(); // OK
(**fn_2)(); // OK
(***fn_1)(); // OK
(***fn_2)(); // OK
}
Run Code Online (Sandbox Code Playgroud)
这些行为是否由 C++ 标准明确定义?
我知道当我们使用函数名作为值时,该函数会自动转换为指针.看下面的代码:
int print(int a)
{
return a;
}
int main()
{
int (*p)(int) = print;
int (*q)(int) = &print;
cout << p(8) << endl;
cout << (*p)(8) << endl;
}
Run Code Online (Sandbox Code Playgroud)
为什么int (*p)(int) = print;,打印是一个指针,并且int (*p)(int) = &print;,与打印是一个地址的指针,等价?
另一方面,当我们使用指向函数的指针来调用函数时,为什么p(8)和(*p)(8)等价?
假设我有一个函数指针,如:
void fun() { /* ... */ };
typedef void (* func_t)();
func_t fp = fun;
Run Code Online (Sandbox Code Playgroud)
然后我可以通过以下方式调用它:
fp();
Run Code Online (Sandbox Code Playgroud)
要么
(*fp)();
Run Code Online (Sandbox Code Playgroud)
有什么不同/
可能重复:
如何解除引用函数指针?
大家好,为什么这两个代码给出相同的输出,案例1:
#include <stdio.h>
typedef void (*mycall) (int a ,int b);
void addme(int a,int b);
void mulme(int a,int b);
void subme(int a,int b);
main()
{
mycall x[10];
x[0] = &addme;
x[1] = &subme;
x[2] = &mulme;
(x[0])(5,2);
(x[1])(5,2);
(x[2])(5,2);
}
void addme(int a, int b) {
printf("the value is %d\n",(a+b));
}
void mulme(int a, int b) {
printf("the value is %d\n",(a*b));
}
void subme(int a, int b) {
printf("the value is %d\n",(a-b));
}
Run Code Online (Sandbox Code Playgroud)
输出:
the value is 7
the …Run Code Online (Sandbox Code Playgroud) 我在C++程序中有一个奇怪的typedef语句,由Py ++生成.
double radius(int); // function to be wrapped
typedef double (*radius_function_type)(int);
bp::def("radius", radius_function_type(&radius)); // bp::def is a function for wrapping
Run Code Online (Sandbox Code Playgroud)
到目前为止我想到的是上面的typedef statemnt不是那种类型,我们大多数人都熟悉,
typedef complex_type simple_alias;
Run Code Online (Sandbox Code Playgroud)
相反,它是一种声明指向函数的指针的方法,该函数将int作为参数并返回double(与原型相同).所以现在我的问题是,如何使用函数的地址作为参数来调用指向函数的指针(没有解除引用)?这也与原型不符.有人请解释一下!
我写这篇文章主要是为了澄清我在 Stackoverflow 上偶然发现的一些关于函数指针的令人困惑/误导的信息。
让我们从一个例子开始:
#include <iostream>
void func ()
{
std::cout<<"func here"<<'\n';
}
int main()
{
void (*fp)()=func;
void (&fref)()=func;
func();//call through function
(&func)();//call through function pointer
(*fp)();//call through function
fp();//call through function pointer
fref();//call through function
(&fref)();//call through function pointer
}
Run Code Online (Sandbox Code Playgroud)
这打印:
func here
func here
func here
func here
func here
func here
Run Code Online (Sandbox Code Playgroud)
可以看出,由于函数到函数指针的衰减cppreference,大多数时候可以使用函数来代替函数指针。
函数类型 T 的左值可以隐式转换为指向该函数的纯右值指针。这不适用于非静态成员函数,因为不存在引用非静态成员函数的左值。
但除此之外,函数指针看起来也可以用来代替函数,因为我可以使用它来调用函数而无需显式取消引用。
另请注意,您不需要使用一元 * 来通过函数指针进行调用;两者 (*p1_foo)(); 和 (p1_foo)(); 由于函数到函数指针的转换,具有相同的结果。
还有一个双重的便利:调用位置的函数指针会自动转换为函数值,因此您不必编写 * 来通过函数指针进行调用。
让它看起来好像存在一个隐式函数指针来进行函数转换。
c++ ×11
c ×6
pointers ×5
function ×4
dereference ×1
memory ×1
obfuscation ×1
reference ×1
typedef ×1