字节序的理解----C语言和Python语言

字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。常见的主要有以下2种:

  • 小端序(Little-Endian):低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。最符合人的思维的字节序,地址低位存储值的低位,地址高位存储值的高位。该序因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位,反之,高位值就应该放在内存地址大的地方,也即内存地址高位。在80X86平台上,系统将多字节中的低位存储在变量起始地址,使用小端法。
  • 大端序(Big-Endian):高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。最直观的字节序,地址低位存储值的高位,地址高位存储值的低位。该序不需考虑对应关系,只需要把内存地址从左到右按照由低到高的顺序写出把值按照通常的高位到低位的顺序写出,两者对照,一个字节一个字节的填充进去。

常见的还一种是网络序,即网络字节顺序,它是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释,网络字节顺序采用big endian排序方式。

在C语言中,为了进行转换,socket库中提供了转换函数,包括下面四个:

  • htons:把unsigned short类型从主机序转换到网络序
  • htonl:把unsigned long类型从主机序转换到网络序
  • ntohs:把unsigned short类型从网络序转换到主机序
  • ntohl:把unsigned long类型从网络序转换到主机序

在使用little endian的系统中,这些函数会把字节序进行转换;在使用big endian类型的系统中,这些函数会定义成空宏而不作任何转换。

【例】如对于整数0x12345678,在Windows系统上(小端序存储)使用C语言和Python语言查看其不同表示方式。

其位[0-31]表示方式为:

小端序(Little-Endian)和大端序(Big-Endian)的表示方式为:

其网络字节序同大端法表示相同。

(1)C语言程序:

 1 #include <iostream>
 2 #include <WinSock.h>
 3 #pragma comment(lib, "ws2_32")
 4 using namespace std;
 5
 6 void main()
 7 {
 8     int a = 0x12345678;
 9     cout<<"a = "<<showbase<<hex<<a<<endl;
10     cout<<"Little Endian: [";
11     for (int i=0; i<4; i++)
12     {
13         cout<<int(*((char*)&a+i))<<" ";
14     }
15     cout<<"]"<<endl;
16
17     int b = htonl(a);
18     cout<<"Big Endian:    [";
19     for (int i=0; i<4; i++)
20     {
21         cout<<int(*((char*)&b+i))<<" ";
22     }
23     cout<<"]"<<endl;
24
25     getchar();
26 }

其运行结果为:

在调试状态下,在内存窗口中查看变量a和变量b的地址,也可以清晰的看到两种字节序的不同存储情况。本例中变量a和变量b的地址分别为0x00B3FD3C和0x00B3FD24:

(2)Python语言程序:

 1 # -*- coding: utf-8 -*-#
 2
 3 #-------------------------------------------------------------------------------
 4 # Name:         LittleAndBigEndianTest
 5 # Description:
 6 # Author:       Administrator
 7 # Date:         2018/7/8
 8 #-------------------------------------------------------------------------------
 9
10 import sys
11 from struct import *
12 from ctypes import *
13 import numpy as np
14
15 a = 0x12345678
16 print(‘a: ‘ + hex(a))
17 for name, fmt in zip([‘LittleEndian: ‘, ‘BigEndian:    ‘, ‘Network:      ‘], [Struct(‘<1i‘), Struct(‘>1i‘), Struct(‘!1i‘)]):
18     buffer = create_string_buffer(fmt.size)
19     fmt.pack_into(buffer, 0, a)
20     data = np.frombuffer(buffer, dtype=np.uint8)
21     print(name + str(map(lambda x: hex(x), data)))

其运行结果为:

结果同C语言版本一致,同时也验证了网络字节序同大端序结果完全相同。

原文地址:https://www.cnblogs.com/luke0011/p/9280704.html

时间: 2024-10-09 21:25:20

字节序的理解----C语言和Python语言的相关文章

1000道C语言和C++语言的练习题及答案 #0000-0050

汇集1000道C语言和C++语言的练习题 (例题.笔试题.编程题.算法设计题),由我亲自配上答案(点此查看). 语法题我就不出了,那个没意思,看书就可以了. 本贴汇集50题 (0000-0050),持续更新... 0001. 抽签题 从10个数中随机抽取5个数.(相当于双色球抽签问题) 0002. 插入排序 已有10个按增序排列好的整数1,3,5,7,9,11,13,15,17,19.要求把一个整数n插到数组中,保持增序排列. 0003. 数学公式类计算题 已经圆柱体的底半径r,高h,求体积v.

