十八、结构体

| 收藏本文 下载本文 作者:山河故人

下面就是小编给大家带来的十八、结构体(共含10篇),希望大家喜欢,可以帮助到有需要的朋友!同时,但愿您也能像本文投稿人“山河故人”一样,积极向本站投稿分享好文章。

十八、结构体

篇1:十八、结构体

结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合,结构中可以使用不同的数据类型。

一、结构说明和结构变量定义

在Turbo C中,结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样, 在使用结构变量时要先对其定义。

定义结构变量的一般格式为:

struct 结构名

{

类型 变量名;

类型 变量名;

...

} 结构变量;

结构名是结构的标识符不是变量名。

类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。

构成结构的每一个类型变量称为结构成员,它象数组的元素一样,但数组中元素是以下标来访问的,而结构是按变量名字来访问成员的。

下面举一个例子来说明怎样定义结构变量。

struct string

{

char name[8];

int age;

char sex[4];

char depart[20];

float wage1,wage2,wage3;

}person;

这个例子定义了一个结构名为string的结构变量person,如果省略变量名person,则变成对结构的说明。用已说明的结构名也可定义结构变量。这样定义时上例变成:

struct string

{

char name[8];

int age;

char sex[4];

char depart[20];

float wage1,wage2,wage3;

};

struct string person;

如果需要定义多个具有相同形式的结构变量时用这种方法比较方便,它先作结构说明,再用结构名来定义变量。

例如:

struct string Tianyr, Liuqi, ...;

如果省略结构名,则称之为无名结构,这种情况常常出现在函数内部,用这种结构时前面的例子变成:

struct

{

char name[8];

int age;

char sex[4];

char depart[20];

float wage1,wage2,wage3;

} Tianyr, Liuqi;

二、结构变量的使用

结构是一个新的数据类型,因此结构变量也可以象其它类型的变量一样赋值、运算,不同的是结构变量以成员作为基本变量。

结构成员的表示方式为:

结构变量.成员名

如果将结构变量.成员名看成一个整体,则这个整体的数据类型与结构中该成员的数据类型相同,这样就可象前面所讲的变量那样使用。

下面这个例子定义了一个结构变量,其中每个成员都从键盘接收数据,然后对结构中的浮点数求和,并显示运算结果。请注意这个例子中不同结构成员的访问。

#include

main

{

struct

{ /*定义一个结构变量*/

char name[8];

int age;

char sex[4];

char depart[20];

float wage1,wage2,wage3;

}a;

float wage;

char c='Y';

while(c=='Y'||c=='y') /*判断是否继续循环*/

{

printf(\nName:);

scanf(%s, a.name); /*输入姓名*/

printf(Age:);

scanf(%d, &a.wage); /*输入年龄*/

printf(Sex:);

scanf(%s, a.sex);

printf(Dept:);

scanf(%s, a.depart);

printf(Wage1:);

scanf(%f, &a.wage1); /*输入工资*/

printf(Wage2:);

scanf(%f, &a.wage2);

printf(Wage3:);

scanf(%f, &a.wage3);

wage=a.wage1+a.wage2+a.wage3;

printf(The sum of wage is %6.2f\n, wage);

printf(Continue?);

c=getche();

}

}

三、结构数组和结构指针

结构是一种新的数据类型, 同样可以有结构数组和结构指针,

1.结构数组

结构数组就是具有相同结构类型的变量集合。假如要定义一个班级40个同学的姓名、性别、年龄和住址, 可以定义成一个结构数组。如下所示:

struct

{

char name[8];

char sex[4];

int age;

char addr[40];

}student[40];

也可定义为:

struct string

{

char name[8];

char sex[4];

int age;

char addr[40];

};

struct string student[40];

需要指出的是结构数组成员的访问是以数组元素为结构变量的, 其形式为:

结构数组元素.成员名

例如:

student[0].name

student[30].age

实际上结构数组相当于一个二维构造, 第一维是结构数组元素, 每个元素是一个结构变量, 第二维是结构成员。

注意:

结构数组的成员也可以是数组变量。

例如:

struct a

{

int m[3][5];

float f;

char s[20];

}y[4];

为了访问结构a中结构变量y[2]的这个变量, 可写成y[2].m[1][4]

