关于系统字节序
来源:互联网 发布:江苏减招 知乎 编辑:程序博客网 时间:2024/05/04 15:28
记录一下从网上搜索的关于系统字节序的相关帖子内容
因为现行的计算机都是以八位一个字节为存储单位,那么一个16位的整数,也就是C语言中的short,在内存中可能有两种存储顺序big-endian和litte-endian.
考虑一个short整数0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:
大端字节(Big-endian):
----------------->>>>>>>>内存地址增大方向
short变量地址
0x1000 0x1001
_____________________________
| |
| 0x31 | 0x32
|________________ | ________________
高位字节在低位字节的前面,也就是高位在内存地址低的一端.可以这样记住(大端->高位->在前->正常的逻辑顺序)
小端字节(little-endian):
----------------->>>>>>>>内存地址增大方向
short变量地址
0x1000 0x1001
_____________________________
| |
| 0x32 | 0x31
|________________ | ________________
低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端->低位->在前->与正常逻辑顺序相反)
可以做个实验
在windows上下如下程序
#include
#include
void main( void )
{
short test;
FILE* fp;
test = 0x3132; //(31ASIIC码的’1’,32ASIIC码的’2’)
if ((fp = fopen ("c://test.txt", "wb")) == NULL)
assert(0);
fwrite(&test, sizeof(short), 1, fp);
fclose(fp);
}
然后在C盘下打开test.txt文件,可以看见内容是21,而test等于0x3132,可以明显的看出来x86的字节顺序是低位在前.如果我们把这段同样的代码放到(big-endian)的机器上执行,那么打出来的文件就是12.这在本机中使用是没有问题的.但当你把这个文件从一个big- endian机器复制到一个little-endian机器上时就出现问题了.
下面代码示范了两种检测系统字节序的方法。
第一种方法,使用强制类型转换的方式。C 语言在把占用2个字节的 short 变量强制转换为 char 之后,会把 short 变量的首地址赋给 char 变量,可以根据 char 变量的值判断系统字节序是 大端 还是 小端。
第二种方法,利用 联合类型 的特性。联合类型 共享同一段内存,首地址是相同的。
/*******************
* 文件名:endian.c
******************/
#include <stdio.h>
/*********************************************************
* 使用类型的强制转换实现little-endian与big-endian的判断
*********************************************************
* 返回值:
* 1 表示是小端字节序。
* 0 表示不是小端字节序。
*********************************************************/
int is_little_endian_a(void)
{
unsigned short flag = 0x4321;
if(*(unsigned char*)&flag == 0x21)
return 1;
else
return 0;
}
/*********************************************************************************
* 利用联合的特点来判断little-endian与big-endian
*********************************************************************************
* 返回值:
* 1 表示是小端字节序。
* 0 表示是大端字节序。
* -1 表示不能使用这种方法确定字节序。比如有的机器的 short 长度不是 2 。
********************************************************************************/
int is_little_endian_b(void)
{
union endian_un{
short var;
char bits[sizeof(short)];
};
union endian_un flag;
flag.var=0x0102;
//判断低位和高位的存储内容,确定是何种方式
if(sizeof(short) == 2){
if(flag.bits[0] == 1 && flag.bits[1] == 2)
return 0;
else if(flag.bits[0] == 2 && flag.bits[1] == 1)
return 1;
else
return -1;
}
return -1;
}
int main(void)
{
int type = 0;
type = is_little_endian_a();
if (1 == type)
printf("judged by first method, little-endian/n");
else if (0 == type)
printf("judged by first method, big-endian/n");
type = is_little_endian_b();
if (1 == type)
printf("judged by second method, little-endian/n");
else if (0 == type)
printf("judged by second method, big-endian/n");
else
printf("can't judge it/n");
return 0;
}
- 关于系统字节序
- 判断系统字节序
- 关于字节序
- 关于字节序
- 关于字节序
- 关于网络字节序
- 关于网络字节序
- 关于字节序的问题
- 关于字节序的解释
- 关于字节序的问题
- 关于大小端字节序
- 关于字节序的讨论
- 关于字节
- 系统高低字节序和网络字节序的转换
- 关于网络字节序和主机字节序的转换
- 关于网络字节序和主机字节序的转换
- 关于网络字节序和主机字节序的转换
- 关于大字节序和小字节序
- IP组播和组播协议
- Linux下Socket编程
- 错误:“CObject::CObject”: 无法访问 private 成员(在“CObject”类中声明)
- shell测试和比较函数--test、[、[[、((、和 if-then-else
- 让MySQL高效运行起来
- 关于系统字节序
- Fatal error: Maximum execution time of 30 seconds exceeded in
- 用后台控件做.net多线程编程
- LTE TDD与FDD LTE技术比较
- DNS域名系统
- 第三部分 主机对SEO的影响
- 转帖--关于spin_lock-(居然首次关注内核执行路径,惭愧)
- HP(惠普)大中华区总裁孙振耀退休感言
- GAE 简易论坛——B3log Symphnony