35
1 第 10 第 第第 第第第 体、 结结 typedef 结结 结结 结结 结结结

第10章 结构体、位运算

Embed Size (px)

DESCRIPTION

第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 位学生的考试成绩,如下:. - PowerPoint PPT Presentation

Citation preview

1

第 10章 结构体、位运算 结构体 typedef 语句 共用体 枚举 位运算

2

例如:期末考试结束,已知 5 位学生的考试成绩,如下:

编写程序,要求:计算出每位学生的总成绩,并按总分由高到低输出一张成绩单,格式如下:Rank name C Language English maths Computer Sum 1 **** ** ** ** ** *** 2 **** ** ** ** ** *** 3 **** ** ** ** ** *** 4 **** ** ** ** ** *** 5 **** ** ** ** ** *** •解决的办法 : 将一位学生的数据作为结构体类型

分析 : char na[5][10]={…}; int score[5][4]={{…},…}; int s[5] ; /* 每个同学的总分 */

10.0 结构体导入 为什么要使用结构体?

姓名 C 语言 英语 高数 计算机Jiang Jun 86 90 78 68

Wang Hong 62 65 80 70Li Sijia 65 76 92 75

Chang Mi 79 80 60 67Li Weiwei 95 85 73 88

3

1. 什么是结构体类型? 将一组不同类型的数据组织在一起形成的一种新的数据类型。

2. 结构体类型的定义例 1 : struct s_type { char num[15]; char name[20]; int score[4]; int s; };

• 定义语句的格式:struct 结构体名 { 数据类型 1 成员名 1 ; 数据类型 2 成员 2 名; …; 数据类型 n 成员名 n; };

• 结构体名、成员名:用户标识符• 结构体类型的标识符: struct 结构体名• 结构体类型的作用域 :类似于变量的作用域

10.1 结构体类型的定义

4

1. 结构体变量的定义:有 3 种方法

① 先定义结构体类型,再定义结构体变量

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; }; main() { struct s_type student1,student2; …. }

10.2 结构体变量

5

② 在定义结构体类型的同时,定义结构体变量

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student; main() { struct s_type student1,student2; …. }

1. 结构体变量的定义:有 3 种方法

10.2 结构体变量

6

③ 直接定义结构体变量

例如: struct

{ char num[15]; char name[20]; int score[4]; int s; } student; main() { …. }

1. 结构体变量的定义:有 3 种方法

10.2 结构体变量

7

•表达式: sizeof(student) 或 sizeof(struct s_type) 的值为 :45

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student;

• 结构体变量成员的表示:结构体变量名 . 成员名

2. 结构体变量需要的内存 等于结构体变量所有成员占内存之和

10.2 结构体变量

8

•结构体变量 student 及其各个成员占用内存的情况见下图:

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student;

注意:•结构体变量成员表示的含义: 内存地址?存储单元?

student.num

student.name

student.score

student.s

student

•系统为结构体变量分配内存 , 但不会为结构体类型分配内存。

10.2 结构体变量

9

例如:

struct s_type { char num[15]; char name[20]; int score[4]; int s; } student={"2007101010", "wang",{89,90,87,80},0};

2007101010

student.num

wangstudent.name

89 90 87 80student.score

0student.s

student

10.2 结构体变量 3. 结构体变量的初始化:为结构体变量的成员赋初值

10

例如: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. 结构体变量的使用

11

例如:

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. 结构体变量的使用

12

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } student;

③ 只能对结构体变量中的各个成员分别输入或输出或进行其它操作

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);}

10.2 结构体变量 4. 结构体变量的使用

13

例如: 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 结构体变量 5. 结构体成员的数据类型:可以是任意类型

14

例:定义一个结构体变量来表示一个日期(年月日),编程实现:根据输入的日期确定该日在本年中是第几天。

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 结构体变量 6. 结构体变量应用举例

15

在定义一个结构体变量时系统分配给它的存储空间是 ( )

A) 该结构体变量中第一个成员所需存储空间

B) 该结构体变量中最后一个成员所需存储空间

C) 该结构体变量中所有成员所需存储空间的总和

D) 结构体变量本身并不占用存储空间,即系统并不给结构体变量分配存储空间

10.2 结构体变量 5. 思考讨论

16

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; }; main() { struct s_type stu[3]; …. }

1. 结构体数组的定义:有 3 种方法,与结构体变量类似

①先定义结构体类型,再定义结构体数组

10.3 结构体数组

17

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3]; main() { struct s_type student; …. }

③ 直接定义结构体数组

1. 结构体数组的定义:有 3 种方法,与结构体变量类似

② 在定义结构体类型的同时定义结构体数组

10.3 结构体数组

18

• 表达式: sizeof(struct s_type) 的值为: 45

sizeof(stu) 的值: 135

例如: struct s_type { char num[15]; char name[20]; int score[4]; int s; } stu[3];

2. 结构体数组需要的内存 等于结构体数组所有元素占内存之和

10.3 结构体数组

