大端模式与小端模式

 

Big-Endian和Little-Endian的定义如下:
 1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
 2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
 举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
 1)大端模式:
 低地址 -----------------> 高地址
 0x12  |  0x34  |  0x56  |  0x78
 2)小端模式:
 低地址 ------------------> 高地址
 0x78  |  0x56  |  0x34  |  0x12
 可见,大端模式和字符串的存储模式类似。
 详细信息可参考 http://blog.csdn.net/ce123_zhouwei/article/details/6971544

下面是一个打印各种类型的例子来自于csapp。

  1 /* $begin show-bytes */
  2 #include <stdio.h>
  3 /* $end show-bytes */
  4 #include <stdlib.h>
  5 #include <string.h>
  6 /* $begin show-bytes */
  7 
  8 typedef unsigned char *byte_pointer;
  9 
 10 void show_bytes(byte_pointer start, size_t len) {
 11     size_t i;
 12     for (i = 0; i < len; i++) //转为char的打印一个字节 
 13     printf(" %.2x", start[i]);    //line:data:show_bytes_printf
 14     printf("\n");
 15 }
 16 
 17 void show_int(int x) {
 18     show_bytes((byte_pointer) &x, sizeof(int)); //line:data:show_bytes_amp1
 19 }
 20 
 21 void show_float(float x) {
 22     show_bytes((byte_pointer) &x, sizeof(float)); //line:data:show_bytes_amp2
 23 }
 24 
 25 void show_pointer(void *x) {
 26     show_bytes((byte_pointer) &x, sizeof(void *)); //line:data:show_bytes_amp3
 27 }
 28 /* $end show-bytes */
 29 
 30 
 31 /* $begin test-show-bytes */
 32 void test_show_bytes(int val) {
 33     int ival = val;
 34     float fval = (float) ival;
 35     int *pval = &ival;
 36     show_int(ival);
 37     show_float(fval);
 38     show_pointer(pval);
 39 }
 40 /* $end test-show-bytes */
 41 
 42 void simple_show_a() {
 43 /* $begin simple-show-a */
 44 int val = 0x87654321;
 45 byte_pointer valp = (byte_pointer) &val;
 46 show_bytes(valp, 1); /* A. */
 47 show_bytes(valp, 2); /* B. */
 48 show_bytes(valp, 3); /* C. */
 49 /* $end simple-show-a */
 50 }
 51 
 52 void simple_show_b() {
 53 /* $begin simple-show-b */
 54 int val = 0x12345678;
 55 byte_pointer valp = (byte_pointer) &val;
 56 show_bytes(valp, 1); /* A. */
 57 show_bytes(valp, 2); /* B. */
 58 show_bytes(valp, 3); /* C. */
 59 /* $end simple-show-b */
 60 }
 61 
 62 void float_eg() {
 63   int x = 3490593;
 64   float f = (float) x;
 65   printf("For x = %d\n", x);
 66   show_int(x);
 67   show_float(f);
 68 
 69   x = 3510593;
 70   f = (float) x;
 71   printf("For x = %d\n", x);
 72   show_int(x);
 73   show_float(f);
 74 
 75 }
 76 
 77 void string_ueg() {
 78 /* $begin show-ustring */
 79 /*字符串在内存中的存储方式为ASCII形式所以不受大端小端模式的限制,
 80 与字节的大小和顺序无关,输入的什么内容,输出的为对应的ASCII码*/
 81 const char *s = "123456";
 82 show_bytes((byte_pointer) s, strlen(s)); 
 83 /* $end show-ustring */
 84 }
 85 
 86 void string_leg() {
 87 /* $begin show-lstring */
 88 const char *s = "abcdef";
 89 show_bytes((byte_pointer) s, strlen(s)); 
 90 /* $end show-lstring */
 91 }
 92 
 93 void show_twocomp() 
 94 {
 95 /* $begin show-twocomp */
 96     short x = 12345; 
 97     short mx = -x; 
 98     
 99     show_bytes((byte_pointer) &x, sizeof(short)); 
100     show_bytes((byte_pointer) &mx, sizeof(short)); 
101 /* $end show-twocomp */
102 }
103 
104 int main(int argc, char *argv[])
105 {
106     int val = 12345;
107 
108     if (argc > 1) {
109     if (argc > 1) {
110         val = strtol(argv[1], NULL, 0);
111     }
112     printf("calling test_show_bytes\n");
113     test_show_bytes(val);
114     } else {
115     printf("calling show_twocomp\n");
116     show_twocomp();
117     printf("Calling simple_show_a\n");
118     simple_show_a();
119     printf("Calling simple_show_b\n");
120     simple_show_b();
121     printf("Calling float_eg\n");
122     float_eg();
123     printf("Calling string_ueg\n");
124     string_ueg();
125     printf("Calling string_leg\n");
126     string_leg();
127     }
128     return 0;
129 }

 要判断一个机器是大端模式还是小端模式可以如下测试

 1 #include <stdio.h>
 2 /*编写函数is_little_endian,在小端机器上运行时返回1,大端上时返回0*/
 3 int  is_little_endian();
 4 int main(int argc,char *argv[])
 5 {
 6     if(is_little_endian())
 7     {
 8         printf("this os is a little_endian\n");
 9         return 0;
10     }
11     printf("this os is a big_endian\n");
12     
13 }
14 
15 int  is_little_endian()
16 {
17     int a=4660; //0x1234
18     char b=*(char *)&a;//通过将int强制类型转换成char单字节,通过判断起始存储位置。即等于 取b等于a的低地址部分  
19     if(b==0x34)
20     return 1;
21     return 0;
22 }

 

posted @ 2017-11-25 20:56  快第三个十年  阅读(1277)  评论(0编辑  收藏  举报