大小端模式对C语言的共用体结构的影响

合集下载

大端模式与小端模式解析

大端模式与小端模式解析

大端模式与小端模式一、概念及详解在各种体系的计算机中通常采用的字节存储机制主要有两种:big-endian和little-endian,即大端模式和小端模式。

先回顾两个关键词,MSB和LSB:MSB:Most Significant Bit ------- 最高有效位LSB:Least Significant Bit ------- 最低有效位大端模式(big-edian)big-endian:MSB存放在最低端的地址上。

举例,双字节数0x1234以big-endian的方式存在起始地址0x00002000中:| data |<-- address| 0x12 |<-- 0x00002000| 0x34 |<-- 0x00002001在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0x8B8A为例):----+---------------------------------------------------+bit | 00 01 02 03 04 05 06 07 | 08 09 10 11 12 13----+MSB---------------------------------------------LSB+val | 1 0 0 0 1 0 1 1| 1 0 0 0 1 0 1 0 |----+---------------------------------------------------+= 0x8B8A小端模式(little-endian)little-endian:LSB存放在最低端的地址上。

举例,双字节数0x1234以little-endian的方式存在起始地址0x00002000中:| data |<-- address| 0x34 |<-- 0x00002000| 0x12 |<-- 0x00002001在Little-Endian中,对于bit序列中的序号编排和Big-Endian 刚好相反,其方式如下(以双字节数0x8B8A为例):----+---------------------------------------------------+bit | 15 14 13 12 11 10 09 08 | 07 06 05 04 03 02----+MSB---------------------------------------------LSB+val | 1 0 0 0 1 0 1 1| 1 0 0 0 1 0 1 0 |----+---------------------------------------------------+= 0x8B8A二、数组在大端小端情况下的存储:以unsigned in t value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value:Big-Endian: 低地址存放高位,如下:高地址---------------buf[3] (0x78) -- 低位buf[2] (0x56)buf[1] (0x34)buf[0] (0x12) -- 高位---------------低地址Little-Endian: 低地址存放低位,如下:高地址---------------buf[3] (0x12) -- 高位buf[2] (0x34)buf[1] (0x56)buf[0] (0x78) -- 低位--------------低地址三、大端小端转换方法:Big-Endian转换成Little-Endian如下:#defineBigtoLittle16(A) ((((uint16)( A) & 0xff00) >> 8) | \(((uint16)(A) & 0x00ff) << 8))#defineBigtoLittle32(A) ((((uint32)( A) & 0xff000000) >> 24) | \(((uint32)(A) & 0x00ff0000) >> 8) | \(((uint32)(A) & 0x0000ff00) << 8) | \(((uint32)(A) & 0x000000ff) << 24))四、大端小端检测方法:如何检查处理器是big-endian还是little-endian?联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。

c语言中结构体中如何规避大端小端问题的方法

c语言中结构体中如何规避大端小端问题的方法

c语言中结构体中如何规避大端小端问题的方法【摘要】在C语言中,结构体中的数据在不同大小端系统中可能会出现字节序问题。

为了规避这个问题,可以采取多种方法。

可以使用统一的字节序,即在定义结构体时按照某种规定的顺序排列成员变量。

可以使用位域来手动指定每个成员变量的字节排列顺序。

也可以使用网络字节序函数来统一处理字节序转换。

手动转换字节序和使用联合体也都是解决大端小端问题的有效方法。

通过选择合适的方法,可以在C 语言中避免结构体中的大端小端问题,确保数据在不同系统中的正确传输和解析。

【关键词】引言, 背景介绍, 使用统一的字节序, 使用位域, 使用网络字节序函数, 使用手动转换字节序, 使用联合体, 总结1. 引言1.1 背景介绍在计算机系统中,数据通常以字节序列的形式存储和传输。

不同系统的字节序可能会有所不同,主要分为大端和小端两种类型。

大端表示数据的高位字节存储在内存的低地址处,而小端则相反,高位字节存储在高地址处。

在C语言中,结构体是一种用于存储相关数据的数据类型,它的成员在内存中是按照定义的顺序依次存储的。

当结构体中包含多字节数据类型的成员时,可能会涉及到大端小端问题。

如果不加以处理,将会导致在不同字节序系统中出现数据错误的情况。

为了规避大端小端问题,我们可以采取一些方法来确保数据在不同系统之间的兼容性。

