C语言 联合(union)用法案例详解

联合(union)的声明和结构与结构体类似,但是本质不同。

   联合的所有成员引用的是内存中的相同位置。当你想在不同时刻把不同的东西存储于同一位置时,就可以使用联合。

  构体(struct)中所有变量是“共存”的——优点是“有容乃大”,全面;缺点是struct内存空间的分配是粗放的,不管用不用,全分配。

  而联合体(union)中是各变量是“互斥”的——缺点就是不够“包容”;但优点是内存使用更为精细灵活,也节省了内存空间。

一个简单程序的分析

#include "stdio.h"
union{
    int a;
    float b;
    char c;
}x;
int main()
{
    x.c='x';
    x.b=3.14;
    x.a=25;
    printf("%g \t%c \t %d\t\n",x.b,x.c,x.a);
    return 0;
}

输出结果为 3.50325e-44       垃圾值     25 

可以看出  只有最后一个x.a=25; 因为x.b会把x.c的地址覆盖x.a会把x.b的地址覆盖  所以前两个打印的都是垃圾值只有最后一个打印正确。

  程序分析2

#include<stdio.h>
union var{
        long int l;
        int i;
};
main(){
        union var v;
        v.l = 5;
        printf("v.l is %d\n",v.i);
        v.i = 6;
        printf("now v.l is %ld! the address is %p\n",v.l,&v.l);
        printf("now v.i is %d! the address is %p\n",v.i,&v.i);
}
//结果:
//v.l is 5
//now v.l is 6! the address is 0xbfad1e2c
//now v.i is 6! the address is 0xbfad1e2c  

程序分析3

#include<stdio.h>
union u{
    int i;
    double d;//这个union有8字节大小
};
main(){
    union u uu;
    uu.i = 10;
    printf("%d\n",uu.i);
    char * c;
    c = (char *)&uu;//把union的首地址赋值、强转成char类型
    c[0] = 'a';
    c[1] = 'b';
    c[2] = 'c';
    c[3] = '\0';
    c[4] = 'd';
    c[5] = 'e';
    //最多能到c[7]
    printf("%s\n",c);//利用结束符'\0'打印字符串"abc"
    printf("%c %c %c %c %c %c\n",c[0],c[1],c[2],c[3],c[4],c[5]);
}  

输出

10
abc
a b c  d e

 printf("%s\n",c);//利用结束符'\0'打印字符串"abc" 字符串以‘\0'结束所以后面未打印

程序分析4

main()
{
   struct
   {
      char name[10];
      int age;
      char job;
      union
      {
         int class;
         char office[10];
      } depa;
   }body[2];

  int n,i;
   for(i=0;i<2;i++)
   {
      printf("input name,age,job and department\n");
      scanf("%s %d %c",body[i].name,&body[i].age,&body[i].job);
      if(body[i].job=='s')
         scanf("%d",&body[i].depa.class);
      else
         scanf("%s",body[i].depa.office);
   }
   printf("name\tage job class/office\n");
   for(i=0;i<2;i++)
   {
   if(body[i].job=='s')
      printf("%s\t%3d %3c %d\n",body[i].name,body[i].age ,body[i].job,body[i].depa.class);
   else
      printf("%s\t%3d %3c %s\n",body[i].name,body[i].age, body[i].job,body[i].depa.office);
   }
}

