2020-12-20 第14章-结构和其他数据形式

第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。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值