我在另一个stackexchange网站上的一个流行答案中遇到了此代码,但我仅了解其背后的部分语法和用途:
static const unsigned char code[] = "\xb0\x2a\xc3";
int value;
value = (*(uint8_t(*)())code)();
据我所知,十六进制字符数组(语法上表示为char指针)被强制转换为无符号整数。但是我不明白的是:
括号
a。,尤其是那些在结束分号之前的末尾,使得好像code
数组被称为函数
b。。紧跟uint8_t
之后的一对包含星号
星号
a。被取消引用的内容和顺序?
b。为什么将星号传递给uint8_t
?
unsigned char
和uint8_t
的大小不同,是否可以使用? 答案 0 :(得分:2)
十六进制字符数组(语法上表示为char指针)
不。 “十六进制字符”不是一回事。另外,那里没有char指针。
code
是无符号字符(即字节)的数组。此数组包含4个元素:0xb0
,0x2a
,0xc3
,0x00
(或等效的:176
,42
,195
,0
)。
类型uint8_t (*)()
不是一个无符号整数,它是指向返回uint8_t
的函数(无参数)的指针。
(*(uint8_t(*)())code)()
中发生的事情:
表达式中有code
(一个数组)。它不是sizeof
或&
的操作数,因此它会衰减为指向其第一个元素的指针。
此指向unsigned char *
的指针(类型为code[0]
)被强制转换为其他类型:uint8_t (*)()
,即,指向返回uint8_t
的函数的指针。
强制类型转换的一般形式为( TYPE ) EXPR
。这里我们有TYPE
的{{1}},而我们的int8_t (*)()
是EXPR
。
该函数指针被取消引用(使用code
),从而产生一个函数。此操作是多余的,因为任何函数值都会立即衰减回指针(除非它是*
的操作数,在这种情况下,无论如何您都将返回函数指针)。
最后一对配对&
确实调用了函数指针。
此代码实际执行的操作与平台高度相关。在某些平台上,将数据指针转换为函数指针会为您提供一个“函数”,其代码由数据指定,即最终跳转到()
并将其内容作为机器代码执行。