2.结构指针

结构指针是指向结构的指针。它由一个加在结构变量名前的* 操作符来定义, 例如用前面已说明的结构定义一个结构指针如下:

struct string

{

char name[8];

char sex[4];

int age;

char addr[40];

}*student;

也可省略结构指针名只作结构说明, 然后再用下面的语句定义结构指针。

struct string *student;

使用结构指针对结构成员的访问, 与结构变量对结构成员的访问在表达方式上有所不同。结构指针对结构成员的访问表示为:

结构指针名->结构成员

其中->是两个符号-和>的组合,好象一个箭头指向结构成员。例如要给上面定义的结构中name和age赋值,可以用下面语句:

strcpy(student->name, Lu G.C);

student->age=18;

实际上, student->name就是(*student).name的缩写形式。

需要指出的是结构指针是指向结构的一个指针, 即结构中第一个成员的首地址, 因此在使用之前应该对结构指针初始化, 即分配整个结构长度的字节空间,这可用下面函数完成, 仍以上例来说明如下:

student=(struct string*)malloc(size of (struct string));

篇2:file结构体

struct file, 定义于 , 是设备驱动中第二个最重要的数据结构,

file结构体

。 注意 file 与用户空间程序的FILE 指针没有任何关系。 一个 FILE 定义在 C 库中, 从不出现在内核代码中。 一个 struct file, 另一方面, 是一个内核结构, 从不出现在用户程序中。

文件结构代表一个打开的文件。 (它不特定给设备驱动; 系统中每个打开的文件有一个关联的 structfile 在内核空间)。 它由内核在 open 时创建, 并传递给在文件上操作的任何函数, 直到最后的关闭。 在文件的所有实例都关闭后, 内核释放这个数据结构。

在内核源码中, struct file 的指针常常称为 file 或者 filp(“file pointer”)。 我们将一直称这个指针为 filp 以避免和结构自身混淆。 因此, file 指的是结构, 而 filp 是结构指针。

struct file 的最重要成员在这展示。

1.mode_t f_mode;

文件模式确定文件是可读的或者是可写的(或者都是), 通过位 FMODE_READ 和FMODE_WRITE. 你可能想在你的 open 或者 ioctl 函数中检查这个成员的读写许可, 但是不需要检查读写许可, 因为内核在调用你的方法之前检查。 当文件还没有为那种存取而打开时读或写的企图被拒绝, 驱动甚至不知道这个情况。

2.loff_t f_pos;

当前读写位置。 loff_t 在所有平台都是 64 位( 在 gcc 术语里是 long long )。 驱动可以读这个值,如果它需要知道文件中的当前位置, 但是正常地不应该改变它; 读和写应当使用它们作为最后参数而收到的指针来更新一个位置, 代替直接作用于 filp->f_pos. 这个规则的一个例外是在 llseek 方法中, 它的目的就是改变文件位置,

3.unsigned int f_flags;

这些是文件标志, 例如 O_RDONLY, O_NONBLOCK, 和 O_SYNC. 驱动应当检查O_NONBLOCK 标志来看是否是请求非阻塞操作; 其他标志很少使用。 特别地, 应当检查读/写许可, 使用 f_mode 而不是f_flags. 所有的标志在头文件 中定义。

4.struct file_operations *f_op;

和文件关联的操作。 内核安排指针作为它的 open 实现的一部分, 接着读取它当它需要分派任何的操作时。 filp->f_op 中的值从不由内核保存为后面的引用; 这意味着你可改变你的文件关联的文件操作, 在你返回调用者之后新方法会起作用。 例如, 关联到主编号 1 (/dev/null, /dev/zero, 等等)的 open 代码根据打开的次编号来替代 filp->f_op 中的操作。 这个做法允许实现几种行为, 在同一个主编号下而不必在每个系统调用中引入开销。 替换文件操作的能力是面向

对象编程的“方法重载”的内核对等体。

5.void *private_data;

open 系统调用设置这个指针为 NULL, 在为驱动调用 open 方法之前。 你可自由使用这个成员或者忽略它; 你可以使用这个成员来指向分配的数据, 但是接着你必须记住在内核销毁文件结构之前, 在 release 方法中释放那个内存。 private_data 是一个有用的资源, 在系统调用间保留状态信息, 我们大部分例子模块都使用它。