19

例如:

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} } ;

3. 结构体数组的初始化:将一组结构体数据存储在结构体数组的过程

10.3 结构体数组

20

结构体数组元素类似于一个结构体变量• 只能对结构体数组元素的成员进行输入、输出或其它基本操作

例如:

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} } ;

main(){ int i; for(i=0;i<3;i++) for(j=0;j<4;j++) stu[i].s+=stu[i].score[j]; …. }

4. 结构体数组元素的使用10.3 结构体数组

21

#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(); /* 跳过多余的回车键 */ } ……;}

例 I :某班有 38 名学生,期末考试结束,已知每位学生的成绩单包括:学号、姓名、 4 门课的成绩,要求写程序实现:求出每个学生的总分,并按总分由高到低的顺序输出全班学生的成绩单。格式如下: 名次 学号 姓名 C 语言 高数 …… 总分 1 ***

5. 结构体数组应用举例10.3 结构体数组

#define N 5struct s_type { char num[15]; char name[20]; int score[4]; int s;} stu[N];

/* 按总分由高到低排序 */ 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; }

……;

}

/* 按格式输出 */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"); }}

22

例 II :候选人得票统计程序。设有 5 个候选人,每次输入一个得票候 选人的名字,最后输出每个人得票结果。

5. 结构体数组应用举例10.3 结构体数组

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); }

23

第 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. 思考讨论

24

第 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.3 结构体数组 6. 思考讨论

25

3. 举例例 I 定义基本类型名为新类型名。如: typedef float REAL; 则此后可以使用 REAL 代替 floa 。 即: REAL a,b; 等价于 float a,b;

2. 作用:用新类型名代替已有类型名。

•新类型名为用户标识符。而已有类型名可以是:基本数据类型名、指针、结构体、共用体、枚举类型。

10.4 typedef 语句 1. typedef 语句的一般格式为:

typedef 已有类型名 新类型名;

26

10.4 typedef 语句3. 举例例 II 将已经定义的结构体类型的标识符重新定义为新类型名。如: struct data { int year; int month; int day; }; typedef struct data DATA; 则此后语句: DATA d; 等价于 struct data d;

27

3. 举例例 III 将结构体类型直接定义为新类型名。如: typedef struct data { int year;

int month;

int day;

} DATA;

则可以使用新类型名定义变量: DATA d;

10.4 typedef 语句

28

4. 对 typedef 语句的说明: ① typedef 只是为现有的类型提供了一个易于使用、

可识别的别名,它并没有创建一种新的类型。 ② typedef 的作用域取决于 typedef 语句所在的位置。

与变量作用域类似。

10.4 typedef 语句

5. 思考讨论设有如下说明 typedef  struct  ST { long a;   int  b;   char  c[2]; } NEW; 则下面叙述中正确的是 ____________ 。 A )以上的说明形式非法 B ) ST 是一个结构体类型 C ) NEW 是一个结构体类型 D ) NEW 是一个结构体变量

29

3. 举例union intchar{ int i; char ch[3]; }v,*pv;

2. 用途:

使几个不同类型的变量共占一段内存 ( 相互覆盖 ) 。

10.5 共用体 1. 共用体数据类型的概念: 将不同类型的数据项存放于同一段内存单元的一种构造数据类型。

v.ch

v.i

共用体变量任何时刻只有一个成员存在

30

2. 枚举类型和枚举变量的定义 :

enum weekday {sun,mon,tue,wed,thu,fri,sat};

enum weekday workday;

10.6 枚举 1. 枚举数据类型的概念: 所谓“枚举”是指将变量的所有取值一一列出,变量的值只在列举出来的值的范围内。

31

3. 位运算有:• “ 按位与” 运算• “ 按位或” 运算• “异或” 运算• “取反” 运算• 左移运算• 右移运算

10.7 位运算 1. 位运算和指针一样,都是 C 语言的重要特色。

2. 位运算的概念: 所谓位运算,是指进行二进制位的运算。 例如:将一个存储单元中的各二进制位左移或右移 1 位,两个数按位相加等。

位运算符 含义 举例& 按位与 a&b

| 按位或 a|b

∧ 按位异或 a b∧

~ 按位取反 ~a

<< 左移 a<<1

>> 右移 b>>2

32

10.7 位运算 4. 位赋值运算符 位赋值运算符是位运算符与赋值运算符的结合。

位赋值运算符 含义 举例 等同于&= 位与赋值 a&=b a=a&b

|= 位或赋值 a|=b a=a|b

∧ = 位异或赋值 a =b∧ a=a b∧

<<= 左移赋值 a<<=b a=a<<b

>>= 右移赋值 a>>=b a=a>>b

5. 位段

33

10.7 位运算

程序: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

例 输出一个整数的二进制形式。 6. 应用举例

34

小 结

结构体类型的定义、变量的定义、变量的初始化、结构体数组

typedef 语句格式、使用

共用体的概念

枚举的概念

位运算的概念

35

作业和上机实验