C语言union关键字

union 关键字的用法与struct 的用法非常类似。

union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。例子如下:
union StateMachine
{
   char character;
   int number;
   char *str;
   double exp;
};

一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,最大长度是double 型态,所以StateMachine 的空间大小就是double 数据类型的大小。

在C++里,union 的成员默认属性页为public。union 主要用来压缩空间。如果一些数据不可能在同一时间同时被用到,则可以使用union。

一、大小端模式对union 类型数据的影响

下面再看一个例子:
union
{
   int i;
   char a[2];
}*p, u;
p =&u;
p->a[0] = 0x39;
p->a[1] = 0x38;

p.i 的值应该为多少呢?

这里需要考虑存储模式:大端模式和小端模式。
  1. 大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
  2. 小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。
union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。如此一解释,上面的问题是否已经有了答案呢?

二、如何用程序确认当前系统的存储模式?

上述问题似乎还比较简单,那来个有技术含量的:请写一个C 函数,若处理器是Big_endian 的,则返回0;若是Little_endian 的,则返回1。

先分析一下,按照上面关于大小端模式的定义,假设int 类型变量i 被初始化为1。

以大端模式存储,其内存布局如下图:
以小端模式存储,其内存布局如下图:
变量i 占4 个字节,但只有一个字节的值为1,另外三个字节的值都为0。如果取出低地址上的值为0,毫无疑问,这是大端模式;如果取出低地址上的值为1,毫无疑问,这是小端模式。既然如此,我们完全可以利用union 类型数据的特点:所有成员的起始地址一致。

到现在,应该知道怎么写了吧?参考答案如下:
int checkSystem( )
{
   union check
   {
      int i;
      char ch;
   } c;
   c.i = 1;
   return (c.ch ==1);
}

现在你可以用这个函数来测试你当前系统的存储模式了。当然你也可以不用函数而直接去查看内存来确定当前系统的存储模式。如下图:
图中0x01 的值存在低地址上,说明当前系统为小端模式。

不过要说明的一点是,某些系统可能同时支持这两种存储模式,你可以用硬件跳线或在编译器的选项中设置其存储模式。

