C语言关键字浅析-struct

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Johan_Joe_King/article/details/84247616

### C语言关键字浅析系列 ###

### ISO/ANSI C 关键字 ###

struct原型是指structure,意为结构变量(structure variable),这是C语言中很重要的一个概念

一个自定义的结构中能包含多种数据类型,并可以将这些数据类型看做一组数据来操作,很多情况下能带来很大的便利

struct的作用是:

声明结构和定义结构变量。

1、为什么需要结构(structure)?

试考虑这样的情况:现在需要用C程序来处理环境传感器回传的数据,数据内容包含经度、纬度、海拔、温度、湿度、运行状态和编号,

环境传感器不止一个,所以该程序需要能处理很多组数据。

如果你精通C语言的数组的知识,你可以这样做,且完全没问题:

const int MAX_SIZE = 100;    /* 数组最大长度,即系统能处理的传感器的数量上限 */
float longitude[MAX_SIZE];   /* 经度,把需要操作的数据都按数组存放 */
float latitude[MAX_SIZE];    /* 纬度 */
float altitude[MAX_SIZE];    /* 海拔 */
double temp[MAX_SIZE];       /* 温度 */
double humi[MAX_SIZE];       /* 湿度 */
char status[MAX_SIZE];       /* 运行状态 */
int id[MAX_SIZE];            /* 设备编号 */

/* 这是个数据处理的函数 */
void fun(int i, float lot[], float lat, float alt[], double temp[], double humi[], char sta[], int id[])
{
	save(lot[i]);    /* 所有的参数都要根据参数中的下标i这样写 */
}

如果涉及的信息种类少,这样的编程方式可能还能勉强看懂,但现实生活中一个事物上产生和需要处理的数据信息的种类,是很多很多的

而且上述的用数组来表示一组一组的信息的方式不便于维护,特别是万一角标i的值上出了一点问题,则会为所有数据组带来毁灭性的后果

结构的思想是:把一组信息看成一个整体对待,这个数据整体叫做一个结构,其可以包含若干不同数据类型的项目。

2、结构的格式

结构使用struct关键字进行声明和定义,格式一般是struct{项目;};,比如解决上述问题的代码使用结构的话就可以简化为:

struct sensor   /* 传感器,此处是结构的声明 */
{
	float longitude;   /* 经度,这是结构的一个项目 */
	float latitude;    /* 纬度 */
	float altitude;    /* 海拔 */
	double temp;       /* 温度 */
	double humi;       /* 湿度 */
	char status;       /* 运行状态 */
	int id;            /* 设备编号 */
};   /* 一定要注意写上末尾的分号 */

这样我们就声明了一个结构,结构名称是sensor,你可以认为这是你自定义的一个数据类型,接下来就可以定义相应的结构变量了:

const int MAX_SIZE = 100;
struct sensor s;              /* 定义一个结构变量 */
struct sensor ss[MAX_SIZE];   /* 定义结构变量数组,此时每个结构变量元素的存储是连续的,而结构变量内部项目的存储也是连续的 */

有时我们还能见到这种声明加定义的写法:

struct player  /* 球员 */
{
	int age;     /* 年龄 */
	char* part;  /* 位置 */
	int grade;   /* 评分 */
}Messi;   /* 定义了一个结构变量 */

/* 上述这种前面声明后面定义的写法,简写起来就是下面这个样子 */
struct player Messi;   /* 计算机会把声明部分添上的 */

/* 有了那种前面声明后面定义的写法后,有时候甚至懒得去想自己创造的这个数据类型叫什么,好用就行 */
struct{
	int age;     /* 年龄 */
	char* part;  /* 位置 */
	int grade;   /* 评分 */
}Barca[11];

3、结构的项目

之所以有结构的概念无非是想更方便地操作数据,那么结构内的项目怎么访问呢?

我们需要一个结构成员运算符(.),就是英文中的句号,一个点,在C语言中等高级语言中,点常被认为是“之、的”的意思

所以这样我们就能一眼就看懂访问的数据的所属了,如果一个程序有很多组信息,使用数组的方法可读性就很低了:

/*************** 程序1,用数组 ***************/
int age[10];
char sex[10];
float temp[10];
float humi[10];

void fun()
{
	age[3] = 1;
	temp[1] = 14.3;
	/* 数据访问看上去很混乱,如果数据类型很复杂,不容易看出在对哪种信息进行处理 */
}

/*************** 程序2,用结构 ***************/
struct person   /* 人员 */
{
	int age;
	char sex;
}PERSON[10];
struct sensor   /* 传感器 */
{
	float temp;
	float humi;
}SENSOR[10];

void fun()
{
	PERSON[1].age = 1;
	SENSOR[3].humi = 45;
	/* 分类很规矩的编程风格,简练又易读,内容引起舒适 */
}

C语言中的基本数据类型在定义的时候基本都能初始化,自定义的结构变量在定义的时候也可以初始化,

如果你对数组在定义的时候的初始化格式有所了解,你对结构变量的初始化应该就会倍感亲切:

struct person
{
	int age;       /* 年龄 */
	char sex;      /* 性别 */
	float height;  /* 身高 */
	char* name;    /* 姓名 */
};

/* 已知结构项目时,可以按项目声明顺序挨个初始化 */
struct person P1 = {18, 'm', 160, "Johan Joe King"};

/*
	这时也许你会考虑出现缺省的情况怎么办,其实有那种写法,但与其说是缺省,
	不如说是指定其他的某几个值来初始化,下面这种指定初始化项目的语法,是
	C99以后开始支持的
*/
struct person P2 = {.age = 18, .name = "Johan Joe King"};

结构也可以用指针来操作,这在很多堆栈、链表实现的时候很常见,不过这时对项目的访问的形式有所不同:

struct node  /* 带next指针的结点 */
{
	int value;
	node *next;   /* 这是个node类型的指针 */
};

void fun()
{
	node *p = new node;   /* 创建node类型指针p,并为p分配空间,等同于创建了结构变量,地址为p */
	p->value = 100;       /* 与使用结构变量名访问项目的运算符不同,在指针这里要用->运算符访问项目,效果是一样的 */
	p->next = NULL;       /* NULL是空,注意结构变量和结构指针的访问项目的运算符的差异,一定不能混淆 */
}

4、结构的嵌套

结构也能嵌套,可以很通俗的讲解这个道理,比如用一个结构表示战机的信息,战机包括发动机、侧翼、尾翼等数据,而这些项目本身又包含很多自己的信息:

struct flanking   /* 侧翼数据 */
{
	char* number;
	double weight;
	double length;
};

struct tail   /* 尾翼数据 */
{
	char* number;
	double height;
	double area;
};

struct engine   /* 发动机数据 */
{
	char* type;
	float power;
};

/* 需要注意的是,一个结构的项目如果包含其他结构类型,包含的结构必须在该结构之前声明 */
struct fight
{
	char* number;
	flanking FLK;
	tail TL;
	engine EG;
}J20;

——参考《C Primer Plus第五版》

相关文章:

C语言关键字浅析-enum

C语言关键字浅析-union

C语言关键字浅析-typedef

猜你喜欢

转载自blog.csdn.net/Johan_Joe_King/article/details/84247616