`((void (*)())0x1000)();` 是什么意思?
What does `((void (*)())0x1000)();` mean?
这是一段代码,目的是设置程序计数器跳转到地址0x1000
。我知道它是做什么的,但我不明白它是怎么做的。这与我对C语言知识的缺乏有关。也许你能启发我。这是 statement/function(我什至不知道它是什么:))
((void (*)())0x1000)();
我认为它是指向 returns void
并且不接受任何参数的函数的指针。如有不妥请指正
(void (*)())
是指向返回 void
并采用未指定但固定数量的参数的函数的指针。
(void (*)())0x1000
是 将 文字 0x1000
转换为上述类型。
最后,后缀()
调用那个函数。前面的表达式需要放在方括号中,否则后缀 ()
将绑定到语法上无效的 0x1000
。
由您来检查转换是否真的有效。如果不是,那么您的程序的行为是 undefined.
常数
0x1000
转换为类型:
(type)0x1000
类型是 void (*)()
— 指向函数的指针(星号),该函数采用 no(哎呀,请参阅 )未指定数量的 个参数(右边的空括号)和 returns 没有值(左边的 void
)。星号上的其他括号阻止将其与 void
相关联,这会在此处错误地创建 void *
类型。
所以在转换之后你有一个指向地址 0x1000:
的 无参数 void 函数的指针
(void (*)())0x1000
那个函数...
((void (*)())0x1000)
通过添加一个空参数列表来调用:
((void (*)())0x1000)()
最后,最后加的分号把这个函数调用表达式变成了一条完整的指令:
((void (*)())0x1000)();
C
声明使用一个简单的规则从内向外解码:从标识符开始并在右侧检查 []
(数组)或 ()
(函数)然后检查左侧值的类型(存储在数组中或由函数 returned),不要穿过括号;从括号中转义并重复。
例如:
void (*p)()
p
是(右边没有)一个指针(左边,不要越过括号)到(避开括号,阅读下一级)一个函数(右)那个return什么都没有(左)。
当标识符(在本例中为 p
)丢失时,剩下的就是类型声明。
括号中的类型,放在值前面的是类型转换。
(void (*)())0x1000
将数字 0x1000
转换为一个 指向一个函数的指针,该函数 return 没有任何东西 (请参阅关于以上 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();
代码的作用现在几乎已经自我记录。
这是一段代码,目的是设置程序计数器跳转到地址0x1000
。我知道它是做什么的,但我不明白它是怎么做的。这与我对C语言知识的缺乏有关。也许你能启发我。这是 statement/function(我什至不知道它是什么:))
((void (*)())0x1000)();
我认为它是指向 returns void
并且不接受任何参数的函数的指针。如有不妥请指正
(void (*)())
是指向返回 void
并采用未指定但固定数量的参数的函数的指针。
(void (*)())0x1000
是 将 文字 0x1000
转换为上述类型。
最后,后缀()
调用那个函数。前面的表达式需要放在方括号中,否则后缀 ()
将绑定到语法上无效的 0x1000
。
由您来检查转换是否真的有效。如果不是,那么您的程序的行为是 undefined.
常数
0x1000
转换为类型:
(type)0x1000
类型是 void (*)()
— 指向函数的指针(星号),该函数采用 no(哎呀,请参阅 void
)。星号上的其他括号阻止将其与 void
相关联,这会在此处错误地创建 void *
类型。
所以在转换之后你有一个指向地址 0x1000:
的(void (*)())0x1000
那个函数...
((void (*)())0x1000)
通过添加一个空参数列表来调用:
((void (*)())0x1000)()
最后,最后加的分号把这个函数调用表达式变成了一条完整的指令:
((void (*)())0x1000)();
C
声明使用一个简单的规则从内向外解码:从标识符开始并在右侧检查 []
(数组)或 ()
(函数)然后检查左侧值的类型(存储在数组中或由函数 returned),不要穿过括号;从括号中转义并重复。
例如:
void (*p)()
p
是(右边没有)一个指针(左边,不要越过括号)到(避开括号,阅读下一级)一个函数(右)那个return什么都没有(左)。
当标识符(在本例中为 p
)丢失时,剩下的就是类型声明。
括号中的类型,放在值前面的是类型转换。
(void (*)())0x1000
将数字 0x1000
转换为一个 指向一个函数的指针,该函数 return 没有任何东西 (请参阅关于以上 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();
代码的作用现在几乎已经自我记录。