定义一个结构体类型的一般形式:
struct 结构体类型名
{
成员表
};
右花括号后的分号是必不可少的,它表示声明结束。
定义一个结构体类型时,对每个成员都应该进行类型声明,即:
数据类型 成员名;
每一个成员也称为结构体中的域(field)。成员表又称为域表。
每个结构代表一种新的作用域。
任何声明在此作用域内的名字都不会和程序中的其他名字冲突。
结构的成员在内存中是按照声明的顺序存储的。
先声明结构体类型,再声明结构体类型变量。
例:
struct Student //Student为结构体类型
{
int score;
char name[10];
};
struct Student stu1,stu2; //stu1和stu2为结构体变量
在声明结构类型的同时声明结构变量。
例:
struct Student //Student为结构体类型
{
int score;
char name[10];
}stu1,stu2; //stu1和stu2为结构体变量
结构变量在声明的同时进行初始化。
为了对结构进行初始化,要把待存储到结构中的值的列表准备好并用花括号把它括起来:
struct student my_stu = {100,"C++"};
初始化式中的值必须按照结构成员的顺序一一对应。
初始化式中没有涉及的成员都设为0。
C99允许指定成员初始化,但在初始化时需要对每个元素名赋值:
struct student my_stu =
{
.score = 100,
.name = "C++"
};
将点号和成员名称的组合称为指示符。
初始化式中的值的顺序不需要与结构中成员的顺序一致。
可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。
例如:student1 = student2;
为了访问结构内的成员,首先写出结构的名字,然后写一个句点,再写出成员的名字。
student1.score = 100;
student1.name = "C++";
结构的成员是左值,所以它们可以出现在赋值运算的左侧。
句点运算符的优先级几乎高于所有其他运算符。
给函数传递结构和从函数返回结构都要求生成结构中所有成员的副本。
可以用指向结构的指针作为参数或者作为返回值的函数。
C99使用复合字面量创建一个没有名字结构。
例:
(struct student){100,"C++"};
把复合字面量赋给变量:
stu = (struct student){100,"C++"};
每个数组元素都是一个结构体类型的数据,它们都分别包括各个成员项。
结构体数组的初始化:
struct student stu[3] =
{
{100,"C++1"},
{10,"C++2"},
{80,"C++3"}
};
一个指向结构体变量的指针简称结构体指针。
struct student stu1 = {100,"C++"}; //结构体变量
struct student *p = &stu1; //指向结构体的指针
通过指向结构体指针访问结构体变量的成员:
p->score; //访问 stu1 的 score 成员
“->
”称为指向运算符。
以下三种形式等价:
结构体变量名.成员名
P->成员名
(*p).成员名
联合(union)也是由一个或多个成员构成的,而且这些成员可能具有不同的类型。
但是,编译器只为联合中最大的成员分配足够的内存空间。
联合的成员在这个空间内彼此覆盖。
这样的结果是,给一个成员赋予新值也会改变其他成员的值。
声明一个联合变量:
union{
int i;
double d;
}u;
事实上,结构变量和联合变量只有一处不同:结构变量的成员存储在不同的内存地址中,而联合变量的成员存储在同一内存地址中。
访问联合成员的方法和访问结构成员的方法相同。
联合的初始化方式和结构的初始化很类似。但是,只有联合的第一个成员可以获得初始值。
union{
int i;
double d;
}u = {0};
花括号是必需的,花括号内的表达式必须是常量。
C99允许指定成员初始化:
union{
int i;
double d;
}u = {.d = 10.0};
只能初始化一个成员,但不一定是第一个。
定义枚举类型的一般形式:
enum 枚举类型名 {枚举常量表};
枚举常量的名字必须不同于作用域范围内声明的其他标识符。
例:
enum suit {CLUBS, DIAMONDS,HEARTS,SPADES};
默认情况下,编译器会把整数 0,1,2,3······赋给特定枚举中的常量。
例如,在枚举 suit 的例子中,CLUBS、DIAMONDS、HEARTS 和 SPADES 分别表示0、1、2 和 3。
可以为枚举常量自由选择不同的值:
enum suit {CLUBS = 1, DIAMONDS = 3,HEARTS = 4,SPADES = 9};
当没有为枚举常量指定值时,它的值比前一个常量的值大1。
声明枚举变量:
enum suit s1,s2;
枚举变量接受一个枚举常量值:
s1 = DIAMONDS;
在系统内部,C语言会把枚举变量和常量作为整数来处理。
可以用 typedef 声明一个新的类型名代替已有的类型名。
typedef int INTERGER; //使用标识符INTERGER代表int类型
typedef float REAL; //使用标识符REAL代表float类型
typedef struct
{
int month;
int day;
int year;
}DATE; //DATA是新类型名,而不是结构体变量名
typedef int NUM[10]; //声明NUM为整形数组,包括10个元素
typedef char* STRING; //声明STRING为指向字符型的指针