IOS-2-C语言和Objective-C语言衔接学习资料

前言:在IOS学习中,一般会先学习一周的C语言,两周的Objective-C语言,这是今后开发的最基础最重要的部分,下面给大家分享一下培训课上的精简资料: C语言和Objective-C语言衔接学习资料,PPT格式,简单易懂,可迅速掌握. 资料链接: C语言:http://download.csdn.net/detail/iot_li/8951557 Objective-C语言:http://download.csdn.net/detail/iot_li/8944225 版权声明:本文为博主原创

Unicode与UTF-8互转(c语言和lua语言)

1. 基础 1.1 ASCII码 我们知道, 在计算机内部, 全部的信息终于都表示为一个二进制的字符串. 每个二进制 位(bit)有0和1两种状态, 因此八个二进制位就能够组合出 256种状态, 这被称为一个字 节(byte). 也就是说, 一个字节一共能够用来表示256种不同的状态, 每个状态相应一 个符号, 就是256个符号, 从 0000000到11111111. 上个世纪60年代, 美国制定了一套字符编码, 对英语字符与二进制位之间的关系, 做了统 一规定. 这被称为ASCII码, 一直

编程语言和Python解释器介绍

主要内容: 一.编程语言分类和介绍 二.Python解释器分类和介绍 一.编程语言分类和介绍 1.编程语言分类 编程语言的发展依次经历了机器语言.汇编语言和高级语言. 2.编程语言的介绍   2.1 机器语言 定义: 计算机内部只能接受二进制代码,因此,用二进制代码0和1描述的指令称为机器指令,全部机器指令的集合构成计算机的机器语言. 机器语言属于低级语言. 特点: <1>面向最底层,速度最快: <2>最复杂,开发效率低,直观性差,程序全部由0和1构成. 示例: 指令部分 0000

C语言和go语言之间的交互

一.go语言中使用C语言 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:testC.go 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 package main  2  3 /*  4 #include <stdio.h>  5 #include <stdlib.h>  6 void c_print(char *s

过程 : 系统语言和jobPost 语言版本

在前台,用户选择语言会是checkbox list,可以选择多个.如果英文是主要语言,那么 ·选择英文而已,jobPosts 只显示英文版本 ·如果jobPost有英文和中文,只显示英文 ·如果jobPost有中文,不显示 ·选择中文而已,jobPosts只显示中文版本 ·如果jobPost有英文和中文,只显示中文 ·如果jobPost有英文,不显示 ·选择中文.英文,jobPosts只显示英文版本 ·如果jobPost有英文和中文,只显示英文 ·如果jobPost有英文,显示英文 ·如果job

oc基础第一天---c语言和oc语言的对比

/* 1. OC程序的编译. 它的编译.连接.执行和C程序是相差无几的. 1). 在.m文件中写上符合OC语法规范的源代码. 2). 使用 cc -c 指令来编译我们的文件. a. 预处理. b. 检查语法 c. 生成.o的目标文件. 3). 链接 cc xx.o a. 添加启动代码. b. 链接函数. 将要调用的函数的实现拷贝进来 在代码中如果使用到了框架中的功能  就必须要指定系统到那1个框架中去找. cc main.o -framework Foundation 4). 链接完毕之后 会生

c语言和java语言

C(64位,因机器而异) JAVA(固定) Int 32 运行时存储在堆栈上,如果使用malloc则存储在堆上,可以在前使用static等表示词更改存放区域(寄存器,全局变量区) Int 32 运行时值可以存储在堆栈上 数据类型 Short 16 Short 16 Long 64 Long 64 Float 32 Float 64 Double 64 Double 64 Boolean 布尔类型 Char 8 Char 16 字符类型 Byte 8 Void Void 空类型 * 指针类型 St

Java语言和C语言混合编程(1)--Java native关键字

可以将native方法比作Java程序同C程序的接口,其实现步骤为:1.编写java源程序,add用native修饰 package p2019.p06; public class NativeAdd { public native int add(int a,int b); } 2.编译java程序,生成NativeAdd.class文件[[email protected] java]# javac p2019/p06/NativeAdd.java生成NativeAdd.class Nativ