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;
};