第14章-结构和其他数据形式
1.建立结构声明
//申明一个结构体
struct book
{
char title[MAXTITL];//一个字符串表示的titile 题目 ;
char author[MAXAUTL];//一个字符串表示的author作者 ;
float value;//一个浮点型表示的value价格;
};//注意分号不能少,这也相当于一条语句;
- 这个声明描述了一个由两个字符数组和一个float变量组成的结构体,但是注意,他并没有创建一个实际的数据对象,而是描述了一个组成这类对象的元素。
- 下面介绍一下上面的结构体声明;
1,首先使用关键字struct,他表示接下来是一个结构体。
2;后面是一个可选的标志(book),它是用来引用该结构体的快速标记。因此我们以后就会可以这样创建数据对象
2.定义结构变量
- 结构有两层含义。一层含义是“结构布局”,结构布局告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。下一步是创建一个结构变量,即是结构的另一层含义。程序中创建结构变量的一行是:
struct book library;
- 组合后的结构声明和结构变量定义不需要使用结构标记:
struct { /* 无结构标记 */
char title[MAXTITL];
char author[MAXAUTL];
float value;
} library;
3.初始化结构
struct book s1={//对结构体初始化
"yuwen",//title为字符串
"guojiajiaoyun",//author为字符数组
22.5 //value为flaot型
};
//要对应起来,用逗号分隔开来,与数组初始化一样;
- 关于结构体变量的初始化与初始化数组类似;
也是使用花括号括起来,用逗号分隔的初始化好项目列表,注意每个初始化项目必须要和要初始化的结构体成员类型想匹配。
4.访问结构成员
- 使用结构成员运算符——点(.)访问结构中的成员。例如,library.value即访问library的value部分。可以像使用任何float类型变量那样使用library.value。
- 注意,点其结合性是自左至右的,它在所有的运算符中优先级是最高的;
例如,s1.title指的就是s1的title部分,s1.author指的就是s1的author部分,s1.value指的就是s1的value部分。然后就可以像字符数组那样使用s1.title,象使用float数据类型一样使用s1.value;
注意,s1;虽然是个结构体,但是s1.value却是float型的,因此s1.value就相当于float类型的变量名一样,按照float类型来使用;
例如;printf(“%s\n%s\n%f”,s1.title,s1.author,s1.value);//访问结构体变量元素
注意scanf(“%d”,&s1.value); 这语句存在两个运算符,&和结构成员运算符点,按照道理我们应该将(s1。value括起来,因为他们是整体,表示s1的value部分)但是我们不括起来也是一样的,因为点的优先级要高于&。
5.结构初始化器
- 只初始化book结构的value成员,可以这样做:
struct book surprise = { .value = 10.99};
- 可以按照任意顺序使用指定初始化器:
struct book gift = {
.value = 25.99,
.author = "James Broadfool",
.title = "Rue for the Toad"
};
- 与数组类似,在指定初始化器后面的普通初始化器,为指定成员后面的成员提供初始值。另外,对特定成员的最后一次赋值才是它实际获得的值。
struct book gift= {
.value = 18.90,
.author = "Philionna Pestle",
0.25
};
- 赋给value的值是0.25,因为它在结构声明中紧跟在author成员之后。新值0.25取代了之前的18.9。
6.结构数组
#include<stdio.h>
#include<string.h>
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
};
int main()
{
int i;
struct student stu[3]={{10101,"LiuHu",'F',18,99.7,"beijing road"},{10102,"NaoDan",'M',17,99.8,"shanghai road"},{10103,"MaHuangTeng",'F',48,99.9,"shenzhen road"}};
for(i=0;i<3;i++)
{
printf("%d %s %c %d %1f %s\n",stu[i].num,stu[i].name,stu[i].sex,stu[i].age,stu[i].score,stu[i].addr);
}
return 0;
7.声明结构数组
struct book library[MAXBKS];
8.标识结构数组成员
- 总结一下:
library // 一个book 结构的数组
library[2] // 一个数组元素,该元素是book结构
library[2].title // 一个char数组(library[2]的title成员)
library[2].title[4] // 数组中library[2]元素的title 成员的一个字
9.嵌套结构
struct names { // 第1个结构
char first[LEN];
char last[LEN];
};
struct guy { // 第2个结构
struct names handle; // 嵌套结构
char favfood[LEN];
char job[LEN];
float income;
};
10.声明和初始化结构指针
struct guy {
struct names handle;
char favfood[LEN];
char job[LEN];
float income;
};
- 规则就是,struct 结构体名+ * + 指针名;
struct guy * him;
- 这个声明不是建立一个新的结构体,而是创建了一个指针类型的him指针变量,他可以指向任何现有的book类型的结构体;
- him = &library[0];
如果barney是一个guy类型的结构,可以这样写:
him = &barney;
fellow 是一个结构数组,这意味着 fellow[0]是一个结构。所以,要让 him 指向fellow[0],可以这样写:
him = &fellow[0];
11.用指针访问成员
- 第1种方法也是最常用的方法:使用->运算符。该运算符由一个连接号(-)后跟一个大于号(>)组成。我们有下面的关系:
如果him == &barney,那么him->income 即是 barney.income
如果him == &fellow[0],那么him->income 即是 fellow[0].income
- 第2种方法是,以这样的顺序指定结构成员的值:如果him == &fellow[0],那么him == fellow[0],因为&和是一对互逆运算符。因此,可以做以下替代:
fellow[0].income == (*him).income
- 必须要使用圆括号,因为.运算符比*运算符的优先级高。
总之,如果him是指向guy类型结构barney的指针,下面的关系恒成立:
barney.income == (*him).income == him->income // 假设 him == &barney
12.传递结构成员,地址和结构
/* 把结构成员作为参数传递 */
#include <stdio.h>
#define FUNDLEN 50
struct funds {
char bank[FUNDLEN];
double bankfund;
char save[FUNDLEN];
double savefund;
};
double sum(double, double);
int main(void) {
struct funds stan = {
"Garlic-Melon Bank",
4032.27,
"Lucky's Savings and Loan",
8543.94
};
printf("Stan has a total of $%.2f.\n", sum(stan.bankfund, stan.savefund));
return 0;
}
/* 两个double类型的数相加 */
double sum(double x, double y) {
return (x + y);
}
13.枚举类型
- 可以用枚举类型(enumerated type) 声明符号名称来表示整型常量。使用enum关键字,可以创建一个新“类型”并指定它可具有的值(实际上,enum常量是int类型,因此,只要能使用int类型的地方就可以使用枚举类型)。枚举类型的目的是提高程序的可读性。它的语法与结构的语法相同。例如,可以这样声明:
enum spectrum {red, orange, yellow, green, blue, violet};
enum spectrum color;
- 第1个声明创建了spetrum作为标记名,允许把enum spetrum作为一个类型名使用。第2个声明使color作为该类型的变量。第1个声明中花括号内的标识符枚举了spectrum变量可能有的值。因此,color 可能的值是 red、orange、 yellow 等。这些符号常量被称为枚举符(enumerator)。然后,便可这样用:
int c;
color = blue;
if (color == yellow)
...;
for (color = red; color <= violet; color++)
...;
14.默认值
- 默认情况下, 枚举列表中的常量都被赋予0、 1、 2等。 因
此, 下面的声明中nina的值是3:
enum kids {nippy, slats, skippy, nina, liz};
15.赋值
- 在枚举声明中, 可以为枚举常量指定整数值:
enum levels {low = 100, medium = 500, high = 2000};
- 如果只给一个枚举常量赋值, 没有对后面的枚举常量赋值, 那么后面的常量会被赋予后续的值。 例如, 假设有如下的声明:
enum feline {cat, lynx = 10, puma, tiger};
- 那么, cat的值是0(默认) , lynx、 puma和tiger的值分别是10、 11、12。