6.struct dentry *f_dentry;

关联到文件的目录入口( dentry )结构。 设备驱动编写者正常地不需要关心 dentry 结构, 除了作为 filp->f_dentry->d_inode 存取 inode 结构。

真实结构有多几个成员, 但是它们对设备驱动没有用处。 我们可以安全地忽略这些成员, 因为驱动从不创建文件结构; 它们真实存取别处创建的结构。

篇3:C语言结构体说课稿

C语言结构体说课稿

各位老师,各位同行:

大家好。

今天我说课的内容是《结构体》,我将从以下六个方面来说课:

一、说教材理解:

本课程选自21世纪普通高校计算机公共课程规划教材《C程序设计实例教程》第四章数据组织的第三节。

本教材通过固定模式引导入门:用“输入—处理—输出”模式强化入门训练;

使用任务驱动语法学习,用实例讲解语法,同一个问题用不同的知识点分别实现。

二、说教学目标:

1、知识与技能

(1)学会和掌握结构体类型的定义方法和结构体变量的定义及初始化。

(2)学会和掌握结构体数组的定义、初始化以及使用。 2、过程和方法

(1)通过程序半成品修改实现结构体,帮助掌握结构体语句的语法格式。

(2)通过程序设计编写,体验并归纳结构体语句解决问题的基本思想。

3、情感态度与价值观

(1)培养学生对新事物的认知能力和解决实际问题的能力。

(2)初步在学生心中建立数据存储效率的思想。

三、说教学对象:

大一学生已经有很强的独立思考能力、抽象思维能力和认识新事物的能力,而且已经学习了C语言的基础知识。前面已经学过基本数据类型──整型、浮点型、字符型,也介绍了一种构造类型──数组,并且会引用构造出的'数组类型来实现程序的编写。

四、说教法学法:

首先根据上节课所学知识提出问题,快速自然的引出本节课主题(结构体),采用任务驱动法提出任务,紧接着教师引导学生共同分析问题、修改程序以实现对结构体的认识。中途可以适时向学生提出问题,让学生自己对程序做出修改,教师在进行判断给与学生反馈。“编写程序”环节中要注意引导学生对照格式来编写程序,以降低学习难度,逐步提高学生的编程能力。

五、说教学流程:

(一)知识回顾,提出问题,引入新知。

向同学展示上节课的成功作品(未使用结构体的通讯录程序),对程序进行简单分析,提出问题:如果将不同类型的数据组合成一个有机的整体,这样是否更方便呢?

设计意图:创设情境,引发动机,引出本课知识点:结构体及其运用。

(二)学习新知,提出结构体一般形式。

1、对结构体的一般形式进行解说,对每个人的信息进行定义以后,结构体的变量需要引用结构体的成员进行存取数据,如Table[i].Num。

结构体中的成员称为域或字段。本例中的结构有三个成员:Num、Name和TelNum。 设计意图:提出新知识,引起学生注意力,理解结构体语句的格式,实际操作,遇到问题,引发思考。

2、教师带领学生运用VC++6.0软件,按照ppt上所呈现的结构体语句格式修改上次的代码,引入结构体类型,运行代码,结果出现了错误,接着教师就像同学们提问:为什么引入结构体类型后会出错呢?

设计意图:激发学生的求知欲,带领学生一起来解决问题(原因是仅仅引入了结构体的类型,并没有实现结构体的各个字段或域的正确引用)。

(三)学习新知,修改代码实现结构体内部字段的引用。

1、通过修改结构体内部字段的引用方法,帮助学生从实践中学会学会和掌握结构体数组的定义、初始化以及使用。

设计意图:培养学生的动手能力,动脑能力,和探索学习的能力,边改边学。

(四)学习新知,提出结构体另外3种形式。

对结构体的另外3种形式进行解说,对每个人的信息进行定义以后,结构体的变量需要引用结构体的成员进行存取数据,如Table[i].Num。

(五)学习新知,提出结构体另外3种形式。

对结构体的另外3种形式进行解说,给学生进行知识拓展和延伸。

(六)课堂总结,升华主旨。

注意结构类型的定义,结构变量的定义,结构变量的成员的引用(下节课涉及)。 C语言结构体中的成员是以定义的先后顺序连续存放的。

