123下一页
返回列表 发新帖我要提问本帖赏金: 3.00元(功能说明)

[STM32F1] STM32芯片导致的还是C语言导致的这个灵异事件,求大神解释!

[复制链接]
9164|56
 楼主| 工行ATM 发表于 2016-12-8 15:36 | 显示全部楼层 |阅读模式
请教大家一个语法方面的问题

u16 result, counter;
u8 str[5] = {0x00, 0x11, 0x22, 0x33, 0x44};

counter = 1;
result = ((u16)str[counter ++] << 8) | str[counter ++];

计算完成以后result的值是多少呢?

按道理来说是0x1122,但是在stm32上仿真出来后,结果是0x2211,高低字节调了个个儿!
但是如果用
result=(u16)str[1]<<8|str[2];
或者用
result = (u16)str[counter ++] << 8;
result |= str[counter ++];
分步计算,得到的值是0x1122。求大神指点迷津orz!!
JY-DX-JY 发表于 2016-12-8 15:43 | 显示全部楼层
result = ((u16)str[counter ++] << 8) | str[counter ++];
感觉这一句是从右往左算的。
 楼主| 工行ATM 发表于 2016-12-8 15:44 | 显示全部楼层
JY-DX-JY 发表于 2016-12-8 15:43
result = ((u16)str[counter ++]

为啥呢
JY-DX-JY 发表于 2016-12-8 15:51 | 显示全部楼层

可能跟C语言计算的优先级有关。
 楼主| 工行ATM 发表于 2016-12-8 15:56 | 显示全部楼层
JY-DX-JY 发表于 2016-12-8 15:51
可能跟C语言计算的优先级有关。

可能真的和优先级有关,在[] | ()比较的时候,[]优先级高,先算的后面的。。。
 楼主| 工行ATM 发表于 2016-12-8 16:01 | 显示全部楼层
JY-DX-JY 发表于 2016-12-8 15:51
可能跟C语言计算的优先级有关。

那如何实现想要的功能呢?!求大神解答!!
 楼主| 工行ATM 发表于 2016-12-8 16:10 | 显示全部楼层
我听闻 发表于 2016-12-8 15:51
你确定仿真的结果不是 0x1111

仿真结果不是0x1111,刚才把计算式改了,
result = ((u16)str[counter ++] << 8) | (str[counter ++]);
结果还是0x2211,感觉还有其他的问题。
john_lee 发表于 2016-12-8 16:19 | 显示全部楼层
C 语言标准:
Except where noted, the order of evaluation of operands of individual operators and sub-expressions of individual expressions, and the order in which side effects take place, is unspecified.
除非另有说明,各个的操作符的操作数和各个表达式的子表达式求值的顺序和副作用发生的顺序是未指定的。

具体到你的表达式:((u16)str[counter ++] << 8) | str[counter ++];
你不能假设 | 两边的子表达式哪个先哪个后计算。

打赏榜单

工行ATM 打赏了 1.00 元 2016-12-09
理由:C语言确实没有明确规定,不同的编译器操作不一样

 楼主| 工行ATM 发表于 2016-12-8 16:26 | 显示全部楼层
john_lee 发表于 2016-12-8 16:19
C 语言标准:
Except where noted, the order of evaluation of operands of individual operators and su ...

但是我刚才将表达式改为
result = (str[counter ++]) | (str[counter ++] << 8);
出来的结果还是0x2211,是不是有其他的原因。
NE5532 发表于 2016-12-8 16:34 | 显示全部楼层
谭浩强:不要写那种自己不知道计算机会如何执行的代码。

拆成几行写,不代表写得笨。
 楼主| 工行ATM 发表于 2016-12-8 16:40 | 显示全部楼层
NE5532 发表于 2016-12-8 16:34
谭浩强:不要写那种自己不知道计算机会如何执行的代码。

拆成几行写,不代表写得笨。 ...

但是。。。拆开看起来不爽。。。
mmuuss586 发表于 2016-12-8 16:42 | 显示全部楼层
result = ((u16)str[counter +1] << 8) | (str[counter +2]);
这样试下
chenyongand 发表于 2016-12-8 16:42 | 显示全部楼层
8楼和10楼两位版主说的在理
JY-DX-JY 发表于 2016-12-8 16:44 | 显示全部楼层
工行ATM 发表于 2016-12-8 16:01
那如何实现想要的功能呢?!求大神解答!!

你为什么非要用++呢?直接给出下标不行吗?
 楼主| 工行ATM 发表于 2016-12-8 16:46 | 显示全部楼层
本帖最后由 工行ATM 于 2016-12-8 16:56 编辑
mmuuss586 发表于 2016-12-8 16:42
result = ((u16)str[counter +1]

还是0x2211


//上面结果写错了,不是0x2211

是0x2233,不好意思哈。。
 楼主| 工行ATM 发表于 2016-12-8 16:49 | 显示全部楼层
JY-DX-JY 发表于 2016-12-8 16:44
你为什么非要用++呢?直接给出下标不行吗?

原型是modbus通讯里面的一个操作,得到数组以后从里面取值呢,直接写下标要写很多。。
JY-DX-JY 发表于 2016-12-8 16:52 | 显示全部楼层
工行ATM 发表于 2016-12-8 16:49
原型是modbus通讯里面的一个操作,得到数组以后从里面取值呢,直接写下标要写很多。。 ...

你还是分开写吧,如果存储空间够的话,没有必要那么纠结。
 楼主| 工行ATM 发表于 2016-12-8 17:01 | 显示全部楼层
JY-DX-JY 发表于 2016-12-8 16:52
你还是分开写吧,如果存储空间够的话,没有必要那么纠结。

不要。。。
 楼主| 工行ATM 发表于 2016-12-8 17:16 | 显示全部楼层
再贴一段keil5的汇编代码,请能看懂的大神解释一下orz!
   333:                                         ConfigDeviceRAM.Sort.limit_OA_VA = (usart_receive_temp[modbus_rx_num ++] << 8) | (usart_receive_temp[modbus_rx_num ++]);
   334:                                 }
0x080014C8 48C2      LDR      r0,[pc,#776]  ; @0x080017D4
0x080014CA 7801      LDRB     r1,[r0,#0x00]
0x080014CC 7800      LDRB     r0,[r0,#0x00]
0x080014CE 1C40      ADDS     r0,r0,#1
0x080014D0 4AC0      LDR      r2,[pc,#768]  ; @0x080017D4
0x080014D2 7010      STRB     r0,[r2,#0x00]
0x080014D4 48C0      LDR      r0,[pc,#768]  ; @0x080017D8
0x080014D6 5C41      LDRB     r1,[r0,r1]
0x080014D8 4610      MOV      r0,r2
0x080014DA 7802      LDRB     r2,[r0,#0x00]
0x080014DC 7800      LDRB     r0,[r0,#0x00]
0x080014DE 1C40      ADDS     r0,r0,#1
0x080014E0 4BBC      LDR      r3,[pc,#752]  ; @0x080017D4
0x080014E2 7018      STRB     r0,[r3,#0x00]
0x080014E4 48BC      LDR      r0,[pc,#752]  ; @0x080017D8
0x080014E6 5C80      LDRB     r0,[r0,r2]
0x080014E8 EA412000  ORR      r0,r1,r0,LSL #8
0x080014EC 49BB      LDR      r1,[pc,#748]  ; @0x080017DC
0x080014EE 8308      STRH     r0,[r1,#0x18]
0x080014F0 E000      B        0x080014F4
lxyppc 发表于 2016-12-8 18:27 来自手机 | 显示全部楼层
这个是keil的bug,换成IAR就好了

打赏榜单

工行ATM 打赏了 0.50 元 2016-12-09
理由:是keil的问题

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

17

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部