这些方法包括使用统一的字节序、使用位域、使用网络字节序函数、使用手动转换字节序以及使用联合体等。

通过正确选择和应用这些方法,我们可以有效地处理结构体中的大端小端问题,确保数据的正确传输和存储。

2. 正文2.1 使用统一的字节序在C语言中,结构体中的成员在不同平台上可能会出现大端小端问题。

为了规避这个问题,我们可以使用统一的字节序来确定结构体中成员的存储顺序。

一种简单的方法是在定义结构体时按照特定的顺序排列成员,这样就可以避免不同平台上字节序的差异。

可以按照从高位到低位的顺序排列成员,确保在任何平台上都能正确地存储和读取数据。

共用体union的妙用

共用体union的妙用

共用体union的妙用结构体struct 是一个常用的数据类型,主要是将各种类型的数据打包成一个新的数据类型,在驱动开发,寄存器的定义等方面都有比较大的优势。

在使用的过程中需要注意空结构体的大小以及对齐(8 字节)对数据大小的影响。

具体的应用就不说了。

另一个与struct 非常相近的数据类型union 则相对运用的较少,但是如果理解了union 的本质就会发现该数据类型的好处。

union 主要是将各种类型的数据存放在一段固定的存储器中,存储器的大小由union 中需要最大存储器的数据类型决定。

比如:union student{ char ***; int age; long number; double score;};其中long、double 需要16 个字节,而char 只需要1 个字节,因此该共用体占用16 个字节。

union 的关键是不同的数据类型共用存储器。

