帮同学解决crc-16码的问题时,遇到一个小问题,觉得挺有价值的,故在此mark一下。
场景如下:
有以下c++代码
unsigned char data[] = "testtest";
while (len >1) {
sum += *(unsigned short*)data; //这是代码中一个求和的操作
data +=2;
len -= 2; //len为data中字符个数
}
这段代码中将连续的两个字节(unsigned char)合并成了unsigned short,现欲将其转换为java代码:
while ( len>1 ) {
sum += ((data[idx] &0x000000FF) << 8) | (0x000000FF & data[idx+1]); //data为对应的byte数组
idx += 2;
len -= 2;
}
这段代码初看并无问题,但折腾半天输出结果就是跟c++代码有出入,最后想到了大小端的问题,以上代码使用data[idx]表示高八位,data[idx+1]表示低八位,当时想当然地这样认为。现在看来是因为经验少,没有遇到过此类问题,把data[idx]和data[idx+1]交换之后,得到了正确的结果:sum += ((data[idx+1] &0x000000FF) << 8) | (0x000000FF & data[idx]);
总结:
大端模式更接近人们习惯的思考方式,c语言一般默认小端模式,java虽然默认大端,但是此过程中并未体现出来,在改写代码时很容易犯此类错误,知识点很简单,贵在点滴的积累,特此记录一下。