1、1,假定一台电脑由显示器、CPU、内存、硬盘和机箱5个部件组成,每个部件包括牌子、型号和价格3个属性,从一个文本文件中读取一台电脑的5个部件的信息,然后算出该电脑的总价格,并把5个部件的属性和总价格输出另一个文件中。,2,struct BuJian char PinPai;char XingHao;int JiaGe; ;,3,main() struct BuJian xsq,yp,cpu,nc,jx;int ZongJiaGe;FILE * fp;fp = fopen(“e:a.txt“,“r“);fscanf(fp,“%s %s %d“,xsq.PinPai,xsq.XingHao,4,Z
2、ongJiaGe = xsq.JiaGe + yp.JiaGe + cpu.JiaGe + nc.JiaGe + jx.JiaGe ;fp = fopen(“e:b.txt“,“w“);fprint(fp,“%s %s %dn“,xsq.PinPai,xsq.XingHao,xsq.JiaGe);fprint(fp,“%s %s %dn“,yp.PinPai,yp.XingHao,yp.JiaGe);fprint(fp,“%s %s %dn“,cpu.PinPai,cpu.XingHao,cpu.JiaGe);fprint(fp,“%s %s %dn“,nc.PinPai,nc.XingHao
3、,nc.JiaGe);fprint(fp,“%s %s %dn“,jx.PinPai,jx.XingHao,jx.JiaGe);fprint(fp,“ %dn“,ZongJiaGe);fclose(fp); ,5,第二题,6,struct BuJian char PinPai;char XingHao;int JiaGe; ;,7,struct DianNao BuJian xsq;BuJian yp;BuJian cpu;BuJian nc;BuJian jx; ;,8,main() struct DianNao dn3;int i;FILE * fp;fp = fopen(“e:a.txt
4、“,“r“);for(i=0;i3;i+)fscanf(fp,“%s %s %d“,dni.xsq.PinPai,dni.xsq.XingHao,9,第五讲 链表,10,链表结构,(1)头指针变量head指向链表的首结点。 (2)每个结点由2个域组成: 1)数据域存储结点本身的信息。 2)指针域指向后继结点的指针。 (3)尾结点的指针域置为“NULL(空)”,作为链表结束的标志,11,链表结构的定义,struct student char name10;struct student *next; next为student类型指针变量,指向下一个结点的指针域。 结点的变量或指针变量的定义: st
5、ruct student node,*head; node可以存放一个学生结点 指针head可以存放学生结点的地址。,12,例:建立一个简单链表,它由3个学生数据的节点组成。输出各节点中的数据。,#define NULL 0 struct student long num;float score;struct student *next; ; main() struct student a,b,c,*head,*p; a.num=10101;a.score=89.5; b.num=10103;b.score=90; c.num=10107;c.score=85;,head= ,13,NULL,
6、14,对链表的基本操作,链表的基本操作有:创建、查找、插入、删除和修改等: (1)创建链表:从无到有地建立起一个链表。 (2)查找:按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,称为检索失败。,15,(3)插入:在结点ki-1与ki之间插入一个新的结点k,使表的长度增1,且逻辑关系发生如下变化:(4) 删除操作:删除结点ki,使链表的长度减1,且ki-1、ki和ki+1结点之间的逻辑关系发生如下变化:,16,建立链表,1. 尾插法建立单链表 特点:头指针固定不变,新产生的结点总是链接到链表的尾部。 操作步骤: (1)设head为链表头,last为链表尾结
7、点,p为新结点。head=NULL; (2)生成新结点,由p指针指示(第一次p和last指向同一个结点),并将新结点的地址域清空:p-next=NULL; (3)如果head为NULL,则head=p; 否则 last-next=p; (4)last=p; (5)重复(2)(4),继续建立新结点。,17,struct student int num;char name10;struct student *next;,18,head=NULL,last=p=(struct student *)malloc(sizeof(struct student) p-next=NULL; scanf(“%d
8、”,head=NULL?,head=p,last-next=p; last=p;,p=(struct student *)malloc(sizeof(struct student) p-next=NULL; scanf(“%d”,p-num=0?,Y,N,Y,N,scanf(“%d”,p-name);,19,struct student *creat(void) struct student *head=NULL;struct student *p,*last;p=(struct student *)malloc(sizeof(struct student);last = p;p-next =
9、 NULL; scanf(“%d”,20,while(p-num!=0)scanf(“%s”,p-name); if(head=NULL) head=p;else last-next=p;last=p;p=(struct student *)malloc(sizeof(struct student);p-next=NULL;scanf(“%d”, ,21,2. 头插法建立单链表,特点:新产生的结点作为新的链表头插入链表。 操作步骤: (1)head=NULL; (2)生成新结点,指针变量p指向该结点; (3)p-next=head; head=p; (4)重复(2)(3),继续生成下一个链表结
10、点。,22,链表的学习与运用是对前面内容的综合,输入尽量用fscanf少用scanf,23,作业,建立学生结构体,包括学号、姓名和年龄,从文件“E:s.txt”中读取5个学生的信息,用头插法建立一个学生的链表。,24,链表的访问,1. 输出链表结点 操作步骤: (1)得到链表头结点的地址 head; (2)指针变量p=head; (3)输出p所指结点的成员值; (4)p后移一个结点,p=p-next; (5)重复(3)(4),直到链表为空。,25,void output(struct student *head) struct student *p=head; /p:遍历链表中的每个节点whi
11、le(p!=NULL)输出节点信息;p=p-next;/指针后移 ,程序,26,2. 统计链表结点的个数,一般情况下,各个单链表中结点个数是随机的,要想知道表中结点数目,必须从表头开始访问到表尾,逐个统计出结点数目。 3. 查找链表的某个结点 在链表上查找符合某个条件的结点,也必须从链表头开始访问链表。,27,链表的插入操作,在第n个结点之后插入1个新结点 ,插入操作步骤: (1)q指针指向新结点,i为已访问过的结点数; (2)p=head,r指向p结点的前一个结点; (3)i+,r=p,p=p-next,p结点往前移动一个结点; (4)若inext=head,head=q; (6)若inex
12、t=q,q-next=NULL; (7)否则,将q结点插入到第n个结点之后,即插入到r结点与p结点之间:r-next=q,q-next=p; (8)返回链表头head。,28,(a) head指示已有链表,q指示待插入结点,29,注意:指针的赋值顺序 q-next=r-next; r-next=q;,30,struct student *insert(struct student *head, struct student *p) struct student *p1,*p2; if(head=NULL) head=p; else p2=p1=head;while( p1!=NULL ,31,
13、链表的删除操作,删除第n个结点 (1)p=head,q指针指向p所指结点的前1个结点; (2)i为访问过的结点数目; (3)i+,q=p,p=p-next,p、q移动1个结点; (4)若p!=NULL且inext; (6)若head=NULL,链表为空,不能删除; (7)若p=NULL,第n个结点不存在,不能删除; (8)找到第n个结点,删除p结点:q-next=p-next; p的前1个结点的next值赋值为p的next域; (9)返回head。,32,指针的赋值方法: q-next=p-next; free(p);,33,程序,struct student *delete(struct s
14、tudent *head, int num) struct student *p,*p1;/p:删除点,p1:删除点前一个节点 if(head=NULL) 输出提示信息;/链表为空时没有要删除的节点,这里也可以不判断,可直接使用绿色和蓝色的代码 else p1=p=head;while(p!=NULL ,34,练习,建立一个学生结构体如下,写一个函数创建一个包含3个学生的链表,再写两个函数分别根据学生姓名来查找一个学生和删除一个学生.,struct student char name16; /*学生姓名*/int sno,age; /*学号,年龄*/struct student * next;
15、,35,第六讲,文件读写FILE * fp;fp = fopen(“e:a.txt”,”w+”);fprintf(fp,”%d”,56);fclose(fp);,36,文件读写FILE * fp;int x,y,z;fp = fopen(“e:a.bmp”,”r”); x = fgetc(fp); y = fgetc(fp); z = fgetc(fp); fclose(fp);,37,位运算按位与(&),运算规则 将两个运算量的每一个位进行逻辑与操作 举例:计算 3 ,38,位运算按位或(|),运算规则 将两个运算量的每一个位进行逻辑或操作 举例:计算 3 | 53: 0 0 0 0 0 0
16、 1 15:(|) 0 0 0 0 0 1 0 1 3 | 5: 0 0 0 0 0 1 1 1 用途: 将某些位置1,其它位不变。 例如:将 int 型变量 a 的低字节置 1 : a = a | 0xff;,39,位运算按位异或(),运算规则 两个操作数进行异或: 若对应位相同,则结果该位为 0, 若对应位不同,则结果该位为 1, 举例:计算 071052071: 0 0 1 1 1 0 0 1052: () 0 0 1 0 1 0 1 0071052 : 0 0 0 1 0 0 1 1,40,用途: 使特定位翻转(与0异或保持原值,与1异或取反)例如:要使 01111010 低四位翻转:0 1 1 1 1 0 1 0() 0 0 0 0 1 1 1 10 1 1 1 0 1 0 1,41,位运算取反(),单目运算符:对一个二进制数按位取反。 例: 025:0000000000010101025:1111111111101010,42,位运算移位,左移运算() 右移后,低位:舍弃 高位:无符号数:补0有符号数:补“符号位”,