目录
一、char
1.截断存取
2.有符号与无符号的处理
3.整型提升
二、大小端字节序
一、char
众所周知,在c语言里面,char也是属于整型里面的。这是为何呢?因为char调用字符的时候是用的ascii码值储存的。
在c语言中,整型数据里面给int分配的四个字节内存,而给char类型分配的是一个字节,应为如果用其表示英语的话一个字节完全足矣。
那么,现在从下面这个程序引入今天我想分享的学习点里面吧:
#include
这个代码里面首先要了解整型字面值里面是以int类型默认的,按理说以大容量类型到小类型转换需要强制转化类型,但是对于char类型是不需要的。现在上面的代码需要 截断存取,有符号与无符号类型的处理,最后,整型提升。
1.截断存取
首先-1的字面值直接转化为二进制应该是 1000 0000 0000 0000 0000 0000 0000 0001;
这个只是原码,我们知道在内存里面存的是补码,所以要从原码转化为补码,就要需要经过除符号位的按位取反,1111 1111 1111 1111 1111 1111 1111 1110(反码),然后在反码的基础上在加一,得到补码:1111 1111 1111 1111 1111 1111 1111 1111(补码)。注意到的是上述变化只是在负数的时候需要这样变换,但是对于正数来说的话,原码反码补码一致哦。
随后,对于char类型的来说,只有八个bite的内存显然存不下32bite的数据,自然就会发生截断,只把后面的8个bite的数据存到a和b变量里面即可,即 1111 1111。
2.有符号与无符号的处理
虽然此时ab变量里面存的补码一致,但是你以为他们输出的是一样的吗?当然不一样,造成这种差异的正是有符号与无符号的处理,在printf函数的处理时,将它们取出,需要进行整型提升,但是整型提升要按什么要求来提升呢?就是以这个处理来进行提升的。
正如从char型数据取出数据,只有八个bite,现在就要往前补齐至32个bite,有符号的就补符号位,而没有符号的就补0,c语言统一规定的。
3.整型提升
正如2里面所说,那么a就是正常的进行提升,由 1111 1111,是负数,就提升1,那么:
1111 1111 1111 1111 1111 1111 1111 1111;和原来存进去的方式一模一样,所以可以确定a输出来的结果也是一致了,那么b的话是无符号,就提升0:
0000 0000 0000 0000 0000 0000 1111 1111 ,这个时候需要转化为反码和原码吗?不,此时补零后打印%d,看首位是0,所以被认成了正数,所以就直接转化为十进制得255啦!
二、大小端字节序
大小端字节序指的是数据在电脑上存储的字节顺序。
这是怎么一回事呢?
比如储存1:
int a = 1;
调试后在内存块找到&a即可会看到这样的情况:
按理说的话应该是(上面内存块是以十六进制存的)
高位 00 00 00 01 低位,是反起存的,当然这就是小端储存。,那么大小端字节序究竟是怎么储存的呢?
大端字节序:高位的字节存在低地址上,低位的字节存在高地址上。
小端字节序:高位的字节存在高地址上,低位的字节存在低地址上。
当然,大端字节序的话就符合我们的观看情况了:
那么,我们如何分析或者说设计一个函数来区别当前环境下是什么字节序呢?
当然可以,我们可以直接在主函数里面去写:
int main(){int a = 1;char* b = (char*)&a;if (*b == 0)printf("大端");elseprintf("小端");return 0;}
想一想,我们可以拿最简单的1来进行实验,其在内存里面的存储情况应该是 00 00 00 01(十六进制),那么我们能否从低地址里面去出一个字节的数据即一个 00或者01来判断是否大小端呢?上述代码就实现啦,但是,我们是要制作一个函数,万一转换环境了,还要把main函数带过去吗?所以,我们可以打包成函数:
void Byte_order(){int a = 1;char* b = (char*)&a;if (*b == 0)printf("大端");elseprintf("小端");}int main(){Byte_order();return 0;}
但是,在函数里面打印的话效率不高,不适用,我们不妨将这个函数的类型改为int型的,使其返回1和0来表示判断:
int Byte_order(){int a = 1;char* b = (char*)&a;if (*b == 0)return 0;return 1;}int main(){if (Byte_order() == 1)printf("小端");elseprintf("大端");return 0;}
既然都返回0和1了,那么我们为何不直接返回呢?并且,在函数里面还重新创建了一个指针变量,我们是否可以不用创建呢?
int Byte_order(){int a = 1;return *(char*)&a;}int main(){if (Byte_order() == 1)printf("小端");elseprintf("大端");return 0;}
显然,最后一个代码已经让我沦陷。。。