主要的运用:1、确定CPU 的模式:大端、小端模式确定大小端不同,则存储的方式也存在差别,比如int 需要4 个字节,而char 只需要1 个字节,根据1 个字节所在的具体位置即可判定CPU 的模式union TestCPU{ int i; char ch;};void testCPUMode(void){ union TestCPU Test; Test.i = 1; if(Test.ch == 1) { //这个CPU 是小端模式} else { //这种情况下就是大端模式}}2、实现不同数据之间的类型转换union Type{ int i; char ch; long lint; ....};...union Type type;这样各种类型的数据共用存储空间,很方便的实现了不同数据类型之间的转换,不需要显示的强制类型转换。

union 相比struct 更加的节省空间。

3、寄存器的定义,实现整体的访问和单项的访问。

struct register{char a;char b;char c;char d;};union Register{ struct register; int whole;};这样就能实现单项和整体的访问,特别是引入位域操作等相关结构以后,能够实现每一个bit 的访问。

大端模式与小端模式理解

大端模式与小端模式理解

⼤端模式与⼩端模式理解字节序字节序指多字节数据在计算机内存储或者⽹络上传输时各字节的顺序。

(来源:百度百科)为了⽅便,逻辑上将字节序列⾥左边的字节称为⾼字节,右边的字节称为低字节,从左到右,由⾼到低,这样符合数学上的思维习惯,左边是⾼位,右边是地位。

⼤端模式与⼩端模式由于每个字节在内存中都是有地址的,并且内存的地址是顺序排列的,当我们在内存中保存数据时:如果,⾼字节存放在低地址,低字节存放在⾼地址,则为⼤端模式(big-endian)。

如果,低字节存放在低地址,⾼字节存放在⾼地址,则为⼩端模式(little-endian)。

数据从内存保存到⽂件(或发送到⽹络上)时,会受到内存的⼤端模式与⼩端模式的影响。

数据从⽂件读取到(或从⽹络接收到)内存时,需要知道之前是先保存的(或是先发送的)⾼字节还是低字节。

C++⽰例代码1//int 占 4 个字节,short 占 2 个字节int main(){printf("在栈上分配内存\n");int a = 0x11223344;short b = 0x5566;short c = 0x7788;unsigned char *pa = (unsigned char *)&a;unsigned char *pb = (unsigned char *)&b;unsigned char *pc = (unsigned char *)&c;printf("pa 0x%p 0x%x\n", pa, a);printf("pb 0x%p 0x%x\n", pb, b);printf("pc 0x%p 0x%x\n", pc, c);printf("按字节序打印所有字节(⾼字节->低字节)\n");printf("a0 0x%x\n", (a & 0xFF000000) >> (3 * 8));printf("a1 0x%x\n", (a & 0x00FF0000) >> (2 * 8));printf("a2 0x%x\n", (a & 0x0000FF00) >> (1 * 8));printf("a3 0x%x\n", (a & 0x000000FF));printf("b0 0x%x\n", (b & 0xFF00) >> (1 * 8));printf("b1 0x%x\n", (b & 0x00FF));printf("c0 0x%x\n", (c & 0xFF00) >> (1 * 8));printf("c1 0x%x\n", (c & 0x00FF));printf("根据地址顺序打印所有字节(低地址->⾼地址)\n");for (int i = 0; i < 4; i++) {printf("pa[%d] 0x%p 0x%02x\n", i, pa + i, pa[i]);}for (int i = 0; i < 2; i++) {printf("pb[%d] 0x%p 0x%02x\n", i, pb + i, pb[i]);}for (int i = 0; i < 2; i++) {printf("pc[%d] 0x%p 0x%02x\n", i, pc + i, pc[i]);}return 0;}⽰例代码1运⾏结果在栈上分配内存pa 0x007ffe24 0x11223344pb 0x007ffe22 0x5566pc 0x007ffe20 0x7788按字节序打印所有字节(⾼字节->低字节)a0 0x11a1 0x22a2 0x33a3 0x44b0 0x55b1 0x66c0 0x77c1 0x88根据地址顺序打印所有字节(低地址->⾼地址)pa[0] 0x007ffe24 0x44pa[1] 0x007ffe25 0x33pa[2] 0x007ffe26 0x22pb[0] 0x007ffe22 0x66pb[1] 0x007ffe23 0x55pc[0] 0x007ffe20 0x88pc[1] 0x007ffe21 0x77⽰例代码1结果分析a、b、c 在内存中的排列情况:---------------------------------------------------|低地址 -> ⾼地址|---------------------------------------------------|....|0x88|0x77|0x66|0x55|0x44|0x33|0x22|0x11|....|---------------------------------------------------a、b、c 是在栈中分配的,可以看到内存地址是连续的,且 a 的地址相对较⾼,c 的地址相对较低。

C语言程序判断计算机的CPU大小端

C语言程序判断计算机的CPU大小端

C语言程序判断计算机的CPU大小端第一篇:C语言程序判断计算机的CPU大小端如何判断一台计算机的CPU是大端还是小字端对齐呢?那么首先得了解何为大端,何为小端,明确一下概念。

所谓大端模式,是指字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。

小端格式:与大端存储格式相反,在小端存储格式中,低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节。

那么如何使用C语言程序判断CPU是大端还是小端对齐呢?有几个方法:方法一:直接使用看变量的内存值,这里需要使用一些调试技巧。

方法二:使用C中的共用体:请写一个C函数,若处理器是Big_endian的,则返回false;若是Little_endian的,则返回true。

bool IsLitte_Endian(){union w{int a;char b;}c;c.a=1;return(c.b==1);}方法三:强制类型转换,和共用体的做法差不多。

bool IsLitte_Endian(){int wTest = 0x12345678;short *pTest=(short*)&wTest;return!(0x1234 == pTest[0]);}第二篇:计算机Cpu介绍计算机Cpu介绍从计算机组成的观点来看,计算机中最重要的核心部件是Cpu (中央处理单元),以不同的Cpu类型划分计算机是否可行呢?生产Cpu的厂商非常多,不同Cpu厂商之间的产品逐步分化为两大阵容:Cisc(复杂指令系统)系列和Risc(简单指令系统)系列!在Cisc系列产品中,主要包括Intel、Amd(超威)、Via(盛威)生产的X86系列Cpu产品,它们在硬件上虽然不完全兼容,但是在操作系统一级上是相互兼容的,也就是说,它们都可以运行Microsoft 的Dos或Windows操作系统。

我们通常所说的微机,大部分是指这类微机。

生产Risc系列的Cpu厂商有Ibm、Motorola(摩托罗拉)、Sun、(太阳)、Hp(惠普)等,它们之间的Cpu产品在硬件上互不兼容,在软件上也无法统一!因此,它们生产的计算机有些称为“微机”,如采用Powerpc芯片的苹果微机,它们的操作系统为苹果公司自己开发的Mac oxc;也有些称为“工作站”,如Sun公司采用Ultras ArcⅢ芯片生产的计算机,它们采用Sun公司设计的Solaris操作系统!生产Cpu的厂商非常多,不同Cpu厂商之间的产品逐步分化为两大阵容:Cisc(复杂指令系统)系列和Risc(简单指令系统)系列!无论是采用Cisc芯片,还是采用Risc芯片,都可以采用单元Cpu 芯片组成微机系统,或采用多个Cpu芯片组成大型服务器计算系统,甚至采用成千上万个Cpu芯片组成超级计算机系统。

大小端存储模型对union的影响

大小端存储模型对union的影响

计算机都是以八位一个字节为存储单位,那么一个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 ||______________|_____________|低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端->低位->在前->与正常逻辑顺序相反)总结:大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。

小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

union型数据所占的空间等于其最大的成员所占的空间。

对union型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union的首地址位置开始,因此,大小端模式存储将会直接影响union内成员的值。

C语言内存地址对齐及大小端

内存地址对齐及大小端
我们常常看到“alignment", "endian"之类的字眼, 但很少有C语言教材提到这些概念. 实际上它们是与处理器与内存接口, 编译器类型密切相关的.
考虑这样一个例子: 两个异构的CPU进行通信, 定义了这样一个结果来传递消息:
struct Message
{
short opcode;
char subfield;
long message_length;
char version;
short destination_processor;
}message;
用这样一个结构来传递消息貌似非常方便, 但也引发了这样一个问题: 若这两种不同的CPU对该结构的定义不一样, 两者就会对消息有不同的理解. 有可能导致二义性. 会引发二义性的有这两个方面:
确定某一个字节.
Motorola, Sun的机器一般采用大端. 当然, 这不代表所有情况. 有的CPU即能工作于小端, 又能工作于大端, 比如ARM, PowerPC, Alpha. 具体情形参考处理器手册.
举个例子来说名大小端: 比如一个int x, 地址为0x100, 它的值为0x1234567. 则它所占据的0x100, 0x101, 0x102, 0x103地址组织如下图:
0x01234567的MSB为0x01, LSB为0x67. 0x01在低地址(或理解为"MSB出现在LSB 前面,因为这里讨论的地址都是递增的), 则为大端; 0x67在低地址则为小端.。

c语言编程题大小端的转换及实现

C语言编程题:大小端的转换及实现在计算机领域,大小端字节序是一个重要的概念。

它描述了存储器中多字节数据的排列顺序。

在C语言编程中,理解大小端并能够实现大小端的转换是非常重要的。

本文将从简单的概念入手,逐步深入探讨大小端的含义、实现方法以及在实际编程中的应用。

1. 什么是大小端?在计算机中,一个字节通常由8个bit组成。

在多字节数据的存储过程中,即两个字节或更多字节的数据,就会涉及到大小端的问题。

所谓的大小端,指的是多字节数据中高字节和低字节的存储顺序。

•大端字节序(Big Endian):高字节存储在低位置区域,低字节存储在高位置区域。

•小端字节序(Little Endian):低字节存储在低位置区域,高字节存储在高位置区域。

2. 大小端的转换在实际编程中,经常会遇到需要进行大小端转换的情况。

特别是在进行数据交换、网络传输或与硬件交互时,正确处理大小端是非常重要的。

下面我们将介绍一些在C语言中实现大小端转换的方法。

2.1 通过位运算实现大小端转换位运算是C语言中常用的操作之一,我们可以通过位运算来实现大小端的转换。

以下是一个示例代码:#include <stdio.h>unsigned int swapEndian(unsigned int value) {return ((value>>24)&0xff) | // 将高8位移到低8位((value<<8)&0xff0000) | // 将次高8位移到次低8位((value>>8)&0xff00) | // 将次低8位移到次高8位((value<<24)&0xff000000); // 将低8位移到高8位}2.2 通过联合体(union)实现大小端转换在C语言中,使用联合体也可以很方便地进行大小端的转换。

通过联合体,我们可以同时访问同一块内存的不同部分,从而实现大小端的转换。

大小端笔试题

大小端笔试题
以下是一份关于大小端问题的笔试题:
1.什么是大小端问题?
大小端问题是指计算机在存储多字节数据时,采用大端字节序(Big-Endian)或小端字节序(Little-Endian)的顺序进行存储。

大端字节序是指高位字节存储在内存的低地址处,而小端字节序是指低位字节存储在内存的低地址处。

2.大小端问题对编程有什么影响?
大小端问题对编程的影响主要体现在数据在网络传输、不同系
统间通信、跨平台数据交换等方面。

由于不同系统、不同硬件
架构可能采用不同的字节序,因此在进行这些操作时需要考虑
字节序的一致性问题,否则可能会出现数据解析错误或数据传
输错误。

3. 如何编写跨平台的网络通信程序?
在编写跨平台的网络通信程序时,需要考虑大小端问题。

可以
采用网络字节序(大端字节序)进行数据传输,并在发送和接
收数据时进行大小端的转换。

在C语言中,可以使用ntohl()和
ntohs()函数进行网络字节序和主机字节序之间的转换。

在Java
中,可以使用ByteOrder类来进行字节序的转换。

此外,为了
简化跨平台通信的问题,还可以使用跨平台的通信库,如
ZeroMQ等。

用指针解决大小端问题的方法

用指针解决大小端问题的方法一、大小端问题的产生与影响在计算机系统中,大小端问题主要是由于数据在不同架构或不同系统间传输时,字节顺序不同而引发的。

在很多系统架构中,数据的高位字节存储在内存的低地址中,而低位字节存储在内存的高地址中,这被称为“大端”模式。

反之,如果低位字节存储在内存的低地址中,则称为“小端”模式。

这种字节顺序的差异可能会对程序产生一些问题。

1. 数据序列化问题:在多字节数据的传输和存储中,如果系统之间的大小端模式不一致,会导致接收方解析数据时出现错误。

2. 兼容性问题:软件需要在不同架构的硬件和操作系统上运行时,大小端问题可能会影响其兼容性。

3. 性能问题:处理大小端转换的开销可能会影响程序的性能。

二、指针在解决大小端问题中的重要性指针是C和C++等语言中用于访问内存地址的重要工具。

通过指针,我们可以直接操作内存中的数据,包括读写、移动等操作。

因此,指针在解决大小端问题中扮演着重要角色。

1. 直接操作内存:指针允许我们直接读写内存中的数据,这使得我们可以在程序中直接进行字节顺序的转换,避免了数据传输和解析时的错误。

2. 高效解决方案:使用指针进行大小端转换可以在编译时进行优化,从而提高转换的效率。

3. 跨平台兼容性:通过使用指针进行大小端转换,我们可以编写出更加跨平台兼容的代码,提高了软件的可用性和可维护性。

三、使用指针解决大小端问题的具体方法在C/C++语言中,我们可以使用指针来对内存中的数据进行操作,从而达到解决大小端问题的目的。

具体方法如下:1. 使用联合体(Union):联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。

通过使用联合体,我们可以将一个多字节的数据类型与一个单字节的数据类型进行转换,从而实现大小端的转换。

例如:union {int i;char c[sizeof(int)];} x;x.i =123456789;// 打印结果可能因平台不同而不同for (int j =0; j <sizeof(int); j++) {printf("%02x ", x.c[j]);}在这个例子中,我们将一个int类型的整数存储在联合体中,然后将每个字节分别打印出来。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、一些问题
问题1
1.#include "stdio.h"
2.union
3.{
4. int i;
5. char ch[2];
6.}key;
7.main()
8.{
9. key.i=65*256+66;
10. printf("%c\t%c\n",key.ch[0],key.ch[1]);
11.}
答案是B A;为什么不是A B呢?
在前面的文章中我们已经测试过,X86体系结构的CPU是小端模式的。

比如一个数0x1234,放在内存里按照内存地址从低往高实际上是低地址字节里放的是0x34,高字节里放的是0x12。

小端模式和我们平时感觉上的一致,把数位数越高的部分放在地址越高的部分。

union 类型是共享内存的,union中是按照从低到高放的,i=0x4142,也就是低地址中放的是42,高地址中放的是41,按照ch[0],ch[1]的顺序输出就是B A。

如果是大端模式的话就是打印两个空了,故不会出现A B的情况。

问题2
1.union myun
2.{
3.struct { int x; int y; int z; }u;
4. int k;
5.}a;
6.int main()
7.{
8. a.u.x =4;
9. a.u.y =5;
10. a.u.z =6;
11. a.k = 0;
12. printf("%d %d %d\n",a.u.x,a.u.y,a.u.z);
13. return 0;
14.}
union类型是共享内存的,以size最大的结构作为自己的大小,这样的话,myun这个结构就包含u这个结构体,而大小也等于u这个结构体的大小,在内存中的排列为声明的顺序x,y,z从低到高,然后赋值的时候,在内存中,就是x的位置放置4,y的位置放置5,z的位置放置6,现在对k赋值,对k的赋值因为是union,要共享内存,所以从union的首地址开始放置,首地址开始的位置其实是x的位置,这样原来内存中x的位置就被k所赋的值代替了,就变为0了,这个时候要进行打印,就直接看内存里就行了,x的位置也就是k的位置是0,而y,z的位置的值没有改变,所以应该是0,5,6。

问题3
1.int checkCPU()
2.{
3.union
4.{
5.int a;
6.char b;
7.}c;
8. c.a = 1;
9.return (c.b == 1); // 小端返回TRUE,大端返回FALSE
10.}
这个就不详细解释了,用来判定CPU大小端模式的一个经典例子。

问题4
1.union {
2. int a[2];
3. long b;
4. char c[4];
5.}s;
6.main()
7.{
8. s.a[0]=0x12345678;
9. s.a[1]=0x23456789;
10. printf("%lx\n",s.b);
11. printf("%x,%x,%x,%x\n",s.c[0],s.c[1],s.c[2],s.c[3]);
12.}
答案是:
12345678
78,56,34,12
问题5
1.# include <stdio.h>
2.main()
3.{
4. union {
5. long i;
6. int k;
7. char ii;
8. char s[4];
9. } mix ;
10. mix.k=0x23456789;
11. printf("mix.i=%lx\n",mix.i);
12. printf("mix.k=%x\n",mix.k);
13. printf("mix.ii=%x\n",mix.ii);
14. printf("mix.s[0]=%x\tmix.s[1]=%x\n",mix.s[0],mix.s[1]);
15. printf("mix.s[2]=%x\tmix.s[3]=%x\n",mix.s[2],mix.s[3]);
16. return 0;
17.}
答案是:
mix.i=23456789
mix.k=23456789
mix.ii=ffffff89
mix.s[0]=ffffff89 mix.s[1]=67
mix.s[2]=45 mix.s[3]=23
出现f是因为把char型强制转换成int型输出,0x89最高位1000 1001最高位为1,转换为int类型的时候认为是负数,而且数在计算机中是按补码存储的,所以自然高位补1了。

2、这是一个什么问题
2.1、共用体结构的意义
问题:
假设网络节点A 和网络节点B 中的通信协议涉及四类报文,报文格式为“报文类型字段+报文内容的结构体”,四个报文内容的结构体类型分别为STRUCTTYPE1~ STRUCTTYPE4,如何编写程序以最简单的方式组织一个统一的报文数据结构。

分析:
报文的格式为“报文类型+报文内容的结构体”,在真实的通信中,每次只能发四类报文中的一种,我们可以将四类报文的结构体组织为一个union(共享一段内存,但每次有效的只是一种),然后和报文类型字段统一组织成一个报文数据结构。

解答:
1.typedef unsigned char BYTE;
2.//报文内容联合体
3.typedef union tagPacketContent
4.{
5.STRUCTTYPE1 pkt1;
6.STRUCTTYPE2 pkt2;
7.STRUCTTYPE3 pkt1;
8.STRUCTTYPE4 pkt2;
9.}PacketContent;
10.//统一的报文数据结构
11.typedef struct tagPacket
12.{
13.BYTE pktType;
14.PacketContent pktContent;
15.}Packet;
当多个基本数据类型或复合数据结构要占用同一片内存时,我们要使用共用体;当多种类型,多个对象,多个事物只取其一时(我们姑且通俗地称其为“n 选1”),我们也可以使用共用体来发挥其长处。

把几种不同类型的变量放到同一段内存单元中,这些变量在内存中占用的字节数可能不同,但都从同一个地址开始存放。

也就是使用覆盖技术,几个变量互相覆盖。

同一个内存段可以用来存放几种不同类型的成员,但在每一瞬间只能存放其中一种,而不能同时存放几种。

即,每一瞬间只有一个成员起作用,其他的成员不起作用,不能同时存在和起作用。

共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去了作用。

2.2、大小端模式对共用体的影响
当共用体中有不同类型的变量,用一种变量类型给共用体赋值,但用另一种变量类型读取共用体的时候就涉及到大小端的问题。

比如在
问题1中,给int类型的变量i赋值,但通过char类型的数组来读取时,就要注意字节序的问题,也就是大小端的问题。

相关文档
最新文档