九、结构体 Structure
类型定义¶
类型定义是使用typedef关键字将一种数据类型定义为一种新类型的过程。
注意以下两点:
- 类型定义是为已有的类型定义了一个别名,习惯上用大写表示。如:
typedef int INT; typedef float REAL; - 程序中有了类型定义后,就可以使用新的类型名来定义变量。如:
typedef int INT; // 这两个语句都表示x,y均为整型变量。 int x; INT y;
结构类型¶
结构的声明¶
在使用结构体之前,要使用语句的形式对结构的成员情况进行说明,称为结构的声明。结构声明形式如下:
struct 结构名
{
类型 结构成员名1;
类型 结构成员名2;
...
类型 结构成员名n;
};
其中struct为关键字。{ }中包括的是组成该结构的成员列表。举例:
struct date
{
int year;
int month;
int day;
};
int main() {
...
}
- 结构类型声明是一条语句,末尾必须以分号结束。
- 结构名可以省略,此时定义的结构称为无名结构。如上面的结构也可以声明为:
struct { int year; int month; int day; }; - struct与结构体一起,称作结构类型名。无名结构是没有结构类型名的。
- 无论是有名结构还是无名结构,都可以在声明是,把它定义为另一种类型。
typedef struct date // 这是有名结构
{
int year;
int month;
int day;
}DATE;
typedef struct
{
int year;
int month;
int day;
}DATE; // 这是无名结构
定义结构变量¶
先声明类型后定义变量¶
若结构已经声明,并且结构名没有省略,则可以在需要时使用结构类型名来定义变量。例:
struct date
{
int year;
int month;
int day;
}; //声明了名字为date的结构
struct date myBirthday; //定义struct date 型的变量myBirthday
声明结构的同时定义变量¶
可以在声明时同时定义变量。如:
struct date
{
int year;
int month;
int day;
}d1,d2,d3;
struct
{
int year;
int month;
int day;
}d1,d2,d3;
使用typedef定义的类型名来定义变量¶
若使用了typedef为结构类型定义了新类型名,那么就可以使用这个新类型名定义结构变量。如:
typedef struct date DATE;
DATE myBirthday;
// 伪代码
typedef struct 结构体
{
...
}类型名;
类型名 变量名列表;
结构指针¶
定义结构指针的方法与定义标准类型指针的方法完全一样
typedef struct
{
int x;
int y;
float t;
char u;
}SAMPLE;
SAMPLE sam1;
SAMPLE *ptr=&sam1;
定义结构指针的方法与定义标准类型指针的方法完全一样,只要把数据类型换为结构类型即可。若把一个结构变量的地址赋给一个结构指针,指针就指向了该变量。与对标准类型操作一样,只要对指针取间接运算 *
就可以访问它所指向的变量,也就是 *ptr和sam1两者是等价的。
结构的处理¶
结构变量的初始化¶
对结构变量初始化的方法与对数组初始化的方法类似,格式是:结构类型 变量名={值列表};
typedef struct
{
int x;
float t;
char u;
}SAMPLE;
SAMPLE sam1={2,1.5,'A'};
SAMPLE sam2={1,5.5,'B'};
sam1=sam2;
访问结构成员¶
通过结构变量访问结构成员¶
格式: 结构变量名.成员名
列题1:结构变量的定义、初始化和成员访问¶
#include<stdio.h>
typedef struct
{
int x;
float y;
char c;
}SAMPLE;
int main()
{
SAMPLE sam={-1,1.5,'A'};
printf("%d,%lf,%c\n",sam.x,sam.y,sam.c);
sam.c='?';
printf("%d,%lf,%c\n",sam.x,sam.y,sam.c);
return 0;
}
// 输出
-1,1.500000,A
-1,1.500000,?
2.通过结构指针访问结构成员¶
格式: 结构变量名->成员名
例题2:使用结构指针访问成员¶
#include<stdio.h>
typedef struct
{
int x;
float y;
char c;
}SAMPLE;
int main()
{
SAMPLE sam={-1,1.5,'A'};
SAMPLE *p=&sam;
printf("%d,%lf,%c\n",(*p).x,(*p).y,(*p).c);//(*p)与sam是一样的
sam.c='?';
printf("%d,%lf,%c\n",p->x,p->y,p->c);
return 0;
}
// 输出
-1,1.500000,A
-1,1.500000,?
复杂结构¶
嵌套结构¶
声明嵌套结构¶
可以使用两种方法声明嵌套结构:分别声明和整体声明。在实际编程中建议大家使用分别声明的方法,因为这样的格式更容易读。
分别声明:
typedef struct
{
int month;
int day;
int year;
}DATE;
typedef struct
{
int hour;
int min;
int sec;
}TIME;
typedef struct
{
DATE date;
TIME time;
}STAMP;
typedef struct
{
STAMP startTime;
STAMP endTime;
}JOB;
整体声明:
typedef struct
{
struct
{
int month;
int day;
int year;
}date;
struct
{
int hour;
int min;
int sec;
}time;
}STAMP;
typedef struct
{
STAMP startTime;
STAMP endTime;
}JOB;
嵌套结构成员初始化¶
在对嵌套结构进行初始化时,要把每一层上的数据值使用一对{ }括起来。如:
STAMP myStamp={{11,18,1968},{22,45,00}};
JOB myJob={{{01,01,2000},{00,00,00}},{{12,18,2007},{00,00,00}}};
嵌套结构成员的访问¶
访问嵌套结构中的成员,必须从最外层开始由外向里包含每一层,直到包含了要访问的成员为止。格式是:
结构变量名.外层成员名. ... .内层成员名
若stamp、job分别是STMP、JOB类型的变量,则下列的访问格式都是正确的
stamp.date;
stamp.date.month;
job.starttime.time.hour;
#include<stdio.h>
typedef struct
{
int x;
float y;
char c;
}DATA;
typedef struct
{
DATA d1;
DATA d2;
}NODE;
int main()
{
NODE node={{1,2.5,'A'},{10,25.5,'B'}};
NODE *p=&node;
printf("%d,%lf,%c\n",(*p).d1.x,(*p).d1.y,(*p).d1.c);//(*p)与node是一样的
printf("%d,%lf,%c\n",node.d2.x,node.d2.y,node.d2.c);
printf("%d,%lf,%c\n",p->d1.x,p->d1.y,p->d1.c);
return 0;
}
// 输出
1,2.500000,A
10,25.500000,B
1,2.500000,A
含数组的结构¶
输入和输出学生信息:
#include<stdio.h>
typedef struct
{
char name[20];
char sex;
int midterm[3];
int final;
}STUDENT;
int main()
{
STUDENT stu;
int i;
printf("输入姓名:");
gets(stu.name);
printf("输入性别:");
scanf("%c",&stu.sex);
for(i=0;i<3;i++)
{
printf("输入midterm[%d]:",i);
scanf("%d",&stu.midterm[i]);
}
printf("输入final:");
scanf("%d",&stu.final);
printf("%s , %c ,",stu.name,stu.sex);
for(i=0;i<3;i++)
{
printf("%d,",stu.midterm[i]);
}
printf("%d\n",stu.final);
return 0;
}
//控制台输出
输入姓名:limeida
输入性别:M
输入midterm[0]: 87
输入midterm[0]: 76
输入midterm[0]: 65
输入final: 96
limeida , M ,87,76,65,96
至此,第九章完结