目录
结构体
基本语法
定义新结构体
实例化结构体
访问成员变量
直接分量选择 双目操作符 " . "
普通访问
指针访问
间接分量选择 双目操作符 " -> "
结构体初始化
结构体统一初始化
直接初始化
结构体数组的初始化
实例操作
正文
结构体
基本语法
定义新结构体
结构体是我们程序员自己定义的一种数据类型
struct 结构体名 { 类型1 成员变量名1 类型2 成员变量名2 ... };
实例化结构体
struct 结构体名 a; //a就是新类型struct 结构体名的一个实例
不知道大家看到结构体实例化是不是特别眼熟 ,其实“struct 结构体名”与“int”是一个意思,只不过“struct 结构体名”是我们自己定义的类型,而“int”是C语言库中已经定义好的,使用方法都一样,就如同我们使用“int”一样,定义一个4字节32bit的整形数,而我们用我们自己定义的结构体就是,定义一个“struct 结构体名”的变量。
访问成员变量
如上述,我们实例化结构体后,便可以通过一些运算符来访问成员变量了。如下面这个结构体中的成员变量应该如何访问呢
struct date { int y; int m; int d; }; struct student { char name[32]; int num; float score; struct date birthday; };
直接分量选择 双目操作符 " . "
普通访问
组合类型变量.成员变量 ==》去取组合类型变量内部的成员变量
我们现在来访问上面结构体实例化后的成员变量
struct student s; s.name; s.num; s.score; s.birthday; s.birthday.y; s.birthday.m; s.birthday.d;
怎么样,这个还是很简单吧,其中要注意的是,在外面访问的结构体中,还存在结构体,我们要先访问当前结构体中的结构体,再访问具体成员变量。就如我们访问 struct date 中的 y ,我们先访问struct student中的struct date birthday,再访问 struct date 中的 y,代码实现就是 s.birthday.y。
成功访问后,我们就可以对成员变量进行赋值等操作了。
指针访问
(*结构体指针).成员变量
*结构体指针 ==》指向的那个结构体变量
结构体变量.成员变量
有了上面的例子,这个就很简单啦
struct student *p = malloc(sizeof(struct student)); (*p).name; (*p).num; (*p).score; (*p).birthday; (*p).birthday.y; (*p).birthday.m; (*p).birthday.d;
间接分量选择 双目操作符 " -> "
用法:结构体指针->成员变量名
依旧是我们上面定义的结构体,我们要如何访问呢
struct student *p = malloc(sizeof(struct student)); p->name; p->num; p->score; p->birthday; p->birthday.y; p->birthday.m; p->birthday.d;
值得注意的是,再本例中,访问birthday中的成员变量时,因为没有对date进行操作,依旧是用直接分量选择,所以打码实现为:p->birthday.m;。
综上,结构体访问成员变量共有三种方式,按本例来,则是
struct student s; s.成员变量; struct student *p = malloc(sizeof(struct student)); (*p).成员变量; struct student *p = malloc(sizeof(struct student)); p->成员变量;
结构体初始化
结构体统一初始化
就是如何将之后定义的实例都有一个初始值,我们还是按上面的例子来
struct date { int y = 2000; int m = 1; int d = 1; }; struct student { char name[32] = 张三; int num = 20000101; float score = 0; struct date birthday; };
在定义结构体时,给结构体中的成员变量赋值即可。这样之后每个实例化对象都会有这些初始值。
直接初始化
如果我们没有在创建结构体时,就初始化,或者像改变初始化的值,我们就可以直接对结构体实例赋值进行初始化。
按定义时的顺序,依次初始化各成员变量,用逗号分开:
struct student s ={ "张三", 20000101, 0, { 2000,1,1 }, }
当然,我们也可以不安顺序来定义,那我们就要加上成员变量名:
struct student s = { .num = 20000101, .name = "张三", .birthday = { 2000,1,1 }, .score = 0 }
结构体数组的初始化
按顺序初始化
struct student class[3] = { //class[0] { .name = "张三", .num = 20000101, .score = 0, .birthday = {2001,01,01} }, //class[1] { .name = "李四", .num = 20000102, .score = 0, .birthday = {2001,01,02} }, //class[2] { .name = "王五", .num = 20000103, .score = 0, .birthday = {2001,01,03} } };
同样的,我们也可以不按顺序初始化 ,医用数组下标来实现,不过这种方式,不同编译器下,情况或者限制不一样
struct student class[3] = { [1] = { .name = "张三", .num = 20000101, .score = 0, .birthday = {2001,01,01} }, [0] = { .name = "李四", .num = 20000102, .score = 0, .birthday = {2001,01,02} }, [2] = { .name = "王五", .num = 20000103, .score = 0, .birthday = {2001,01,03} } };
实例操作
有了以上的知识储备,我们就来练一练手吧
首先定义一个结构体来描述一个学生的情况(姓名、学号、成绩,出生年、月、日),再定义一个结构体数组来描述我们这个班的同学(3个),并从键盘上输入每一个学生的信息,并输出到终端上。
代码实现:
#include<stdio.h> struct date { int y; int m; int d; }; struct student { char name[32]; int num; float score; struct date birthday; }; int main() { struct student CS[3]; for(int i = 0;i < sizeof(CS) / sizeof(struct student);i++) { scanf("%d%d%d%s%d%f",&CS[i].birthday.y,&CS[i].birthday.m,&CS[i].birthday.d,CS[i].name,&CS[i].num,&CS[i].score); } for(int i = 0;i < sizeof(CS) / sizeof(struct student);i++) { printf("%d %d\t%d\t%s\t%d\t%f\n",CS[i].birthday.y,CS[i].birthday.m,CS[i].birthday.d,CS[i].name,CS[i].num,CS[i].score); } return 0; }