### 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语言关键字浅析-union
C语言关键字浅析-typedef