联合能在同一存储空间存储不同类型的数据(和struct不同不是同时存储)。
一次只能存储一种类型的值。他的主要目的是节省空间。
形式同struct相同:但是含义不同.
struct表示这个结构体可以存储一个int,一个double和一个char
但是union表示他只能存储一个int,或者一个double或者一个char
struct hold1{
int digit;
double bigfl;
char letter;
};
union hold{
int digit;
double bigfl;
char letter;
};
union hold fit; //定义一个fit变量
union hold save[10]; //顶一个save数组
union hold *pu; //指针
union hold{
int digit;
double bigfl;
char letter;
};
union hold a = {88}; //初始化,digit赋值
union hold b = {.bigfl = 118.2}; //指定初始化
//声明一个,并赋值
union hold orig;
orig.letter = '4';
//可以用另一个联合来给一个联合初始化
union hold c = orig;
union hold fit;
fit.digit = 23; //23存储在联合中,此时联合占4字节
fit.bigfl = 2.0; //清除digit,并把2.0存储在bigfl中,占8字节
fit.letter = 'h'; //清除bigfl,并把h存储在letter中,此时占1字节
union一次只能存储一个值,即使有足够空间,也不能同时存储两个类型的值,所以在使用的时候要注意当前在union中存储的是哪个值。
union hold{
int digit;
double bigfl;
char letter;
};
int main(void)
{
union hold a;
a.digit = 899;
printf("%d, %f, %c \n", a.digit, a.bigfl, a.letter); //899, 0.000000, �
a.bigfl = 445.56;
printf("%d, %f, %c \n", a.digit, a.bigfl, a.letter); //-1030792151, 445.560000, )
double dng = a.bigfl*4.5;
printf("%f", dng);
return 0;
}
上面这个例子我们可以看到,当我们给a.bigfl赋值的时候,a.digit的值被修改了,所以如果这时我们还要使用a.digit就不是我们想要的值了。
struct owner {
char c[12];
};
struct outer {
char cc[78];
};
struct car_user {
char rt[34];
int status;
union {
struct owner owncar; //匿名联合中的变量
struct outer ocar;
};
};
struct car_user flit;
flit.owncar.c;
flit.ocar.cc;
这时我们可以看到struct car_user中使用了一个匿名联合,我们可以这样使用他。
枚举类型目的是提高程序可读性。
使用enum关键字来表示整型常量。使整数看起来更直观。
enum spectrum {
red, orange, yellow, green, blue, violet
};
enum spcturm color;
color = blue;
color = 4;
int c = blue;
上面这个示例中,声明创建了一个名为spctrum的枚举。其中red,orange这些叫做枚举符。他们都是int类型。
然后我们定义一个变量,color,他的值可以是red, orange, yellow.
默认情况下枚举列表中的值从0开始被赋值,上面分别被赋值0~5.
还可以给枚举常量赋值
enum feline {
cat, //0
lynx = 10,//10
puma, // 11
tiger //12
};
因为color就是整型,我们可以把他放到for循环中使用。
enum spectrum {red, orange, yellow, green, blue, violet};
int main(void)
{
char choice[LEN];
enum spectrum color;
for (color = red; color <= violet; color++)
{
}
typedef用于为某一类型自定义名称。
他与#define类似,但是有以下不同:
typedef unsigned char BYTE; //把unsigned char 重新自定义名称为BYTE
BYTE x; //声明一个char变量,此句同 unsigned char x;
也可以使用#define来定义
比如使用
#define BYTE unsinged char
他和上面typedef一样。
#define INTERGE int
unsigned INTERGE n; //没问题
typedef int INTERGE;
unsigned INTERGE n; //错误,不能在 INTERGE 前面添加 unsigned
typedef char * STRING
#define char * STRING2
STRING name, sign; //相当于char *name, char *sign;
STRING2 name, sign; //相当于char *name, sign.
看上面对比,发现这样声明则#define在某些情况下起不到我们预期的作用。
http://m.biancheng.net/view/2040.html
typedef char ARRAY20[20];
//下面两个声明相同
ARRAY20 a1, a2, s1, s2;
char a1[20], a2[20], s1[20], s2[20];
这里表示ARRAY20是char[20]的别名,表示一个char类型大小为20的数组。
typedef int (*PTR_TO_ARR)[4];
PTR_TO_ARR p1, p2;
表示 PTR_TO_ARR 是类型int * [4]的别名,它是一个二维数组指针类型.
typedef struct complex {
float real;
float imag;
} COMPLEX;
COMPLEX a; //定义变量a,等同于 stuct complex a;
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
} lib;
这里和结构体就不同类,结构体的下面lib是创建一个变量,而这里的COMPLEX是一个类型别名,并未创建变量。
可以看到使用COMPLEX可以方便的创建一个struct complex类型。