CosyOS
发表于 2024-10-26 00:43:15
本帖最后由 CosyOS 于 2024-10-26 00:46 编辑
sdwys 发表于 2024-10-25 22:49
/* 查询标志组 */
#define sTSV_QueryFlagGroup(group) \
( \
#define sTSV_QueryFlagGroup(group) \
( \
sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false \
: sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \
: sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \
: false \
)
我给你换一种写法来理解它的层次结构:
if(sizeof(group) == 1){
*(s_u8_t*)&group ? true : false
}
else{
if(sizeof(group) == 2){
*(s_u16_t *)&group ? true : false
}
else{
if(sizeof(group) == 4){
*(s_u32_t *)&group ? true : false
}
else{
false
}
}
}
这个写法只是为了让你好理解运算优先级、语句结构,实际这样写是非法的。
必须采用全部三目运算的写法,
原因是:
1、需要返回值
2、三目运算可实现常量优化
sizeof()也是常量优化的,所以最终优化后的结果就是:
假设 sizeof(group) 为 2,
sTSV_QueryFlagGroup(group) 被宏替换后为:*(s_u16_t *)&group ? true : false
所以,看似一大堆代码,被编译器优化后仅有一句C代码,其它都被优化掉了。
stb988
发表于 2024-10-26 09:07:14
打卡学习中,
mengzehua
发表于 2024-10-27 10:56:53
请好,我下载附件的例程,用Keil uVision5 C251无法编译,打开实验箱的例程能编译,就这个RTOS不能编译,能告诉我是用什么软件或者哪个版本来打开吗?
CosyOS
发表于 2024-10-27 12:03:19
mengzehua 发表于 2024-10-27 10:56
请好,我下载附件的例程,用Keil uVision5 C251无法编译,打开实验箱的例程能编译,就这个RTOS不能编译,能 ...
看下你下载的是哪个例程?
例程有 STC8H 的,有 STC32G 的,
STC8H 用 Keil uVision5 C51,
STC32G 用 Keil uVision5 C251,
版本应该别太老就行。
例程都是经过实测的,你可能哪里没搞对。
mengzehua
发表于 2024-10-27 21:35:20
好的,谢谢,我找到原因了,我下载的是STC8例程,我没有安装STC8的型号和头文件,所以无法编译,下载STC32G例程,就就可以打开编译了,我先看你的视频和学习,谢谢了
sdwys
发表于 2024-10-27 21:57:02
CosyOS 发表于 2024-10-26 00:43
#define sTSV_QueryFlagGroup(group) \
( \
sizeof(group) == 1 ? *(s_u8_t*)&group ? true : ...
这种写法我百度查了好久,没找到相关资料,这个是宏预处理器支持的一种写法吗?还请作者解惑。
CosyOS
发表于 2024-10-28 00:06:39
本帖最后由 CosyOS 于 2024-10-28 03:16 编辑
sdwys 发表于 2024-10-27 21:57
这种写法我百度查了好久,没找到相关资料,这个是宏预处理器支持的一种写法吗?还请作者解惑。
...
首先是了解 三目运算。
(条件表达式) ? 表达式1 : 表达式2;
如果条件表达式为真,执行表达式1并返回结果;
否则,执行表达式2并返回结果。
如果 表达式1 或 表达式2 无法返回结果,有些编译器不能支持。
如a > b ? 1 : _nop_();
空操作的执行结果是无值的,无法返回结果,有些编译器不能支持这种写法。
然后是 三目运算 可进行常量优化。
这指的是 三目运算可对条件判断和执行分支进行常量优化。也就是说
在编译时,如果条件表达式能直接确定为真或为假,直接选择表达式1或表达式2,其它全部优化掉。
三是如何理解这种写法的运算优先级或是语句结构。
为了能更好的表述,先做如下处理,加括号是为了便于区分,不用真写:
#define sTSV_QueryFlagGroup(group) \
(sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false \
: (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \
: (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \
: false)))
由于 == 的优先级高于 三目运算 ? : 的优先级,所以,
sizeof(group) == 1 等,结合到一起;
由于三目运算是从右到左结合,所以从最后向前结合,
: false
: false
两个 : 结合不了,而后, *(s_u32_t *)&group ? true : false
可结合为一组三目运算;
而后再结合,
(sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
: false)
可结合为一组三目运算;
而后再结合,
: false
: (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
: false)
两个 : 结合不了,而后, *(s_u16_t *)&group ? true : false
可结合为一组三目运算;
而后再结合,
(sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
: (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
: false))
可结合为一组三目运算;
而后再结合,
: false
: (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
: (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
: false))
两个 : 结合不了,而后, *(s_u8_t*)&group ? true : false
可结合为一组三目运算;
而后再结合,
(sizeof(group) == 1 ? *(s_u8_t*)&group ? true : false
: (sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false
: (sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false
: false)))
可结合为一组三目运算;
所以,这就是单纯的三目运算,只是如何结合,如何划分语句结构的问题。
-- 全剧终 --
可累 我了。。。
当然,再就是实验验证。
可以不用标志组,分别弄3个全局变量,分别为 u8、u16、u32 的,
然后分别调用,编译,看反汇编到底都做了什么?
Matrix
发表于 2024-10-28 10:58:05
非常不错 ,国产原创 RTOS for 32位8051,STC32G12K128
CosyOS
发表于 2024-10-28 14:15:20
CosyOS 发表于 2024-10-28 00:06
首先是了解 三目运算。
(条件表达式) ? 表达式1 : 表达式2;
如果条件表达式为真,执行表达式1并返回结果 ...
由此,我们可以采用 if else 语句 来理解上述的 三目运算的语句结构,
这样层次结构就会非常清晰,如下:
if(sizeof(group) == 1){
*(s_u8_t*)&group ? true : false;
}
else{
if(sizeof(group) == 2){
*(s_u16_t *)&group ? true : false;
}
else{
if(sizeof(group) == 4){
*(s_u32_t *)&group ? true : false;
}
else{
false;
}
}
}
但 if else 语句 只是为了使语句结构清晰起来,能一目了然,
对于 sTSV_QueryFlagGroup(group) 等相关服务的应用,
还必须采用全部三目运算的写法。
DIY365
发表于 2024-10-29 14:41:15
CosyRTOS-STC8H
串口1接收中断没开启吗?
我打印接收数据,显示是串口2接收到的数据
串口1发送,并没有反应