关于c语言中联合体/共用体中数据存放的问题?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于c语言中联合体/共用体中数据存放的问题?相关的知识,希望对你有一定的参考价值。
main()
union dt
int a;char b;double c;data;
data.a=5;
printf("%lf",data.c);
data.c的输出结果为什么总是0.000000?
联合表示几个变量公用一个内存位置,int 占用4个字节,double占用8个字节,
data.a=5只初始化了int型,double型未初始化,内存情况是未知的,所以输出情况应该是未定的。
但是程序运行的结果总是0.000000,我就非常疑惑了,能否解释下,谢谢!
附:我将data中8个字节分别以整数形式输出,第一个字节为5,第二三四字节都为零,后四个字节是随机的,但并不为零。这说明data.c应该不为零啊,为什么输出结果总是0.000000呢??
首先我们了解联合体的所有成员是在内存中共享一块内存的,在某一时刻只能有一个成员使用这个内存!!!
我们来看看一个例子:
#include <stdio.h>
union
int i;
char x[2];
a;
void main()
a.x[0] = 10;
a.x[1] = 1;
printf("%d",a.i);
答案:266
解释如下:
union
int i;
char x[2];
a;
在联合体a中定义了两种数据类型,字符数组x以及整形变量i.其中整形变量是16位的,数组大小为2的字符数组为8X2=16位。如此一来,编译器便会为联合体a在内存中开辟一个16位的空间,这个空间里存储联合体的数据,但是这个空间只有16位,它既是整形变量的数据,也是字符数组的数据。如果你的程序从字符数组的角度解析这个空间,那么它就是两个字符,如果你的程序从整型的角度解析这个空间,那么它就是一个整数。
以你的程序为例子,现在已经开辟了一个16位的空间,然后我们假定现在空间还没有被赋值,为:
00000000 00000000
那么在运行完代码
a.x[0] = 10;
a.x[1] = 1;
之后,16位的空间变为:
00001010 00000001
然后程序运行
printf("%d",a.i);
就是把联合体a当成一个整数来解析,而不是字符串数组。那么这样一来,程序就把这16位变成了一个完整的整数:
(00000001 00001010)二进制 = (266)十进制
注意,你可以看到程序在把16位弄成整数的时候把后面八位放在了前面,前面八位放在了后面。这个反序是计算机存储结构造成的,这个和联合体没有直接关系。如果感兴趣的话可以参考汇编语言。
现在我们来看看,你给的例子:
union dt
int a;
char b;
double c;
data;
此时的联合体所占的内存大小是8个字节,接下来执行:
data.a=5;
此此时内存中就不是空的了,也就不会是你说的是随机数,
但是输出:printf("%lf",data.c);结果是0.000000,这个结果我还不能给你准确的解释。但是我可以肯定这与系统把double转换成int 和int 转化成 double 有关!!!
暂时我只能解释这那多!!! 参考技术A C++ union(联合/共用体)用法 转
共用体类型数据的特点
1.同一个内存段可以用来存放几种不同类型的成员,但是在每一瞬间只能存放其中的一种,而不是同时存放几种。换句话说,每一瞬间只有一个成员起作用,其他的成员不起作用,即不是同时都在存在和起作用。
2.共用体变量中起作用的成员是最后一次存放的成员,在存入一个新成员后,原有成员就失去作用。
3.共用体变量的地址和它的各成员的地址都是同一地址。
4.不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,并且,不能在定义共用体变量时对它进行初始化。
5.不能把共用体变量作为函数参数,也不能是函数带回共用体变量,但可以使用指向共用体变量的指针。
6.共用体类型可以出现在结构体类型的定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型的定义中,数组也可以作为共用体的成员。
1. 共用体声明和共用体变量定义
共用体是一种特殊形式的变量,使用关键字union来定义
共用体声明和共用体变量定义与结构体十分相似。其形式为:
union 共用体名
数据类型 成员名;
数据类型 成员名;
...
变量名;
共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在 union中,所有的共用体成员共用一个空间,并且只能储存其中一个成员变量的值。
下例表示声明一个共用体foo:
union foo
int i;
char c;
double k;
;
再用已声明的共用体可定义共用体变量。
例如用上面说明的共用体定义一个名为bar的共用体变量, 可写成:
union foo bar;
在共用体变量bar中, 整型变量i和字符变量c共用同一内存位置。
当一个共用体被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。以上例而言,最大长度是double数据类型,所以foo的内存空间就是double型的长度。
由于union的资料成员共用一个内存空间,所以必须存取正确的成员才能正确的读取变量值,可以使用一个额外的变数或列举型态来记录最后一次使用空间的是哪个成员,例如:
#include <iostream>
using namespace std;
union StateMachine
public:
char character;
int number;
char *str;
StateMachine(char c)
character = c;
StateMachine(int n)
number = n;
StateMachine(char* s)
str = s;
;
enum State character, number, str;
int main()
State state = character;
StateMachine machine('J');
...
if(state == character)
cout << machine.character << endl;
...
return 0;
另外要注意的是,union的成员不可以为静态、参考,如果是自订型态的话,该自订型态成员不可以有建构函式、解构函式或是复制指定运算子。
2. 共用体和结构体的区别
共用体和结构体有 下列区别:
1. 共用体和结构体都是由多个不同的数据类型成员组成, 但在任何同一时刻, 共用体只存放了一个被选中的成员, 而结构体的所有成员都存在。
2. 对于共用体的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构体的不同成员赋值是互不影响的。 参考技术B printf("%lf",data.c);
--》
printf("%10.2f",data.c);
结果是5.0。
C语言中结构体的理解
参考技术A一、结构体定义
结构体是一个或多个数据的集合,这些数据可以是不同的类型,结构体相当于 数组 的升级。假如我们要统计一个班级学生的成绩,成绩属于float类型,我们可以将成绩用 数组 存放。但是如果要统计一个班级的学生的姓名、性别、成绩,姓名为字符串型,年龄为整数型,成绩为小数型,因为数据类型不同,显然不能用 数组 存放。为了解决这一问题,C语言中给出了另一种构造数据类型——结构体(Struct)。它可以将同一对象的多个数据类型存储在一起。
二、定义形式
方式1 、将结构体变量直接放在结构体尾端
Struct 结构体名
类型1 元素1;
类型2 元素2;
…
类型n 元素n;
结构体变量;
例 :假设将一个班级学生的“姓名”定义为结构体变量,“性别”和“成绩”为结构体内部元素
Struct Student
char* sex; //性别
float score; //成绩
zhangsan; //学生姓名张三
方式2 、先定义结构体,然后在定义结构体变量
Struct 结构体名
类型1 元素1;
类型2 元素2;
…
类型n 元素n;
;
Struct 结构体名 结构体变量;
例 :假设将一个班级学生的“姓名”定义为结构体变量,“性别”和“成绩”为结构体内部元素
Struct Student
char* sex; //性别
float score; //成绩
;
Struct Student zhangsan; //学生姓名张三
方式3、将结构体名省略
Struct
类型1 元素1;
类型2 元素2;
…
类型n 元素n;
结构体变量;
例 :假设将一个班级学生的“姓名”定义为结构体变量,“性别”和“成绩”为结构体内部元素
Struct
char* sex; //性别
float score; //成绩
zhangsan; //学生姓名张三
三、结构体初始化
以方式2的例子为例
Struct Student
char* sex; //性别
float score; //成绩
;
Struct Student zhangsan; //学生姓名张三
/****初始化*****/
Struct Student zhangsan=“nan”,100; //张三 男 成绩100
四、结构体使用
以方式2的例子为例
Struct Student
char* sex; //性别
float score; //成绩
;
Struct Student zhangsan; //学生姓名张三
/****初始化*****/
Struct Student zhangsan=“nan”,100; //张三 男 成绩100
/****使用*****/
zhangsan. score =60; //将张三成绩赋值60
以上是关于关于c语言中联合体/共用体中数据存放的问题?的主要内容,如果未能解决你的问题,请参考以下文章