C语言关键字之union
是什么呢
union 在C语言中可以被称为联合体,也有将其称为共用体。它是一种自定义类型,可以使用它来创建变量。
使用格式
union 联合体名称 {
变量 1;
变量 2;
…
变量 n;
};
如何理解
开辟空间大小是 变量列表中最大的变量所占的空间,足以容纳你变量列表中最大的那个值。
例1:
struct demo {int num1;int num2;};
首先,先看不使用union的这段代码所开辟的空间是两个 int 的大小,可存储 num1 和 num2,如下图
union struct demo {int num1;int num2;};
再来看,使用union的这段代码所开辟的空间是一个 int 的大小,要么存储 num1 要么存储 num2,如下图
例2:
struct demo {int num1;long num2;};
首先,先看不使用union的这段代码所开辟的空间是一个 int + 一个 long 的大小,如下图
union struct demo {int num1;int num2;};
再来看,使用union的这段代码所开辟的空间是 num1 和 num2 中占内存最大的一个 也就是一个 long 的大小,如下图
使用场景
例如,在 Linux 内核中的这段代码
union task_union {struct task_struct task;char stack[PAGE_SIZE];};
这段代码使用 union 定义了 task_union,相当于在内存中开辟了 两个变量列表中最大的空间。stack 占用的空间大小是 一页的空间,也就是 4kb 的大小,而 task 的大小肯定是小于 4kb 的,所以这个 task_union 肯定是仅开辟了 4kb 的空间,换句话说就是巧用了 union 在占中存储了 task 。
上面例子的两个补充代码:
PAGE_SIZE的宏定义如下:
#define PAGE_SIZE 4096
task_struct 的结构体如下:
struct task_struct {/* these are hardcoded - don't touch */long state;/* -1 unrunnable, 0 runnable, >0 stopped */long counter;long priority;long signal;struct sigaction sigaction[32];long blocked;/* bitmap of masked signals *//* various fields */int exit_code;unsigned long start_code,end_code,end_data,brk,start_stack;long pid,father,pgrp,session,leader;unsigned short uid,euid,suid;unsigned short gid,egid,sgid;long alarm;long utime,stime,cutime,cstime,start_time;unsigned short used_math;/* file system info */int tty;/* -1 if no tty, so it must be signed */unsigned short umask;struct m_inode * pwd;struct m_inode * root;struct m_inode * executable;unsigned long close_on_exec;struct file * filp[NR_OPEN];/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */struct desc_struct ldt[3];/* tss for this task */struct tss_struct tss;};