0
点赞
收藏
分享

微信扫一扫

C语言之遇见整形提升

迎月兮 2022-03-20 阅读 74
c语言

在写一个串口程序时,因为收发数据很简单,只有一个字节,所以就加了一个取反字节作为和校验,在收到数据时用以下代码校验数据有有效性:

    uint8_t rxBuffer[2];
    bool rxMsgValid = false;
    ...
    if (rxBuffer[0] == ~rxBuffer[1]) {
      rxMsgValid = true;
    }
    ...

但是运行程序的时候发现,设备永远都收不到有效数据,查了半天链路也没问题,最后调试才发现,这一段代码直接被优化掉了…百思不得姐啊!!!!

后来去同事群里问了一下,然后有个韩国小哥提点了一下,想起来写个测试程序验证一下:


#include "stdint.h"
#include "stdbool.h"
#include "stdio.h"


int	main(int argc, char **argv)
{
	
	uint8_t a[] = {0x01, 0xFE};
	uint8_t b;

	printf("a[0] = 0x%02x, a[1] = 0x%02x, ~a[1] = 0x%02x\n", a[0], a[1], ~a[1]);

	b = a[1] + 0xFF;
	printf("b = a[1] + 0xFF = 0x%02x\n", b);

	if (a[0] == ~a[1]) {
		printf("a[0] == ~a[1]\n");
	} else {
		printf("a[0] != ~a[1]\n");
	}

	system("pause");
	return 0;
}

没想到这段代码的输出是这样的…

a[0] = 0x01, a[1] = 0xfe, ~a[1] = 0xffffff01
b = a[1] + 0xFF = 0xfd
a[0] != ~a[1]
Press any key to continue . . .

为什么本来8位的数据一取反就自动扩展成32位了???这个有点不太科学吧。。。。。。

仔细想来这也就是个王八屁股–规定,但本着刨根问底的科学态度,让我们来找找编译器文档里是怎么说的:

找这个文档也是百转千回,某SDN上还有很多人收费。。。基于本人强烈的开源精神这里Share给大家! FOR FREE:

在查找这个文档的过程中,看到很多人写的例程都会用字节甚至是随便用几位来演示按位取反的操作结果,这对学C语言的人来说是非常不严谨以及有强烈的误导性的。

通过多方查找资料后才明白,这种情形叫***整形提升***,是C语言中非常重要的概念。干了十多年程序员了还不知道这个概念,真是有点。。。

这篇文章算是讲得比较好的,供大家参考:

举报

相关推荐

0 条评论