结构体把一个对象封装起来,设计和理解更容易。

结构体类型是抽象的,变量才是具体的。类型不占用空间,只有实例化成了变量才占用空间。

(七)作业安排,巩固所学。

一个学生的学号(num)、姓名(name)、性别(sex)、年龄(age)、成绩(score) 、家庭地址(addr)等项,这些项与某一学生相联系。请运用结构体实现以下功能:

输入学生信息

按姓名排序

显示通讯录

设计意图:巩固课堂所学是作业设计的关键所在,是根本。

篇4:关于变长结构体 的一些讨论

A:我是这样定义的,不知对不对

typedef  struct  tagTest{

int  uID;//标志

int  iNum;//个数

int  offset;//偏移量

char  *str;//指针

}TEST_S;

uID是固定的,iNum个数是这样的,根据后面的,比如:

我需要返回两对数据,则为2,但我不知如何把这两对数据存入这个结构体中,也有可能是3对数据,数据类型可以是int  .谢谢!

B:我认识一个高人,很喜欢用这种结构,他颇有心得,我就在这里说一下

type  struct  tagTest

{

int  uID;

int  iNum;

int  offset

int  data[1];

}  test;

data是一个数据,个数为1,但是其实在使用的时候,不一定为1,也就是说在上述结构不能

直接test  tt;这样声明,必要声明成指针,然后在malloc的时候,根据iNum数目进行申请,

譬如iNum为5个int,这可以这样

p  =  (test  *)malloc(sizeof(test)  +  (iNum  -  1)  *  sizeof(int));

这样,后面的内容可以通过p->data[i]访问了:)

C:如果编译器够新,可以用VLA:

type  struct  tagTest

{

int  uID;

int  iNum;

int  offset

int  data[];

}  test;

使用时就不需要减一了:

p  =  (test  *)malloc(sizeof(test)  +  iNum  *  sizeof(int));

这里的data只是个占位符,sizeof(test)=3*sizeof(int),

关于变长结构体 的一些讨论

篇5:C语言结构体说课稿

(设计人:教育技术11D 布鲁斯·李)

各位老师,各位同行大家好:

今天我说课的内容是《结构体》,我将从以下六个方面来说课:

1、说教材

2、说教学目标

3、说重点难点

4、说教学对象

5、说教法学法

6、说教学过程

一、说教材理解:

本课程选自21世纪普通高校计算机公共课程规划教材《C程序设计实例教程》第四章数据组织的第三节。

本教材通过固定模式引导入门:用“输入—处理—输出”模式强化入门训练;

使用任务驱动语法学习,用实例讲解语法,同一个问题用不同的知识点分别实现。

二、说教学目标:

1、知识与技能

(1)学会和掌握结构体类型的定义方法和结构体变量的定义及初始化。

(2)学会和掌握结构体数组的定义、初始化以及使用。  2、过程和方法

(1)通过程序半成品修改实现结构体,帮助掌握结构体语句的语法格式。

(2)通过程序设计编写,体验并归纳结构体语句解决问题的基本思想。

3、情感态度与价值观

(1)培养学生对新事物的认知能力和解决实际问题的能力。

(2)初步在学生心中建立数据存储效率的思想。

三、说教学对象:

大一学生已经有很强的独立思考能力、抽象思维能力和认识新事物的能力,而且已经学习了C语言的基础知识。前面已经学过基本数据类型──整型、浮点型、字符型,也介绍了一种构造类型──数组,并且会引用构造出的数组类型来实现程序的编写。

四、说教法学法:

首先根据上节课所学知识提出问题,快速自然的引出本节课主题(结构体),采用任务驱动法提出任务,紧接着教师引导学生共同分析问题、修改程序以实现对结构体的认识。中途可以适时向学生提出问题,让学生自己对程序做出修改,教师在进行判断给与学生反馈。“编写程序”环节中要注意引导学生对照格式来编写程序,以降低学习难度,逐步提高学生的编程能力。

五、说教学流程:

篇6:C语言结构体说课稿

(一)知识回顾,提出问题,引入新知。

向同学展示上节课的成功作品(未使用结构体的通讯录程序),对程序进行简单分析,提出问题:如果将不同类型的数据组合成一个有机的整体,这样是否更方便呢?