到此这篇关于C语言 联合(union)用法案例详解的文章就介绍到这了,更多相关C语言 联合(union)用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言中bool变量的深入理解

    目录 前言 bool类型变量的大小 bool 值与0比较 c语言中bool如何输出 总结 前言 在一些高级语言当中,为了能够完成更好的逻辑判断,因此就有了bool类型,bool类型的变量值只有true和false两种. 而在C语言中,一般认为0为假,非0为真. 这是因为c99之前,c90是没有bool类型的的.但是c99引入了_Bool类型(_Bool就是一个类型,不过在新增头文件stdbool.h中,被重新用宏写成了 bool,为了保证C/C++兼容性). 目前为止大部分C语言书籍采用的标准还

  • 奇怪的C语言特性

    下面列出的特性未必奇怪,有的算是有趣. 1)a[2] 等价于 2[a] "aabbccdd"[5] 等价于 5["aabbccdd"] 这条特性可以用于使用数组.指针.字符串,但不能用在变量定义时.K&R C Programming language 217页对此有介绍. 2)二元.三元复合字符 http://en.wikipedia.org/wiki/Digraphs_and_trigraphs 字符串字面值??!将被认为是|,所以两个问号同时出现在字符串

  • 嵌入式项目使用C语言结构体位段特性实现断言宏校验数据范围有效性的方法

    关于位段的特性这里就不多说了,多去看看相应的C语言书籍都会有介绍了. 今天来介绍断言宏.什么是断言宏?断言宏可以认为是校验数据范围的有效性的一个宏的实现.我们来看看代码: #include <stdio.h> //结构体位段 #define CHECK(x) sizeof(struct {unsigned:(-!!(x));}) //检查常量是否在一定范围之内,如果不在范围之内,则编译报错 //比如定义一个0到1000的范围,如果传入的xxx小于0或者大于1000,则编译器发现会报错 #def

  • C语言入门篇--局部全局变量的作用域及生命周期

    目录 1.变量的分类 1.1 局部变量 1.2 全局变量 1.3 知识点 1.3.1 就近原则 1.3.2 访问规则 1.3.3 有效范围 2.变量的使用 3.变量的作用域和生命周期 3.1 作用域 3.1.1 局部变量的作用域 3.1.2 全局变量的作用域 3.2 生命周期 3.2.1 局部变量的生命周期 3.2.2 全局变量的生命周期 1.变量的分类 1.1 局部变量 也称临时变量,在函数.代码块内定义,一般只可在代码块内部使用的变量. 1.2 全局变量 具有全局性,放在函数外,在同一___

  • C++在C语言基础之上增强的几个实用特性总结

    变量的定义 C语言中的变量都必须在作用域开始的位置定义!!  C++中更强调语言的"实用性",所有的变量都可以在需要使用时再定义. #include <iostream> using namespace std; int main11() { int i = 0; printf("ddd"); int k; // 这段代码在vc6,C语言编译情况下就会报错.就是因为这里的定义 system("pause"); return 0; }

  • C语言完整特性详情

    目录 C# 10 完整特性介绍 1.record struct 2.sealed record ToString 方法 3.struct 无参构造函数 4.匿名对象的 with 5.全局的 using 6.文件范围的 namespace 7.常量字符串插值 8.lambda 改进 8.1. 支持 attributes 8.2. 支持指定返回值类型 8.3. 支持 ref .in .out 等修饰 8.4. 头等函数 8.5. 自然委托类型 9.CallerArgumentExpression 1

  • C语言基于考研的栈和队列

    目录 栈 栈的基本操作 三角矩阵 总结 栈 栈的基本操作 InitStack(&S):初始化 StackEmpty(S):判空,空则true,非空则false Push(&S,x):入栈 Pop(&S,&x):出栈,并用x返回元素内容 GetTop(S,&x):读栈顶元素 DestroyStack(&S):销毁并释放空间 栈是一种受限的线性表,只允许在一端操作 栈若只能在栈顶操作,则只可能上溢 采用非递归方式重写递归时,不一定要用栈,比如菲波那切数列只要用循

  • C语言入门篇--函数及数组用法

    目录 函数 1.函数的作用 2.函数的构成 (1)返回值 (2)函数名 (3)形参列表 (4)函数体 数组 1.定义数组 1.1不进行初始化 1.2进行初始化 1.3不给定数组元素个数 2.数组的经典用法 2.1求数组大小.元素大小.元素个数 2.2遍历 面向过程编程:C语言是面向过程的语言:在C语言中,把大部分的功能以一个个函数呈现,就称之为面向过程编程: 函数 是面向过程编程最关键的语法结构. 1.函数的作用 1.从工程上讲,函数可以让我们的代码更具有结构性,让代码更好看. 2.函数可以提升

  • C语言的数组与指针你了解吗

    目录 前言 一.数组的定义 二.数组空间的初始化 1. char数组赋值 2.char数组硬件开发规范 二.数组与指针 总结 前言 自学笔记,没有历史知识铺垫(省略百度部分)C语言数组的概念及使用 一.数组的定义 char a[n]; 注意:数组与指针非常相似 二者的区别: 数组为常量,约定禁止二次赋值,即数组不应该出现在=左侧,如:a="HelloWorld";数组在声明时,会申请一段连续的内存空间,指针不会数组元素为变量,标记可以修改指向任意内存(实际上会copy右侧变量/常量到左

  • 整理C语言中各种类型指针的特性与用法

    指针为什么要区分类型: 在同一种编译器环境下,一个指针变量所占用的内存空间是固定的.比如,在16位编译器环境 下,任何一个指针变量都只占用8个字节,并不会随所指向变量的类型而改变. 虽然所有的指针都只占8个字节,但不同类型的变量却占不同的字节数. 一个int占用4个字节,一个char占用1个字节,而一个double占用8字节: 现在只有一个地址,我怎么才能知道要从这个地址开始向后访问多少个字节的存储空间呢,是4个,是1个,还是8个. 所以指针变量需要它所指向的数据类型告诉它要访问多少个字节存储空

随机推荐