350 likes | 539 Views
第10章 结构体、位运算. 结构体 typedef 语句 共用体 枚举 位运算. 姓名. C 语言. 英语. 高数. 计算机. Jiang Jun. 86. 90. 78. 68. Wang Hong. 62. 65. 80. 70. Li Sijia. 65. 76. 92. 75. Chang Mi. 79. 80. 60. 67. Li Weiwei. 95. 85. 73. 88. 10.0 结构体导入 为什么要使用结构体?. 例如 : 期末考试结束,已知 5 位学生的考试成绩,如下:.
E N D
第10章 结构体、位运算 • 结构体 • typedef语句 • 共用体 • 枚举 • 位运算
姓名 C语言 英语 高数 计算机 Jiang Jun 86 90 78 68 Wang Hong 62 65 80 70 Li Sijia 65 76 92 75 Chang Mi 79 80 60 67 Li Weiwei 95 85 73 88 10.0 结构体导入 为什么要使用结构体? 例如:期末考试结束,已知5位学生的考试成绩,如下: 编写程序,要求:计算出每位学生的总成绩,并按总分由高到低输出一张成绩单,格式如下: Rank name CLanguage English maths Computer Sum 1 **** ** ** ** ** *** 2 **** ** ** ** ** *** 3 **** ** ** ** ** *** 4 **** ** ** ** ** *** 5 **** ** ** ** ** *** 分析: char na[5][10]={…}; int score[5][4]={{…},…}; int s[5] ; /*每个同学的总分 */ • 解决的办法: 将一位学生的数据作为结构体类型
定义语句的格式: struct结构体名 {数据类型1 成员名1; 数据类型2 成员2名; …; 数据类型n 成员名n; }; 10.1 结构体类型的定义 1.什么是结构体类型? 将一组不同类型的数据组织在一起形成的一种新的数据类型。 2.结构体类型的定义 例1:struct s_type { char num[15]; char name[20]; int score[4]; int s; }; • 结构体名、成员名:用户标识符 • 结构体类型的标识符:struct 结构体名 • 结构体类型的作用域 :类似于变量的作用域
10.2 结构体变量 1.结构体变量的定义:有3种方法 ① 先定义结构体类型,再定义结构体变量 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; }; main() { struct s_type student1,student2; …. }
10.2 结构体变量 1.结构体变量的定义:有3种方法 ② 在定义结构体类型的同时,定义结构体变量 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; } student; main() { struct s_type student1,student2; …. }
10.2 结构体变量 1.结构体变量的定义:有3种方法 ③ 直接定义结构体变量 例如: struct { char num[15]; char name[20]; int score[4]; int s; } student; main() { …. }
10.2 结构体变量 2.结构体变量需要的内存 等于结构体变量所有成员占内存之和 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; } student; • 表达式:sizeof(student)或sizeof(struct s_type)的值为:45 • 结构体变量成员的表示:结构体变量名 . 成员名
student.num student.score student.name student student.s 10.2 结构体变量 • 结构体变量student及其各个成员占用内存的情况见下图: 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; } student; 注意: • 结构体变量成员表示的含义: 内存地址?存储单元? • 系统为结构体变量分配内存,但不会为结构体类型分配内存。
2007 101010 student.num wang student.name student • 90 • 87 80 student.score student.s 0 10.2 结构体变量 3.结构体变量的初始化:为结构体变量的成员赋初值 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student={"2007101010", "wang",{89,90,87,80},0};
10.2 结构体变量 4.结构体变量的使用 ①允许将一个结构体变量直接赋值给另一个具有相同结构的结构体变量 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student={"2007101010", "wang",{89,90,87,80},0}; main() { struct s_type student1; student1=student; ……. }
10.2 结构体变量 4.结构体变量的使用 ②不能将一个结构体变量作为一个整体进行输入或输出 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student={"2007101010", "wang",{89,90,87,80},0}; main() { struct s_type student1; printf("%s ", student); /* 错误 */ ……. }
10.2 结构体变量 4.结构体变量的使用 ③只能对结构体变量中的各个成员分别输入或输出或进行其它操作 main() { int i; printf("Input num:"); gets(student.num); printf("Input name:"); gets(student.name); printf("Input score:"); for(i=0;i<4;i++) { scanf("%d", &student.score[i]); student.s+=student.score[i]; } printf("%s \n", student.num); printf("%s \n", student.name); for(i=0;i<4;i++) printf("%d", student.score[i]); printf("\n"); printf("%d\n",student.s); } 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student;
10.2 结构体变量 5. 结构体成员的数据类型:可以是任意类型 • 当结构体成员的数据类型为另一个结构体类型时: 例如: struct s1 { int y; int m; int d; }; struct s2 { char num[15]; char name[20]; struct s1 bday; int score[4]; int s; }; main() { struct s2 student={"2007101010", "wang", {1987,11,12}, {87,90,89,80},0}; printf("%s \n", student.num); printf("%s \n", student.name); printf("y-m-d:%d-%d-%d", student.bday.y, student.bday.m, student.bday.d); for(i=0;i<4;i++) printf("%d", student.score[i]); printf("\n"); printf("%d\n",student.s); }
10.2 结构体变量 6.结构体变量应用举例 例:定义一个结构体变量来表示一个日期(年月日),编程实现:根据输入的日期确定该日在本年中是第几天。 struct DATA{ int y; int m; int d; }; main() { int m_day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int i,days=0; int t,a,b; struct DATE adate; printf("input a date as :YYYY-MM-DD\n"); scanf("%d-%d-%d",&adate.y,&adate.m,&adate.d); a= (adate.y%4==0)&&(adate.y%100!=0); b= (adate.y%400==0); t=a||b; if(t) m_day[2]=29; for(i=1;i<adate.m;i++) days+=m_day[i]; days+=adate.d; printf("%d-%d-%d is the %d days of the year ", adate.y,adate.m,adate.d,days); }
10.2 结构体变量 5. 思考讨论 在定义一个结构体变量时系统分配给它的存储空间是( ) A) 该结构体变量中第一个成员所需存储空间 B) 该结构体变量中最后一个成员所需存储空间 C) 该结构体变量中所有成员所需存储空间的总和 D) 结构体变量本身并不占用存储空间,即系统并不给结构体变量分配存储空间
10.3 结构体数组 1.结构体数组的定义:有3种方法,与结构体变量类似 ①先定义结构体类型,再定义结构体数组 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; }; main() { struct s_type stu[3]; …. }
10.3 结构体数组 1.结构体数组的定义:有3种方法,与结构体变量类似 ② 在定义结构体类型的同时定义结构体数组 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3]; main() { struct s_type student; …. } ③ 直接定义结构体数组
10.3 结构体数组 2.结构体数组需要的内存 等于结构体数组所有元素占内存之和 例如:struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3]; • 表达式: sizeof(struct s_type)的值为:45 sizeof(stu) 的值:135
10.3 结构体数组 3.结构体数组的初始化:将一组结构体数据存储在结构体数组的过程 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3]={{"2007101010", "wang",{89,90,87,80},0}, {"2007101011", "Li",{88,95,77,70},0}, {"2007101012", Jiang",{79,65,69,76},0} };
10.3 结构体数组 4. 结构体数组元素的使用 • 结构体数组元素类似于一个结构体变量 • 只能对结构体数组元素的成员进行输入、输出或其它基本操作 main() { int i; for(i=0;i<3;i++) for(j=0;j<4;j++) stu[i].s+=stu[i].score[j]; …. } 例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3]={{"2007101010", "wang",{89,90,87,80},0}, {"2007101011", "Li",{88,95,77,70},0}, {"2007101012", Jiang",{79,65,69,76},0} };
#include <stdio.h> main(void) { struct s_type temp; int i, j; /* 输入成绩单并计算总分 */ for(i=0;i<N;i++) { printf("enter student %d\n",i); gets(stu[i].num); gets(stu[i].name); stu[i].s=0; for (j=0;j<4;j++) { scanf("%d",&stu[i].score[j]); stu[i].s+= stu[i].score[j]; } getchar(); /* 跳过多余的回车键 */ } ……; } /* 按总分由高到低排序 */ for(i=1;i<N;i++) for(j=0;j<N-i;j++) if( stu[j].s<stu[j+1].s) { temp=stu[j]; stu[j]=stu[j+1]; stu[j+1]=temp; } ……; } 10.3 结构体数组 5. 结构体数组应用举例 /* 按格式输出 */ printf("%-6s%-15s%-20%-5s%-5s%-5s%-5s%-5s\n", "No.","num","name", "Lge","Esh","Math","Cter","Sum"); for(j=0;j<N;j++) { printf("%-6d%-15s",j+1,stu[j].num); printf("%-20s", stu[j].naue); for(i=0;i<4;i++) printf("%-5d",stu[j].score[i]); printf("%-5d",stu[j].s); printf("\n"); } } 例I:某班有38名学生,期末考试结束,已知每位学生的成绩单包括:学号、姓名、4门课的成绩,要求写程序实现:求出每个学生的总分,并按总分由高到低的顺序输出全班学生的成绩单。格式如下: 名次 学号 姓名 C语言 高数 …… 总分 1 *** #define N 5 struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[N];
10.3 结构体数组 5. 结构体数组应用举例 例II:候选人得票统计程序。设有5个候选人,每次输入一个得票候 选人的名字,最后输出每个人得票结果。 struct p_type {char name[10]; int vote; }pn[5] = {{"wang",0}, {"li",0}, {"chen",0} , {"lin",0}, {"sun",0}}; main( ) {char str[10]; int i; do { printf(“name:”); gets(str); for(i=0; i<5; i++) if (strcmp(str, pn[i].name)==0) pn[i].vote++; } while(strlen(str)); printf("%-10s%-6s\n",“name”,“count”); for(i=0; i<5; i++) printf("%-10s%-6d\n", pn[i].name, pn[i].vote); }
10.3 结构体数组 6. 思考讨论 第1题:建立一个结构体数组存放五个学生的成绩单,成绩单中包括每个学生的姓名(字符串)和总分(整型)。要求输出总分最高的学生的姓名及总分。 main() { struct stu_type { char na[10]; int s; }student[5]={{"Wang",634},{"Li",709},{"Jiang",686}, {"Sun",647.5},{"Pei",688}}; int j,max=0; for(j=1;j<5;j++) if(student[j].s>student[max].s) max=j; printf("%-10s%-10d\n",student[max].na,student[max].s); }
10.3 结构体数组 6. 思考讨论 第2题:建立一个结构体数组存放五个学生的成绩单,成绩单中包括每个学生的姓名(字符串)和总分(整型)。要求查找姓名为“wang”的学生,如果找到则显示其姓名和总分,否则显示“NO”。 #include<string.h> main() { struct stu_type { char na[10]; int s; }student[5]={{"Wang",634},{"Li",709},{"Jiang",686}, {"Sun",647.5},{"Pei",688}}; int j,flag=0; for(j=0;j<5;j++) if( strcmp(student[j].na , "Wang")= =0) { flag=1; printf("%-10s%-10d\n",student[j].na,student[j].s); } if(flag==0) printf("NO"); }
10.4 typedef 语句 1.typedef语句的一般格式为: typedef 已有类型名新类型名; 2. 作用:用新类型名代替已有类型名。 • 新类型名为用户标识符。而已有类型名可以是:基本数据类型名、指针、结构体、共用体、枚举类型。 3.举例 例I 定义基本类型名为新类型名。如: typedef float REAL; 则此后可以使用REAL代替floa。 即:REAL a,b; 等价于 float a,b;
10.4 typedef 语句 3.举例 例II 将已经定义的结构体类型的标识符重新定义为新类型名。 如: struct data { int year; int month; int day; }; typedef struct data DATA; 则此后语句:DATA d; 等价于 struct data d;
10.4 typedef 语句 3.举例 例III 将结构体类型直接定义为新类型名。 如: typedef struct data { int year; int month; int day; } DATA; 则可以使用新类型名定义变量:DATA d;
10.4 typedef 语句 4. 对 typedef 语句的说明: ① typedef只是为现有的类型提供了一个易于使用、可识别的别名,它并没有创建一种新的类型。 ② typedef的作用域取决于typedef语句所在的位置。与变量作用域类似。 5. 思考讨论 设有如下说明typedef struct ST { long a; int b; char c[2]; } NEW;则下面叙述中正确的是____________。A)以上的说明形式非法 B)ST是一个结构体类型C)NEW是一个结构体类型 D)NEW是一个结构体变量
v.ch v.i 10.5 共用体 1.共用体数据类型的概念: 将不同类型的数据项存放于同一段内存单元的一种构造数据类型。 2. 用途: 使几个不同类型的变量共占一段内存(相互覆盖)。 共用体变量任何时刻 只有一个成员存在 3.举例 union intchar { int i; char ch[3]; }v,*pv;
10.6 枚举 1.枚举数据类型的概念: 所谓“枚举”是指将变量的所有取值一一列出,变量的值只在列举出来的值的范围内。 2. 枚举类型和枚举变量的定义: enum weekday {sun,mon,tue,wed,thu,fri,sat}; enum weekdayworkday;
10.7 位运算 1.位运算和指针一样,都是C语言的重要特色。 2.位运算的概念: 所谓位运算,是指进行二进制位的运算。 例如:将一个存储单元中的各二进制位左移或右移1位,两个数按位相加等。 3. 位运算有: • “按位与” 运算 • “按位或” 运算 • “异或” 运算 • “取反” 运算 • 左移运算 • 右移运算
10.7 位运算 4.位赋值运算符 位赋值运算符是位运算符与赋值运算符的结合。 5. 位段
10.7 位运算 6.应用举例 例输出一个整数的二进制形式。 程序: main( ) { int num,bit,i; unsigned test=0x8000; printf("input mum:"); scanf("%d",&num); printf("binary of %x is: ",num); for(i=1;i<=16;i++) { bit=((num&test)==0)?0:1; printf("%d",bit); test>>=1; } } 运行结果: input num:12345↙ binary of 3039 is: 0011000000111001
小 结 • 结构体类型的定义、变量的定义、变量的初始化、结构体数组 • typedef语句格式、使用 • 共用体的概念 • 枚举的概念 • 位运算的概念