小代码背后的大道理

先看这段代码 前端

经过指针能够直接访问内存,而在C#中这属于不安全操做,为了能让代码编译运行所以都要带上unsafe,这个不用管它。这段代码主要是借助单字节数据类型byte,直接访问内存,查看各类数据类型的数据在内存的存放状况。在往常认为整数0,1,2,3,4,5……之类的存放在内存的就是转换成二进制再放进去;而字符则是先经过字符编码转换,好比ASCII码A,B,C,D转换成01000001,01000010,01000011再放进去。固然这个层次还不够细。想当年在大学时代知道这些还算过得去了。直到最近再去看计算机科学之类的书籍才加深了本身对这方面的认知。安全

在学C的时候都有提过无符号数,而咱们一般使用的都是有符号数。在整形而言有符号整形而无符号整形已经是两套不一样的编码:无符号整形是直接把十进制数转换成二进制;有符号整形须要把数转换成补码。补码原码反码之类的在大学里常常接触。可是记忆中老师好像没提到补码是存无符号整形的,却是想再翻翻之前的教材里有没有提到。因为整形有short,int,long三种不一样长度,若是二进制值超出了所存放类型的长度就会把高位舍去,这就形成所谓的数据溢出。有符号和无符号数的区别在于多了个符号,因此补码是把最高位留着做为符号位,既然二进制位的长度是定的,因此补码中表示数据的位数就少了一位,所以有符号数的最大正数会比无符号数的最大整数要小了。这好像扯远了。 测试

虽然这些数字和字符转换成0101这样的二进制编码后就能存放在内存中,好比无符号整数12345,它转换成二进制就是0011 0000 0011 1001太长了,为了方便显示就转换成16进制表示30 39,而int类型是4个字节,1个字节8个位。这个值实际只占了2个字节,剩余的字节用0来补全,那么其实是00 00 30 39。在无符号整数123456在内存中是否就以00 00 30 39来存放呢?运行一下代码 编码

查看结果 spa

发现恰好跟猜测相反。对于00 00 30 39 这串数据而言,00是高位,39是低位,测试的结果发现数字存放在内存中被高低位互换了。不过也不能妄下定论说数据通过高低位互换才放到内存中,实际上这里还涉及到字节顺序中大端法和小端法的概念。若是一个数据,它存放在内存中的字节顺序是从数据的高位一直到低位的,好比上面12345,存放顺序是 00 00 30 39。那这种就称为大端法,我理解是"大位靠前端法";与之相反,数据存放内存中字节顺序从低位到高位存放的,好比上面12345,存放顺序是39 30 00 00,这种称之为小端法,"小位靠前法"。C语言是移植性很强的语言。C#依靠DotNet Core也能够实现跨平台,我却是没有在别的平台上运行过上面的代码。C语言也没有,但听说与上面相似的代码在Sun,Linux32,Linux64上运行,仅有Sun是显示00 00 30 39。也就是说只有Sun是使用了大端法来存储数据,其余平台都使用小端法来存储数据。当咱们在主机与主机与间进行数据交互时,就要注意双方平台所用的字节顺序。鄙人在使用串口通信时就遇到过这个场景,发送或接收一串数据,其中某几个字节是有用的数据,把数据取出来以后还须要高低位互换,才是所须要的数据。这就是一个很好的例子了。 指针

相关文章
相关标签/搜索