设计意图:创设情境,引发动机,引出本课知识点:结构体及其运用。

(二)学习新知,提出结构体一般形式。

1、对结构体的一般形式进行解说,对每个人的信息进行定义以后,结构体的变量需要引用结构体的成员进行存取数据,如Table[i].Num。

结构体中的成员称为域或字段。本例中的结构有三个成员:Num、Name和TelNum。   设计意图:提出新知识,引起学生注意力,理解结构体语句的格式,实际操作,遇到问题,引发思考。

2、教师带领学生运用VC++6.0软件,按照ppt上所呈现的结构体语句格式修改上次的代码,引入结构体类型,运行代码,结果出现了错误,接着教师就像同学们提问:为什么引入结构体类型后会出错呢?

设计意图:激发学生的求知欲,带领学生一起来解决问题(原因是仅仅引入了结构体的类型,并没有实现结构体的各个字段或域的正确引用)。

(三)学习新知,修改代码实现结构体内部字段的引用。

1、通过修改结构体内部字段的`引用方法,帮助学生从实践中学会学会和掌握结构体数组的定义、初始化以及使用。

设计意图:培养学生的动手能力,动脑能力,和探索学习的能力,边改边学。

(四)学习新知,提出结构体另外3种形式。

对结构体的另外3种形式进行解说,对每个人的信息进行定义以后,结构体的变量需要引用结构体的成员进行存取数据,如Table[i].Num。

(五)学习新知,提出结构体另外3种形式。

对结构体的另外3种形式进行解说,给学生进行知识拓展和延伸。

(六)课堂总结,升华主旨。

注意结构类型的定义,结构变量的定义,结构变量的成员的引用(下节课涉及)。 C语言结构体中的成员是以定义的先后顺序连续存放的。

结构体把一个对象封装起来,设计和理解更容易。

结构体类型是抽象的,变量才是具体的。类型不占用空间,只有实例化成了变量才占用空间。

(七)作业安排,巩固所学。

一个学生的学号(num)、姓名(name)、性别(sex)、年龄(age)、成绩(score) 、家庭地址(addr)等项,这些项与某一学生相联系。请运用结构体实现以下功能:

输入学生信息

按姓名排序

显示通讯录

设计意图:巩固课堂所学是作业设计的关键所在,是根本。

篇7: 十八

关于十八

青春大概定在一个什么时期,电影里的热血恰在谁的身上发生,谁又说过嗯那就是我要的未来,有什么意外让那些潇洒落寞,有什么解释不开的误会让朋友走散,十八岁的不服从安排与完美的想象错开。

我想,关于十八,纵使是“就这样吧”,我还是想纪念,纪念所谓懵懂的未成年,纪念我自认为深刻的不可原谅,纪念写过还是不懂的习题,并不再记起。

我想每个人都有那个18的无可奈何,是那个不明所以的感情,是那个众人不晓的'情绪,是想说不能说的秘密,而我可怜的是面目可憎却又不得应对的老师,他的不屑,他的不可一世,他的丑陋,像社会的病态,想罢他是所要忘记。

关于我的十八,我想我更想像是平凡的世界里的孙少平,活的没有表面风光,却有着镶入骨子里的浪漫情怀。

其实,十八岁没什么个性的,还有18岁01天18岁02天

但是也算是个节点,提醒我去忘记那些个衰的事那些个想起就想爆粗的人,没有蜡烛也能够许愿,比如能遇到一个好的老师,能再认识一群那么酷的人

18岁,你好哦,不用指教,我自己走

From:阿棱

篇8:岩体结构面有哪些类型及其特征?

结构面也称不连续面,切割岩体的各种地质界面统称为结构面。它们是一些具有一定方向、延展较广、厚度较薄的二维地质界面,如层面、沉积间断面、节理、断层等,也包括厚度较薄的软弱夹层。结构面在空间按不同组合,可将岩体切割成不同形状和大小的块体,这些被结构面所围限的岩块称为结构体。岩体的结构特征,就是指岩体中结构面和结构体的形状、规模、性质及其组合关系的特征。

篇9:C结构体实现一个通讯录

题目:实现一个通讯录,通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名,性别,年龄,电话,住址,

提供方法:1.添加联系人信息 2.删除指定联系人的信息 3.查找指定联系人的信息 4.修改指定联系人的信息 5.显示所有联系人信息 6.清空所有联系人 7.以名字排序所有联系人

思路分析:1. 首先我们可以分三个模块来解决这个问题,第一个模块我们需要一个头文件,这个头文件里可以包含一些相应信息,当实现文件和测试文件包含自己定义的头文件时便可以获得一些相关的信息。所以头文件里应该包括一个结构体,这个结构体里应包含姓名,性别,年龄,电话,住址。同时还可以定义一个结构体,这个结构体里包含通讯录,同时通讯录里人员的计数变量,将通讯录的地址传到别的地方便可以实现对它遍历或者其他操作。 2.第二个模块便是我们的测试函数,测试函数便可以实现我们的菜单打印,同时由我们接收不同的值便可以实现不同的操作,就是相应的方法的实现,这里很明显可以通过一个switch语句来进行控制。 3.第三个模块便是我们的方法实现的函数,将模块2里定义的类型为通讯录的地址传到各个方法里,这样便可以实现对通讯录的操作。

代码实现:

模块1:

#pragma oncetypedef struct Peo//每一个人的信息用一个结构来接收,包括姓名,性别,年龄,电话,地址{char name[20];char sex[4];int age;char tell[12];char address[20];}Peo;typedef struct Contact//将通讯录和人员计数也声明在结构体里{Peo Dhb[1000];int count;}Contact;void add_stu(Contact *p);//相应函数void del_stu(Contact *p);void find_stu(Contact *p);void modify_stu(Contact *p);void show_stu(Contact *p); void clear_stu(Contact *p);void sort_stu(Contact *p);

模块2:(测试功能)

#include#include“contact.h”#includeContact con;//类型为Contact变量,里面包含电话本和计数变量void menu{printf(“menu:\n”);printf(“**********1.添加联系人信息************\n”);printf(“********2.删除指定联系人信息**********\n”);printf(“********3.查找指定联系人信息**********\n”);printf(“********4.修改指定联系人信息**********\n”);printf(“********5.显示所有联系人信息**********\n”);printf(“**********6.清空联系人信息************\n”);printf(“******7.以名字排序所有联系人信********\n”);}void test()//测试函数{int input = 1;menu();while (input){printf(“请输入选项:”);scanf_s(“%d”, &input);switch (input)//方法选择功能的实现{case 1:add_stu(&con);break;case 2:del_stu(&con);break;case 3:find_stu(&con);break;case 4:modify_stu(&con);break;case 5:show_stu(&con);break;case 6:clear_stu(&con);break;case 7:sort_stu(&con);break;case 0:exit(1);break;}}}int main(){test(); return 0;}

模块3:(方法的具体实现)

#include“contact.h”#includeint search(Contact *p,char *pname)//分装的函数利于删除,查找,修改方法的实现{int ret;int i;for (i = 0; i < p->count; i++){if(strcmp(p->Dhb[i].name, pname)==0)return i;}return -1;}void add_stu(Contact *p)//添加联系人{printf(“请输入姓名:”);scanf(“%s”, p->Dhb[p->count].name);printf(“请输入性别:”);scanf(“%s”, p->Dhb[p->count].sex);printf(“请输入年龄:”);scanf(“%d”, &p->Dhb[p->count].age);printf(“请输入电话:”);scanf(“%s”, p->Dhb[p->count].tell);printf(“请输入地址:”);scanf(“%s”, p->Dhb[p->count].address);p->count++;printf(“联系人添加成功\n”);}void del_stu(Contact *p)//删除联系人{int ret;int n;int i = 0;char name[20];printf(“请输入要删除人的姓名:”);scanf(“%s”,name);ret=search(p,name);if (ret !=-1){printf(“要删除的人存在\n”);printf(“你是否确定删除该联系人?\n”);printf(“确定输入1,不删除输入0\n”);scanf(“%d”,&n);if (n == 1){for (i = 0; i < p->count; i++){p->Dhb[i] = p->Dhb[i + 1];//使i后面的元素向前覆盖便可以删掉}printf(“删除成功\n”);}else{printf(“删除失败\n”);}}}void find_stu(Contact *p)//查找联系人{int ret;char name[20];printf(“请输入要查找人的姓名:”);scanf(“%s”, name);ret = search(p, name);if (ret !=-1){printf(“要查找的人存在\n”);printf(“%s ”, p->Dhb[ret].name);printf(“%s ”, p->Dhb[ret].sex);printf(“%d ”, p->Dhb[ret].age);printf(“%s ”, p->Dhb[ret].tell);printf(“%s ”, p->Dhb[ret].address);}}void modify_stu(Contact *p)//修改联系人{int ret;char name[20];printf(“请输入要修改人的姓名:”);scanf(“%s”, name);ret = search(p, name);if (ret != -1){printf(“请把姓名修改成:”);scanf(“%s”, p->Dhb[ret].name);printf(“请把性别修改成:”);scanf(“%s”, p->Dhb[ret].sex);printf(“请把年龄修改成:”);scanf(“%d”, &p->Dhb[ret].age);printf(“请把电话修改成:”);scanf(“%s”, p->Dhb[ret].tell);printf(“请把地址修改成:”);scanf(“%s”, p->Dhb[ret].address);}else{printf(“不存在此人\n”);}}void show_stu(Contact *p)//显示联系人信息{int i = 0;printf(“输出所有人的信息:”);for (i = 0; i <( p->count); i++){printf(“%s ”,p->Dhb[i].name);printf(“%s ”, p->Dhb[i].sex);printf(“%d ”, p->Dhb[i].age);printf(“%s ”, p->Dhb[i].tell);printf(“%s ”, p->Dhb[i].address);}printf(“\n”);}void clear_stu(Contact *p)//清空联系人{p->count = 0;//是人员计数的变量置0就可以实现清空}void sort_stu(Contact *p)//以名字排序所有联系人{int i = 0;int j = 0;for (i = 0; i < p->count-1;i++)//冒泡法for (j = 0; j < p->count - 1 - i;j++){if (strcmp(p->Dhb[j].name, p->Dhb[j + 1].name)>0){Peo tmp;tmp=p->Dhb[j];p->Dhb[j] =p->Dhb[j + 1];p->Dhb[j + 1] = tmp;}}void show_stu( p);}

总结:此题只是利用了相关结构体的知识,主要难处就是三个模块各自的分工不好想到,其他地方便只是基本方法的实现,

篇10:结构体的内存空间分配及字节对齐

关于内存对齐

一:

1.什么是内存对齐

假设我们同时声明两个变量:

char a;

short b;

用&(取地址符号)观察变量a,

b的地址的话,我们会发现(以16位CPU为例):

如果a的地址是0x0000,那么b的地址将会是0x0002或者是0x0004,

那么就出现这样一个问题:0x0001这个地址没有被使用,那它干什么去了?答案就是它确实没被使用。因为CPU每次都是从以2字节(16位CPU)或是4字节(32位CPU)的整数倍的内存地址中读进数据的。如果变量b的地址是0x0001的话,那么CPU就需要先从0x0000中读取一个short,取它的高8位放入b的低8位,然后再从0x0002中读取下一个short,取它的低8位放入b的高8位中,这样的话,为了获得b的值,CPU需要进行了两次读操作。

但是如果b的地址为0x0002,那么CPU只需一次读操作就可以获得b的值了。所以编译器为了优化代码,往往会根据变量的大小,将其指定到合适的位置,即称为内存对齐(对变量b做内存对齐,a、b之间的内存被浪费,a并未多占内存)。

2.结构体内存对齐规则

结构体所占用的内存与其成员在结构体中的声明顺序有关,其成员的内存对齐规则如下:

(1)每个成员分别按自己的对齐字节数和PPB(指定的对齐字节数,32位机默认为4)两个字节数最小的那个对齐,这样可以最小化长度。

(2)复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。

(3)结构体对齐后的长度必须是成员中最大的对齐参数(PPB)的整数倍,这样在处理数组时可以保证每一项都边界对齐。

(4)计算结构体的内存大小时,应该列出每个成员的偏移地址,则其长度=最后一个成员的偏移地址+最后一个成员数的长度+最后一个成员的调整参数(考虑PPB)。

下面举例说明上述规则:

#include#pragma pack(2) //指定PPB为2struct T { char a; //偏移地址0 int b; //偏移地址2 char c; //偏移地址6};#pragma pack() //恢复原来默认PPB,32位下为4int main(int argc,char * argv[]){ printf("sizeof(struct T)); return 0;}最后输出的结果为:8。语句#pragma pack(2)的作用是指定结构体按2字节对齐,即PPB=2。分析如下:

变量a默认为1字节,PB=2,所以a按1字节对齐,a的偏移地址为0。

变量b默认为4字节(在32位机器中int为4字节),PB=2,所以b按2字节对齐,b的偏移地址为2。

变量c默认为1字节,PB=2,所以c按1字节对齐,偏移地址为6。

此时结构体的计算出的字节数为7个字节。最后按规则3,结构体对齐后的字节数为8。sizeof(T)=6+1+1=8

3.范例

(1)#pragma pack(2) //指定PPB为2

struct T { char a; //偏移地址0 char b; //偏移地址1 int c; //偏移地址2};

则sizeof(T)=最后一个成员的偏移地址+最后一个成员数的长度=2+4=6。

struct T1 { char a; //偏移地址0 char b; //偏移地址1 int c; //偏移地址4};struct T2 { char a; //偏移地址0 int b; //偏移地址4 char c; //偏移地址8};

PPB=4,则sizeof(T1)=4+4=8;sizeof(T2)=8+1=9,9不能整除4,故调整数为3,即sizeof(T2)=8+1+3=12

4.注意的问题

(1)字节对齐取决于编译器;

(2)一定要注意PPB大小,PPB大小由pragam pack(n)指定;

(3)结构体占用的字节数要能被PPB整除,

二:

(1)sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用。

(2)终于搞懂struct结构体内存分配问题了,结构体中各个成员字节对齐遵循以下几个原则: 直接用下面几个原则即可判断结构体的大小

1.结构体每个成员相对于结构体首地址的偏移量(offset)都是(这个)成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internaladding);

例如有以下一个结构体:

structex { int i; char t; int n;};

第1个成员偏移量为0,是int型成员大小4(假设这太机器的整型长度占4个字节)的整数倍。

第2个成员t为char型,他的大小为1,首先假设在成员i和t之间没有填充字节,由于i是整型,占4个字节那么在没有填充之前,第2个成员t相对于结构体的偏移量为4,他是t成员大小1的4倍,符合此条件,所以系统在给结构体第2个成员分配内存时,不会在i和t之间填充字节以到达对齐的目的。

当分配结构体第3个成员n时,首先发现是一个整型数据,大小为4,没有填充之前,n相对于结构体首地址偏移量为:前面2个成员+填充字节=5,所以当系统发现5不是4(成员大小)的整数倍时,会在成员t之后(或者说n之前)填充3个字节,以使n的偏移量到达8而成为4的整数倍。这样这个结构体占用内存情况暂时为4+1+3+4。

2.结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailingpadding)。

上面的结构体内存分配以后还要看是否满足此条件,假设在最末一个成员之后不需填充字节数,那么这个结构体的大小为12。而ex结构体中最宽基本类型成员为int,大小为4,12为4的整数倍,所以无须再在最末一个成员之后加上填充字节了。所以sizeof(ex)=12;

如果一个结构体如下所示:

struc test1 { int i; char t; int n; char add;};那么sizeof(ex1)=16;原因就是在最后一个成员之后填充了3个字节。

3.还有一个额外的条件:结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

4.对于结构体成员属性中包含结构体变量的复合型结构体再确定最宽基本类型成员时,应当包括复合类型成员的子成员。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。

5总结出一个公式:结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目,即:

sizeof( struct ) = offsetof( last item ) + sizeof( last item ) +sizeof( trailing padding )

十八抒情散文

十八春读后感

语录体

十八精神辅导主持词

女孩,十八了诗歌

游十八湾作文

筒体结构在侧向力作用下有哪些受力特点?

句子结构

初中英语There be 结构

策划书结构

十八、结构体(精选10篇)

欢迎下载DOC格式的十八、结构体,但愿能给您带来参考作用!
推荐度: 推荐 推荐 推荐 推荐 推荐
点击下载文档 文档为doc格式

相关文章

点击下载本文文档