判断系统大小端方法分析与总结
2011-03-09 15:44
281 查看
2011-03-09 wcdj
问题
:如何用程序确认当前系统的存储模式(大端还是小端)?写一个C函数,若处理器是Big-endian的,则返回0;若是Little-endian的,则返回1。
情况1:利用数组类型
情况2:利用位移运算
上述方法正确吗?要理解为什么不正确?
因为不要在数值上做文章,而大小端是严格与内存挂钩的东西。如果int a=1; 那么a&1==1一定成立,因为这是从数值角度运算的,已经给用户屏蔽掉了大小端的问题。一定要int a=1; *((char*)(&a)) == 1 ,这样判断才有效。
下面总结一些有效的方法。
方法1:利用union类型 —— 可以利用union类型数据的特点:所有成员的起始地址一致。
方法2:对int强制类型转换
方法3:使用union和宏定义
补充:
大小端模式对union类型数据的影响。
分析如下图所示:
高地址 低地址
—— —— —— —— int
0 | 0 | 56 | 57
—— —— —— ——
—— —— char
56 | 57
—— ——
这里需要考虑存储模式:大端模式和小端模式。
大端模式(Big-endian):数据的低字节存放在高地址中。
小端模式(Little-endian):数据的低字节存放在低地址中。
union型数据所占的空间等于其最大的成员所占的空间,对union型成员的存取都是相对于该联合体基地址的偏移量为0处开始,即,联合体的访问不论对哪个变量的存取都是从union的首地址位置开始。因此,上面程序输出的结果就显而易见了。
问题
:如何用程序确认当前系统的存储模式(大端还是小端)?写一个C函数,若处理器是Big-endian的,则返回0;若是Little-endian的,则返回1。
情况1:利用数组类型
#include <cstdio> int checkSystem() { char s[]="1000"; return (s[0]=='1'); } int main() { checkSystem()==1 ? printf("Little-endian/n") : printf("Big-endian/n"); return 0; }
情况2:利用位移运算
int i = 1; if(1>>32 == 0) cout<<"小端模式"<<endl; else cout<<" 大端模式"<<endl;
上述方法正确吗?要理解为什么不正确?
因为不要在数值上做文章,而大小端是严格与内存挂钩的东西。如果int a=1; 那么a&1==1一定成立,因为这是从数值角度运算的,已经给用户屏蔽掉了大小端的问题。一定要int a=1; *((char*)(&a)) == 1 ,这样判断才有效。
下面总结一些有效的方法。
方法1:利用union类型 —— 可以利用union类型数据的特点:所有成员的起始地址一致。
#include <cstdio> int checkSystem() { union check { int i; char ch; }c; c.i=1; return (c.ch==1); } int main() { checkSystem()==1 ? printf("Little-endian/n") : printf("Big-endian/n"); return 0; }
方法2:对int强制类型转换
#include<stdio.h> #include<stdlib.h> int main() { int i = 1; (*(char *)&i == 1) ? printf("Little-endian/n") : printf("Big-endian/n"); system("pause"); return 0; }
方法3:使用union和宏定义
#include<stdio.h> #include<stdlib.h> static union { char a[4]; unsigned long ul; }endian = {{'L', '?', '?', 'B'}}; #define ENDIAN ((char)endian.ul) int main() { printf("%c/n", ENDIAN); system("pause"); return 0; }
补充:
大小端模式对union类型数据的影响。
#include <cstdio> union { int i; char a[2]; }*p, u; int main() { p=&u; p->a[0]=0x39; p->a[1]=0x38; printf("%x/n",p->i);// 3839 (hex.) printf("%d/n",p->i);// 111000 00111001=14393 (decimal) return 0; }
分析如下图所示:
高地址 低地址
—— —— —— —— int
0 | 0 | 56 | 57
—— —— —— ——
—— —— char
56 | 57
—— ——
这里需要考虑存储模式:大端模式和小端模式。
大端模式(Big-endian):数据的低字节存放在高地址中。
小端模式(Little-endian):数据的低字节存放在低地址中。
union型数据所占的空间等于其最大的成员所占的空间,对union型成员的存取都是相对于该联合体基地址的偏移量为0处开始,即,联合体的访问不论对哪个变量的存取都是从union的首地址位置开始。因此,上面程序输出的结果就显而易见了。
相关文章推荐
- 判断系统大小端方法分析与总结
- 判断系统大小端方法的总结
- 总结和分析几种判断RecyclerView到达底部的方法
- 总结和分析几种判断RecyclerView到达底部的方法
- 总结和分析几种判断RecyclerView到达底部的方法
- 总结和分析几种判断 RecyclerView 到达底部的方法
- [置顶] 知识总结之 插件化学习 Hook系统方法分析
- 系统分析中写 需求说明书 的方法--个人经验总结
- 总结和分析几种判断RecyclerView到达底部的方法
- 总结和分析几种判断RecyclerView到达底部的方法
- 总结和分析几种判断RecyclerView到达底部的方法
- Linux系统故障分析方法个人总结
- 总结和分析几种判断RecyclerView到达底部的方法
- C#中判断空字符串的3种方法性能分析【月儿原创】
- JS中判断null, undefined, '', 0等的方法分析
- 系统Hang住时用oradebug分析的方法
- 在Windows7环境下安装Kali双系统方法总结
- jq中的isArray方法分析,如何判断对象是否是数组
- [总结]机房收费系统 条件判断
- 主成分分析方法PCA总结