留个问题:在x86 系统下,输出的值为多少?
#include <stdio.h>
intmain()
{
   int a[5]={1,2,3,4,5};
   int *ptr1=(int *)(&a+1);
   int *ptr2=(int *)((int)a+1);
   printf("%x,%x",ptr1[-1],*ptr2);
   return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450412.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js 深拷贝 和 浅拷贝

1、 ...运算符 &#xff08;浅拷贝&#xff09; let obj {a:1,b:2}; let obj2 {...obj}; obj.a3 obj //{a: 3, b: 2} obj2 //{a: 1, b: 2}a {a:[{b:1}]}; b a ;b.a[0].b 2; //b {a:[{b:2}]}a // a {a:[{b:2}]} 2、 JSON.parse(JSON.stringify(参数))…

软考如何备考

软考上半年 报名时间 3月 考试时间 5月 备考持续时间&#xff1a;一个半月&#xff0c;每天至少两个小时。 第一轮 基础知识轮&#xff0c; 15天 在这一轮中如果碰到无法理解的知识点一定不要过于纠结&#xff0c;往后学&#xff0c;一般后面的学着学着之前的内容就…

Python学习第一天-第2节

*本节课内容参见&#xff1a;https://www.cnblogs.com/jin-xin/articles/7459977.html运行第一个Python程序 print(hello world) 将文本文件保存为以.py结尾的文件&#xff0c;如hello_world.py &#xff0c;在终端中&#xff0c;运行命令&#xff1a;Python hello_world.py&am…

SpringMVC之组合注解@GetMapping

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Spring4.3中引进了&#xff5b;GetMapping、PostMapping、PutMapping、DeleteMapping、PatchMapping&#xff5d;&#xff0c;来帮助简化…

资源下载地址

1、nginx http://nginx.org/en/download.html 2、nodejs http://nodejs.cn/download/ 3、vscode https://code.visualstudio.com/ 4、canal https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal.deployer-1.1.4.tar.gz 5、jenkins https://jenkins.io/i…

C语言volatile关键字—最易变的关键字

volatile 是易变的、不稳定的意思。很多人根本就没见过这个关键字&#xff0c;不知道它的存在。也有很多程序员知道它的存在&#xff0c;但从来没用过它。我对它有种“杨家有女初长成,养在深闺人未识” 的感觉。volatile 关键字和const 一样是一种类型修饰符&#xff0c;用它修…

mysql 备份脚本

#!/bin/bash INNOBACKUPEXFULL"/usr/bin/innobackupex" MYSQL_CMD --socket/ssd/mysql/3346/tmp/mysql.sock --userroot --passwordmysqlpassword --port3346 MYSQL_UP --userroot --passwordmysqlpassword --port3346 #mysqladmin的用户名和密码 TMPLOG"/dat…

爆栈的处理方法

爆栈指递归中&#xff0c;存储的信息量大于系统栈的内存。 信息量包括元素编号&#xff0c;每一层中开的变量。 和递归的层数正相关。 &#xff08;虽然noip一般开栈&#xff09; 1.手写栈 while(top){ int xsta[top]; for(each son) if(has son){ //blablabla sta[top]son; h…

项目面试题

项目面试题 1.描述最熟悉的或者&#xff08;最近&#xff09;的一个项目 &#xff1f; 目的&#xff1a;检测技术和项目的熟悉程度工作职责 回答&#xff1a;项目名称&#xff0c;项目的甲方&#xff0c;背景&#xff0c;实现的目的和意义&#xff0c;该项目主要是为了解决什…

MySQL定时备份(全量备份+增量备份)

MySQL 定时备份 参考 zone7_ 的 实战-MySQL定时备份系列文章 参考 zmcyu 的 mysql数据库的完整备份、差异备份、增量备份 更多binlog的学习参考马丁传奇的 MySQL的binlog日志&#xff0c;这篇文章写得认真详细&#xff0c;如果看的认真的话&#xff0c;肯定能学的很好的。 如果…

java 接口可以多继承

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 接口是常量值和方法定义的集合。接口是一种特殊的抽象类。 java类是单继承的。classB Extends classA java接口可以多继承。Interface…

C语言struct关键字详解—结构体

struct 是个神奇的关键字&#xff0c;它将一些相关联的数据打包成一个整体&#xff0c;方便使用。在网络协议、通信控制、嵌入式系统、驱动开发等地方&#xff0c;我们经常要传送的不是简单的字节流&#xff08;char 型数组&#xff09;&#xff0c;而是多种数据组合起来的一个…

JDK1.8使用Dubbo时需注意

2019独角兽企业重金招聘Python工程师标准>>> Dubbo自带的很多包都比较旧了&#xff0c;其中的javassist在JDK1.8上运行会报错 而且错误通常比较诡异&#xff0c;javassist是编辑和创建Java字节码的类库&#xff0c;常见的错误会从spring中报出 解决办法&#xff1a;…

Java 11 已发布,String 还能这样玩!

在文章《Java 11 正式发布&#xff0c;这 8 个逆天新特性教你写出更牛逼的代码》中&#xff0c;我有介绍到 Java 11 的八个新特性&#xff0c;其中关于 String 加强部分&#xff0c;我觉得有点意思&#xff0c;这里单独再拉出来讲。 Java 11 增加了一系列的字符串处理方法&…

Redis1 晨考题

Redis1 晨考题 1.Redis 是什么 &#xff1f; redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 的内存数据库&#xff0c;并提供多种语言的 API。 2.NOSQL 是什么 &#xff1f;出现的目的和意义是什么 &#xff1f; NoSQL 泛指…

C语言void关键字

void 有什么好讲的呢&#xff1f;如果你认为没有&#xff0c;那就没有&#xff1b;但如果你认为有&#xff0c;那就真的有。有点像“色即是空&#xff0c;空即是色”。一、void a&#xff1f; void 的字面意思是“空类型”&#xff0c;void *则为“空类型指针”&#xff0c;vo…

深入了解RabbitMQ工作原理及简单使用

深入了解RabbitMQ工作原理及简单使用 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建深入了解RabbitMQ工作原理及简单使用RabbitMQ交换器Exchange介绍与实践RabbitMQ事务和Confirm发送方消息确认——深入解读使用Docker部署RabbitMQ集群你不知道的RabbitMQ集群架构全解RabbitM…

使用el-checkbox实现全选,点击失效没有反应

最近在公司接收到了一个需求&#xff0c;给收藏夹的书籍添加批量、全选删除实现思路&#xff1a;点击全选改变item的checked&#xff0c;改变item的checked&#xff0c;重新便利一下所有item的checked来改变全选的selectAll1&#xff09;该组件基本功能已经实现&#xff0c;che…

Spring3.2新注解@ControllerAdvice

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 ControllerAdvice&#xff0c;是spring3.2提供的新注解&#xff0c;从名字上可以看出大体意思是控制器增强。让我们先看看ControllerAdv…

Mysql1 晨考题

Mysql1 晨考题 1.描述主键、外键、候选主键、超键分别是什么 &#xff1f; &#xff08;1&#xff09;主键&#xff1a;数据库表中对存储数据对象给予唯一完整标识的数据列或属性的组合。一个数据列只能有一个主 键&#xff0c;且主键的取值不能缺失&#xff0c;即不能为空值…