【嵌入式学习-C语言篇】 char & short & int 的使用
三种数据类型常用场景
- 智能家居:网关协议中mac地址上报
网关:网关(Gateway)又称网间连接器、协议转换器。网关在传输层以上实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。它是一种充当转换重任的计算机系统或设备,在使用不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。(从一个网络向另一个网络发送信息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。)
- 奶茶机器人:温度采集,小数点上报云端
char,short, int 类型的取值范围
在C语言中,char类型的取值范围是 -128到127 (
−
2
7
−
1
-2^{7}-1
−27−1到
2
7
−
1
2^{7}-1
27−1)。short类型的取值范围是 -32,768到32,767 (
−
2
16
−
1
-2^{16}-1
−216−1到
2
16
−
1
2^{16}-1
216−1)。int类型的取值范围是 -2,147,483,648到2,147,483,647(
−
2
32
−
1
-2^{32}-1
−232−1到
2
32
−
1
2^{32}-1
232−1), 而前面加了 unsigned 代表没有负数,但占用的空间的地址还是和不加 unsigned 一样的空间大小。加了unsigned就是把最高位的用来表示正负的0和1不用来表示正负了,因为unsigend加了之后没有负数了,而将最高位当一位来表示数字,那么就变成了原本char类型的 -128到127成了 0到255(
0
0
0到
2
8
−
1
2^{8}-1
28−1)(涉及到计算机导论的基础知识,很简单不解释)
unsigned char a; //0x00 - 0xff 8
unsigned short b; //0x0000-0xffff 16
unsigned int c; //0x00000000 - 0xffffffff 32
void main(){
printf("hello world\n"); //hello world
printf("%d %d %d\n", sizeof(a), sizeof(b), sizeof(c)); //1 2 4
// char short int 分别占 1字节 2字节 4字节
}
使用数据类型将温度或MAC地址上传到服务器(应用)
预先定义两个变量为temp和mac分别为 float 类型和 *char **类型
float temp = 37.5; //使用float类型表示温度,因为浮点类型可以保存小数点之后的数值
char* mac = "192.168.31.84"; //使用char* 来表示字符串, 可以间接的理解char* 等于 String,但是细节上区别还是挺多的。
那么我们是否有别的办法来表示吗?
当然可以,我们可以使用数组来表示上面的mac地址和温度
char mac_array[4] = {192, 168, 31, 84};
char temp_array[2] = {37, 5};
我们也可以使用更高级的写法,来一点不一样的操作
1.我们知道mac地址是有个四个0~255的数值构成,所以我们可以想像的是mac地址就相当于 0 ~ 28.0 ~ 28.0 ~ 28.0 ~ 28
2.我们又知道 unsigned char 可以表示的范围就是0 ~ 28
3.所以我们可以使用一个unsigned char类型的数组来表示我们的mac地址
具体操作如下:
假设mac地址为192.168.31.84
我们可以把它看成 0xc0.0xa8.0x1f.0x54 (0x代表十六进制)
因为4个char类型等于1个int类型,那么我们就可以用一个 int类型将整个mac地址存储起来 ,从底层来看,我们需要做的就是将0xc0放到int类型的前0-8位,而0xa8我们放到9-16位,0x1f放到17-24位,0x54放到25-32位。
而对于将这些二进制移动到它们原本该有的位置,这需要位移操作。我们需要左移来实现。
//假设mac地址为192.168.31.84
//我们可以把它看成0xc0.0xa8.0x1f.0x54
unsigned char mac_buffer[4] = {0xc0, 0xa8, 0x1f, 0x54};
unsigned int mac;
unsigned int u8Tou32B(unsigned char *buffer){
//将每一个位置的数线转成unsigned int类型,主要目的是方便后面取与能够合并所有的位数的值,而之后<<8也就是左移八位,目的是让这八位移到它该对应的位置。 原理很简单,需要有位移以及取与操作知识,这些操作都是建立在二进制层面的,切忌误以整数层面思考
return (((((((unsigned int)buffer[0])<<8)|buffer[1])<<8)|buffer[2])<<8)|buffer[3];
}
void main(){
mac = u8Tou32B(mac_buffer);
printf("mac - %ld\n ", mac); //1062723756
}
既然能够保存mac地址,我们也可以保存当前时间
//时间戳->十六进制->存储
//1690450650->64C23ADA
unsigned char time_buffer[4] = {0x64, 0xC2, 0x3A, 0xDA};
unsigned int time;
unsigned int u8Tou32B(unsigned char *buffer){
return (((((((unsigned int)buffer[0])<<8)|buffer[1])<<8)|buffer[2])<<8)|buffer[3];
}
void main(){
time = u8Tou32B(time_buffer);
printf("time - %ld s\n", time); // time - 1690450650 s
}