结构体知识点

问题引入:管理学生信息(学生信息管理系统)。

假设每个学生,学校关心如下内容:

学号 char StuId[9];             // 西邮学号8位,再加一个0结束标志,故而设定为9位

姓名 char StuName[21];     // 一个汉字两个字节,此处假设最多十个汉字,再加一个0结束标志,故而设定为21位

性别 int StuSex;       

年龄 int StuAge;                // 一般设定为出生年月日,这样不用每年进行管理

成绩 int Score;                  // 成绩本可能出现小数,但是此处为了练习用整型表示,不到万不得已不用float和double,运算太慢了

假设有50名学生的相关信息需要管理……

char StuId[50][9];

char StuName[50][21];

int StuSex[50];

int StuAge[50];

int Score[50];

若使用上述多个数组形式处理相关任务,则,应保证同一名学生5个方面的信息数据,保存在下标相同的数组元素中,以保证逻辑上的一致性。但是,在“排序”等事务要求下,需要用多次交换来保证逻辑一致性,这使得上述方法太可怕了!

另外:上述方法并没有在逻辑层面保持与人文信息的一致性。

为了简化上述问题的解决,也为了能使C语言更符合人类思维习惯,提出结构体的概念。

补充:二维数组

int a[3][4] <=> int [4] a[3]   理解为:a数组有3个元素,每个元素是一维数组,即 int [4] 类型

上述语句定义了一个3行4列的二维数组。

二维数组m共有12个元素,每个元素都是int类型的。

这12个元素的下标分别是:

a[0][0]、a[0][1]、a[0][2]、a[0][3]、

a[1][0]、a[1][1]、a[1][2]、a[1][3]、

a[2][0]、a[2][1]、a[2][2]、a[2][3]、

char StuName[50][21] => char[21] StuName[50]

一、结构体的基本操作

1.结构体的声明

struct  STUDENT_INFORMATION

{

char StuId[9];

char StuName[21];

int StuSex;

int StuAge;

int Score;

};

结构体的声明,实质上是定义了一个新的数据类型

2.结构体的使用方法

(1)

struct STUDENT_INFORMATION  a;

int  b;

上述两条语句都是变量定义语句;

其中,a和b地位相同,都是变量名称;

int和struct STUDENT_INFORMATION地位相同,都是数据类型

 

(2)

strcut STUDENT_INFORMATION  a, b[50], *p;

通常将结构体类型的变量称为:(结构体)实例;

b是一个拥有50个struct STUDENT_INFORMATION实例元素的数组,b[0]到b[49]就是独立的50个类似a的结构体实例;

p是一个能够指向struct STUDENT_INFORMATION实例的指针变量,其指类就是struct STUDENT_INFORMATION。

 

(3)

结构体的使用有2个基本步骤:

1)声明结构体数据类型;

2)用结构体类型作为数据类型,定义新的实例(数组、指针)。

在上述两步之后,通过对实例的成员的引用,实现对实例的引用。

3.访问结构体的成员

struct  STUDENT_INFORMATION

{

char StuId[9];

char StuName[21];

int StuSex;

int StuAge;

int Score;

};

 

(1)

strcut STUDENT_INFORMATION  a, b[50], *p;

 //要求:对a实例进行赋值      张三,男,19岁,03151038,61    注:男为1,女为0

正确写法:

strcpy(a.StuName, “张三”);                                 strcpy("a.StuName", “张三”);   (错误)

strcpy(a.StuId, “03151038”);

a.StuSex = 1;

a.StuAge = 19;

a.Score = 61;

 

注意:

a.StuName = 张三;

a.StuName = “张三”;

a.StuName[21] = “张三”;

a.StuName[0] = “张三”;

a.StuName = {“张三”};

上述5种写法都是错误的!原因:StuName是常量!数组名称的本质是首地址常量,常量不能被赋值!

 

(2)

strcut STUDENT_INFORMATION  a, b[50], *p;

//要求:对b数组的第一个元素所代表的学生赋值如下信息:   04151038  李四  女  18  99

strcpy(b[0].StuName, “李四”);

strcpy(b[0].StuId, “04151038”);

b[0].StuSex = 0;

b[0].StuAge = 18;

b[0].Score = 99;

 

(3)

strcut STUDENT_INFORMATION  a, b[50], *p;

p = &a;   (p指向a)

*p = a;    (*在等号左边应念作:p所指向的空间,即实例a)

如何通过指针引用其所指向的实例的诸成员?

一般思路: *p.Age    错误       上述的”.”是一个运算符:取结构体实例成员运算符;其优先级高于!(逻辑非)运算符!

                                                在C语言的所有运算符中,优先级最高的前三个运算符是: () -> [] -> . (注意此处的点)

                  *p.Age <-> *(p.Age)   这应该称为:“p实例的Age”所指向的空间,这与原本要表达的意义完全无关!

正确表达: (*p).Age         繁琐           通过(),提高*的运算顺序:

                   p->Age          简单           正确念法是:p所指向的实例的Age成员

 

.运算符与->运算符优先级相同!

两个运算符的差别: 实例.成员

                                指针->成员

 

综上:访问结构体的成员规则如下(以StuSex为例)

strcut STUDENT_INFORMATION  a, b[50], *p;

a.StuSex 

b[0].StuSex

p->StuAge

 

二、结构体内存映像图

struct ABC

{

int a;

char b;

double c;

};

 

 

从上述结构体的内存映像图可知,一个结构体的长度,原则上是各成员长度之和。因此,sizeof(struct ABC) => 13B

注意:上机实验时,结果并非13B,而是比13B大,个中原因与一个较难、较深的概念有关:内存对其模式,该问题只能在进一步的课程《数据结构与算法》中深入探讨。

三、结构体实例赋初值

struct STI      

{

char Id[9];

char Name[21];

char Sex;    //也可以用int Sex;

int Age;

int Score;

};

 

struct STI a = {"03142069", "安宁", 'f', 23, 100};

struct STI b[3] =

{

         {“02150103”, “张三疯子”, ‘m’, 19, 100}, 

         {“02150101”, “仇娇雅子”, ‘f’, 22, 30},

         {“02150013”, “啤酒瓶子”, ‘m’, 20, 0},

};

struct STI b[3] = {“02150103”, “张三疯子”, ‘m’, 19, 100, “02150101”, “仇娇雅子”, ‘f’, 22, 30, };   //不完全赋初值

 

问题:表示性别时为何用单引号,忘记了,下去去查,进行理解。

 

注意”:C语言允许在结构体实例之间直接赋值!

struct STI a = {…};

struct STI b;

b = a; // 这就可以完成将a的所有成员数据,赋值给b的所有成员(不要再进行成员内部一个一个的赋值)

四、复合结构体

稍微专业一些的学生信息,示例如下:

struct DATE     //先定义出生日期

{

       short year;

       char month;

       char day;

};      // 经过上述语句,定义了一个struct DATE的数据类型,以后,就可以使用这个数据类型了!

 

struct STU_INF

{

       char stuId[9];

       char stuName[21];

       char stuSex;

       struct DATE stuBirth; // 这个成员本身是另一个结构体的实例!它有着自己的三个成员:year,month和day成员!

};

 

对struct STU_INF的使用:

struct STU_INF  a;

a有四个成员:a.stuId、a.stuName、a.stuSex和a.stuBirth;

其中的a.stuBirth自己存在3个成员:a.stuBirth.year 、a.stuBirth.month 、a.stuBirth.day 。

猜你喜欢

转载自blog.csdn.net/weixin_42072280/article/details/82630598
今日推荐