C “((void(*)0x1000)();”是什么意思什么意思?

C “((void(*)0x1000)();”是什么意思什么意思?,c,pointers,void,C,Pointers,Void,下面是一段代码,用于将程序计数器设置为跳转到地址0x1000。我知道它是做什么的,但我不知道怎么做。这与我缺乏C语言知识有关。也许你能启发我。下面是语句/函数(我甚至不知道它是什么:) 我认为它是指向返回void且不接受任何参数的函数的指针。如果我错了,请更正。(void(*)()是指向返回void并接受未指定但固定数量参数的函数的指针 (void(*)()0x1000正在将文本0x1000强制转换为上述类型 最后,后缀()调用该函数。前面的表达式需要放在括号中,否则后缀()将绑定到语法无效的0

下面是一段代码,用于将程序计数器设置为跳转到地址
0x1000
。我知道它是做什么的,但我不知道怎么做。这与我缺乏C语言知识有关。也许你能启发我。下面是语句/函数(我甚至不知道它是什么:)

我认为它是指向返回
void
且不接受任何参数的函数的指针。如果我错了,请更正。

(void(*)()
是指向返回
void
并接受未指定但固定数量参数的函数的指针

(void(*)()0x1000
正在将文本
0x1000
强制转换为上述类型

最后,后缀
()
调用该函数。前面的表达式需要放在括号中,否则后缀
()
将绑定到语法无效的
0x1000

这取决于你去检查演员是否真的有效。如果不是,则程序的行为是未定义的。

一个常量

0x1000
获取对类型的强制转换:

(type)0x1000
类型为
void(*)(
)-指向函数的指针(星号),该函数不接受任何参数(右侧为空括号)(oops,请参见)且不返回任何值(左侧为
void
)。星号上的附加参数防止将其与
void
关联,这将错误地在此处创建
void*
类型

因此,在强制转换之后,在addres 0x1000处有一个指向无参数void函数的指针:

(void (*)())0x1000
而这个功能

((void (*)())0x1000)
通过添加空参数列表调用:

((void (*)())0x1000)();

C
声明使用一个简单的规则从内到外进行解码:从标识符开始,在右侧检查
[]
(数组)或
()
(函数),然后在左侧检查值的类型(存储在数组中或由函数返回),而不跨越括号;从括号中转义并重复

例如:

void (*p)()
p
是一个指针(在左边,不要穿过括号),指向(转义括号,读取下一级)一个函数(右边),该函数不返回任何内容(左边)

当标识符(
p
在本例中)丢失时,剩下的就是类型声明

放在值前面的括号中的类型是类型转换

(void (*)())0x1000
将数字
0x1000
转换为指向不返回任何内容的函数的指针(请参见上文关于
p
声明的段落中括号外的内容)

在下一个级别,上面的表达式(指向函数的指针可以与函数名相同的方式使用)用于执行指向的代码

请参见下面的完整表达式分解:

(
  (
    void (*)()   /* type: pointer to function that doesn't return anything     */
  )0x1000        /* value 0x1000 treated as a value of the type declared above */
)                /* enclose in parentheses to specify the order of evaluation  */ 
();              /* the pointer above used as a function name to run the code  */

编写该代码的人员应以可读的方式将其改写为:

#define ADDRESS_OF_FUNCTION_X 0x1000

typedef void (*func_ptr_t)(void);

...

func_ptr_t function_x = (func_ptr_t)ADDRESS_OF_FUNCTION_X;
function_x();

代码的功能现在基本上是自我记录的。

运行此代码的平台和CPU是什么?如果您试图调用具有已知固定地址的过程,例如BIOS过程,则可以使用此语句。在旧的IBM PC中,您可以调用
(void(*far)()0xfffff0ul
。这个过程会重新启动电脑。当你在应该维护的代码中找到它时,我觉得这有一个副词“F**k you”。再说一次,作为一个非C开发人员,所有的C在我看来都是一团乱麻,所以我可能完全错了。cdecl不能很好地解释这一点,但它给出了一个完全可读的英文描述。@QPaysTaxes一旦你稍微习惯了C/C++(成员)函数指针符号,那么实际上阅读起来相当容易。然而,仍然将文本转换为函数指针并调用它是一个相当“WTF”的操作。。。除非你是在操作系统之外写作。。。。函数,该函数接受未指定但固定数量的参数。要成为一个不带参数的函数,它应该是
void(*)(void)
(哦,请参见pmg的评论)“为什么你的答案不包括这个呢?不完全正确。另外,
void(*)(
是指针,但在某些情况下它不是有效的声明语句,因为缺少该指针的标识符。此声明有效:
void call_a_ptr(void(*)())-它声明一个函数,该函数使用指向返回void且不带参数的函数的指针。是的,但这并不能解释为什么其他语法会这样做。@ArturoTorresSánchez如果将整数强制转换为函数指针,该整数将变为函数的地址。就像任何其他整数到指针转换一样,将整数转换为地址。然后调用这个函数。还有什么要解释的?我想OP已经熟悉指针的工作原理了。这不是真正复杂的代码,原来的只是有点不可读。
#define ADDRESS_OF_FUNCTION_X 0x1000

typedef void (*func_ptr_t)(void);

...

func_ptr_t function_x = (func_ptr_t)ADDRESS_OF_FUNCTION_X;
function_x();