第7章 构造数据类型 构造数据类型:数组、结构体、共用体、用户自定义类型 7.1 数组

Slides:



Advertisements
Similar presentations
只怕有心人只怕有心人 世上无难事世上无难事 浙江长征职业技术学院 — 计算机与信息技术系 — 相方莉制作.
Advertisements

电子成绩单项目实现.
第10章 结构体与链表 本章要点: 结构体类型与结构体变量的定义 结构体变量的引用与初始化 结构体数组 链表处理 共用体类型和枚举类型
C程序设计 第6章 数 组 主讲教师: 鲁 萍 西安建筑科技大学 理学院 任务:键盘输入整数,排序.
二级指针与二维数组.
第6章 数组 公共计算机基础教研部.
一维数组 乾坤以有亲可久; 君子以厚德载物。.
C语言程序设计.
大学实用教程 C语言.
6.4 字符串与指针 1. 用字符数组存放一个字符串.
程序设计基础 杨圣洪 ( since ) 群号: QQ:
字符串与二维数组.
第九章 系 统 安 全 性 9.1 结构体 9.2 结构体型数组  9.3 结构体型指针 9.4 内存的动态分配 9.5 共用体
第六章 数 组 主讲教师 贾月乐 联系电话:
C程序设计 第9章 自定义数据类型 主讲教师: 鲁 萍 西安建筑科技大学 理学院.
第九章 结构体 主讲教师 :贾月乐 电话:
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第9章 结构体.
C语言高级编程(第四部分) 字符串 北京大学 信息科学技术学院.
结构体和共用体 2 梁春燕 华电信息管理教研室.
Introduction to the C Programming Language
Introduction to the C Programming Language
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数.
自定义数据类型 潘荣江 山东大学计算机科学与技术学院
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
第九章 结构体和共用体 结构体的定义 结构体的使用 共用体的定义 共用体的使用 主讲:李祥 时间:2015年10月.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
第6章 利用数组处理批量数据.
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
C语言程序设计 李祥.
第7讲 结构体与共用体 7.1 结构体 7.2 共用体.
主要内容: ◆ 一维数组 ◆二维数组 ◆ 字符数组
第六单元 应用数组的程序设计 从现在开始,将详细讲述C语言的方方面面。第一章中的所有疑惑,都将一一消灭。
第11章 结构体和共用体.
第6章 数 组 本章要点: 数组的定义、初始化、数组元素的引用 字符数组的输入输出 字符串处理函数 数组的应用 学习方法建议:
第13章 结构体的应用 13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组
第四章 数组 4.4.1一维数组的定义和初始化 一、一维数组的定义和初始化 1.一维数组定义 定义格式:类型 数组名[常量表达式];
第五章 习题课 电子信息与计算机科学系 曾庆尚.
数组 梁春燕 华电信息管理教研室.
第六章 数组 西安工程大学.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言复习3----结构体.
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
第十章 结构体与链表 西安工程大学.
C语言概述 第一章.
第七章 数组.
浙江长征职业技术学院—计算机与信息技术系—相方莉制作
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第4章 数组 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
第 二 章 数据类型、运算符与表达式.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
第六章 数组.
C语言的特点 1. C程序由许多函数组成 2. C程序必须有且只有一个主函数main( ) 3. 函数用“{”和“}”表示起点和终点
C语言程序设计 第一章 数据类型, 运算符与表达式 第二章 顺序程序设计 第三章 选择结构程序设计 第四章 循环控制 第五章 数组.
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第6章 数组.
第4章 Excel电子表格制作软件 4.4 函数(一).
C程序设计.
第九节 赋值运算符和赋值表达式.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
2.6 字符型数据 一、 字符常量 1、字符常量的定义 用一对单引号括起来的单个字符,称为字符常量。 例如,‘A’、‘1’、‘+’等。
结构体与共用体 结构体 结构体是一种构造数据类型 用途:把不同类型的数据组合成一个整体 自定义数据类型 结构体类型定义
本节内容 结构体.
基本知识 数据类型、变量、常量、运算符.
第14讲 结构体和共用体 计算机与通信工程学院.
C++语言程序设计 C++语言程序设计 第四章 数组及自定义数据类型 C++语言程序设计.
台大資訊工程學系 資料系統訓練班 第119期 吳晉賢
安排座位.
Presentation transcript:

第7章 构造数据类型 构造数据类型:数组、结构体、共用体、用户自定义类型 7.1 数组 第7章 构造数据类型 构造数据类型:数组、结构体、共用体、用户自定义类型 7.1 数组 一组同类型的若干个(已知个数)多个相关变量的数据集合。 在内存中存放在地址连续的存储单元。

一个例子:对三个任意整数从小到大排序。 main() {int a,b,c; scanf(“%d,%d,%d”,&a,&b,&c); if(a>b){t=a;a=b;b=t;} if(a>c) {t=a;a=c;c=t;} if(b>c) {t=b;b=c;b=t;} printf(“%a,%b,%c\n); } 思考:若是10个数、100个数、1000个数…n个数排序又如何? 我们需要通过循环来访问到每个变量,数组能满足这一要求。

定义方式: 数据类型 数组名[常量表达式]; 7.1.1 一维数组的定义 定义方式: 数据类型 数组名[常量表达式]; 例 int a[6]; 合法标识符 [ ] :数组运算符 单目运算符 优先级(1) 左结合 不能用( ) 表示元素个数 下标从0开始 a[0] 1 4 5 a[1] a[2] a[3] a[4] a[5] 2 3 a 编译时分配连续内存 内存字节数=数组维数* sizeof(元素数据类型) 数组名表示内存首地址, 是地址常量

一维数组的引用 例 int i=15; 例 int data[5]; int data[i]; (不能用变量定义数组维数) data[5]=10; //C语言对数组不作越界检查,使用时要 注意 一维数组的引用 数组必须先定义,后使用 只能逐个引用数组元素,不能一次引用整个数组 数组元素表示形式: 数组名[下标] 其中:下标可以是常量或整型表达式 例 int a[10]; printf(“%d”,a); () 必须 for(j=0;j<10;j++) printf(“%d\t”,a[j]); ()

等价于:a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5; 一维数组的初始化 初始化方式   int a[5]={1,2,3,4,5}; 等价于:a[0]=1; a[1]=2; a[2]=3; a[3]=4; a[4]=5; 在定义数组时,为数组元素赋初值 (在编译阶段使之得到初值) 说明: 数组不初始化,其元素值为随机数 对static数组元素不赋初值,系统会自动赋以0值 只给部分数组元素赋初值 当全部数组元素赋初值时,可不指定数组长度 如 int a[5]={6,2,3}; 等价于: a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0; 如 int a[3]={6,2,3,5,1}; () static int a[5]; 等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0; int a[]={1,2,3,4,5,6}; 编译系统根据初值个数确定数组维数

程序举例 #include <stdio.h> #define SIZE 10 main() { int x[SIZE],i,max,min; printf("Enter 10 integers:\n"); for(i=0;i<SIZE;i++) { printf("%d:",i+1); scanf("%d",&x[i]); } max=min=x[0]; for(i=1;i<SIZE;i++) { if(max<x[i]) max=x[i]; if(min>x[i]) min=x[i]; printf("Maximum value is %d\n",max); printf("Minimum value is %d\n",min); 例 读10个整数存入数组,找出其中最大值和最小值 步骤: 1. 输入:for循环输入10个整数 2. 处理: (a) 先令max=min=x[0] (b) 依次用x[i]和max,min比较(循环) 若max<x[i],令max=x[i] 若min>x[i],令min=x[i] 3. 输出:max和min

#include <stdio.h> main() { int i; int f[20]={1,1}; 例 用数组求Fibonacci数列前20个数 f[0] f[1] f[2] f[3] f[4] f[5] f[19] ……... 1 4 5 2 3 19 #include <stdio.h> main() { int i; int f[20]={1,1}; for(i=2;i<20;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) { if(i%5==0) printf("\n"); printf("%12d",f[i]); } 2 3 5

例 用冒泡法对10个数排序 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然 例 用冒泡法对10个数排序 排序过程: (1)比较第一个数与第二个数,若为逆序a[0]>a[1],则交换;然 后比较第二个数与第三个数;依次类推,直至第n-1个数和第 n个数比较为止——第一趟冒泡排序,结果最大的数被安置在 最后一个元素位置上 (2)对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在 第n-1个元素位置 (3)重复上述过程,共经过n-1趟冒泡排序后,排序结束

38 例 49 38 65 97 76 13 27 30 初始关键字 n=8 38 49 65 76 13 27 30 97 第一趟 38 49 65 13 27 30 76 第二趟 38 49 13 27 30 65 第三趟 38 13 27 30 49 第四趟 13 13 27 30 38 第五趟 13 27 30 第六趟 13 27 第七趟 49 13 27 38 13 38 49 27 30 76 65 13 27 49 30 38 13 97 49 76 27 65 30 97 27 76 30 65 76 30 97 97

#include <stdio.h> main() { int a[11],i,j,t; printf("Input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); printf("\n"); for(j=1;j<=9;j++) for(i=1;i<=10-j;i++) if(a[i]>a[i+1]) {t=a[i]; a[i]=a[i+1]; a[i+1]=t;} printf("The sorted numbers:\n"); printf("%d ",a[i]); } 输入n 个数给a[1] 到 a[n] for j=1 to n-1 for i=1 to n-j a[i]>a[i+1] 真 假 a[i]a[i+1] 输出a[1] 到 a[n]

例 用简单选择法对10个数排序 排序过程: (1)首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数 例 用简单选择法对10个数排序 排序过程: (1)首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数 交换—第一趟选择排序,结果最小的数被安置在第一个元素位置上 (2)再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录, 将它与第二个数交换—第二趟选择排序 (3)重复上述过程,共经过n-1趟排序后,排序结束

k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j j j j j k k i=2 一趟: 13 [38 65 97 76 49 27 ] 27 38 j j j j j 二趟: 13 27 [65 97 76 49 38 ] 三趟: 13 27 38 [97 76 49 65 ] 四趟: 13 27 38 49 [76 97 65 ] 五趟: 13 27 38 49 65 [97 76 ] 六趟: 13 27 38 49 65 76 [97 ]

#include <stdio.h> main() { int a[11],i,j,k,x; printf("Input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); printf("\n"); for(i=1;i<10;i++) { k=i; for(j=i+1;j<=10;j++) if(a[j]<a[k]) k=j; if(i!=k) { x=a[i]; a[i]=a[k]; a[k]=x;} } printf("The sorted numbers:\n"); printf("%d ",a[i]); 输入n 个数给a[1] 到 a[n] for i=1 to n-1 for j=i+1 to n a[j]<a[k] 真 假 k=j 输出a[1] 到 a[n] k=i a[i]a[k] i != k

{ int a[N],b[‘B’-60],c[]={1,2,3,4,5,6},i; for(i=0;i<N;i++) #define N 6 main() { int a[N],b[‘B’-60],c[]={1,2,3,4,5,6},i; for(i=0;i<N;i++) scanf(“%d%d”,&a[i],&b[i]); printf(“%d ”,a[i]); printf(“\n”); printf(“%d ”,b[i]); c[i]=a[i]+b[N-i-1]; printf(“%d ”,c[i]); } 数组定义:必须用常量表达式 数组元素引用

7.1.2 二维数组及多维数组 1、二维数组的定义 2、二维数组的初始化 3、二维数组元素的初始化 4、应用举例

1、二维数组的定义 定义方式: 数据类型 数组名[常量表达式][常量表达式]; 数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 int c[2][3][4] 1 2 3 4 5 6 7 ………... 20 21 22 23 c[0][0][0] c[0][0][1] c[0][0][2] c[0][0][3] c[0][1][0] c[0][1][1] c[0][1][2] c[0][1][3] c[0][2][0] c[0][2][1] c[0][2][2] c[0][2][3] c[1][0][0] c[1][0][1] c[1][0][2] c[1][0][3] c[1][1][0] c[1][1][1] c[1][1][2] c[1][1][3] c[1][2][0] c[1][2][1] c[1][2][2] c[1][2][3] 1、二维数组的定义 定义方式:   数据类型 数组名[常量表达式][常量表达式]; 元素个数=行数*列数 列数 行数 数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 多维数组:最右下标变化最快 例 int a[3][4]; float b[2][5]; int c[2][3][4]; int a[3,4]; () int a[3][2] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] 1 4 5 2 3 a[0][0] a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1]

二维数组理解 a[0] 例 int a[3][4]; a[1] a[2] 1 4 5 2 3 a[0][1] a[0][2] a[0][3] 1 4 5 2 3 a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[0][0] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] a[1][2] 6 7 10 11 8 9 a[0] a[1] a[2] 二维数组a是由3个元素组成 例 int a[3][4]; 2016 17 2018 19 2020 21 2022 23 2008 9 2010 11 2012 13 2014 15 2000 1 2002 3 2004 5 20006 7 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] a[0] a[1] a[2] 行名 每个元素a[i]由包含4个元素 的一维数组组成

2、二维数组元素的初始化 分行初始化: 例 int a[2][3]={{1,2,3},{4,5,6}}; a[0][0] a[0][1] 全部初始化 例 int a[2][3]={{1,2},{4}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 例 int a[][3]={{1},{4,5}}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 4 5 第一维长度省略初始化 例 int a[2][3]={1,2,4}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 4 部分初始化 按元素排列顺序初始化 例 int a[2][3]={1,2,3,4,5,6}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 6 全部初始化 例 int a[][3]={1,2,3,4,5}; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 1 2 3 4 5 第一维长度省略初始化

h e l l o \0 h e l l o 例 char name[0]; float weight[10.3]; int array[-100]; 例 char str[]=“Hello”; char str[]={‘H’,‘e’,‘l’,‘l’,‘o’}; h e l l o 2 3 1 4 h e l l o \0 5 例 int a[10]; float i=3; a[i]=10; 例 int a[5]; a={2,4,6,8,10}; 例 int a[][10]; float f[2][]={1.2 ,2.2}; 5 6 0 7 8 0 5 6 7 8 0 0 例 比较 int a[2][3]={{5,6},{7,8}}; 与 int a[2][3]={5,6,7,8};

二维数组的访问也是通过访问其元素来实现的。二维数组的引用方式为: 数组名[下标表达式][下标表达式] 几点注意: 3、二维数组元素的引用 二维数组的访问也是通过访问其元素来实现的。二维数组的引用方式为: 数组名[下标表达式][下标表达式] 几点注意: ① 二维数组的下标表达式的范围和一维数组类似,可以是整型的变量、常量、表达式。第一维下标的范围是0、1、2……第一维长度-1; 第二维下标范围是0、1、2……第二维长度-1。 在引用每一个数组元素时下标表达式的值不能越界! ② 虽然二维数组是特殊的一维数组,是元素为一维数组的一维数组,但并不能引用数组的行或列,只能引用单个是数组元素。 ③ 二维数组元素的表示方式不能写为如b[1,2]、b[2],[0]、b(1,2)、b(3)(1)的形式,而且两个下标之间也不能有空格。

4、程序举例 例 将二维数组行列元素互换,存到另一个数组中 #include <stdio.h> main() 例 将二维数组行列元素互换,存到另一个数组中 #include <stdio.h> main() { int a[2][3]={{1,2,3},{4,5,6}}; int b[3][2],i,j; printf("array a:\n"); for(i=0;i<=1;i++) { for(j=0;j<=2;j++) { printf("%5d",a[i][j]); b[j][i]=a[i][j]; } printf("\n"); printf("array b:\n"); for(i=0;i<=2;i++) { for(j=0;j<=1;j++) printf("%5d",b[i][j]); a= 1 2 3 4 5 6 b= 1 4 2 5 3 6

#include <stdio.h> main() { int a[3][4]={{1,2,3,4}, {9,8,7,6}, {-10,10,-5,2}}; int i,j,row=0,colum=0,max; max=a[0][0]; for(i=0;i<=2;i++) for(j=0;j<=3;j++) if(a[i][j]>max) { max=a[i][j]; row=i; colum=j; } printf("max=%d,row=%d, \ colum=%d\n",max,row,colum); 例 求二维数组中最大元素值及其行列号 max=a[0][0] for i=0 to 2 for j=0 to 3 a[i][j]>max 真 假 max=a[i][j] row=i colum=j 输出:max和row,colum

例 读入下表中值到数组,分别求各行、各列及表中所有数之和 #include <stdio.h> main() 例 读入下表中值到数组,分别求各行、各列及表中所有数之和 #include <stdio.h> main() { int x[5][4],i,j; for(i=0;i<4;i++) for(j=0;j<3;j++) scanf("%d",&x[i][j]); for(i=0;i<3;i++) x[4][i]=0; for(j=0;j<5;j++) x[j][3]=0; { x[i][3]+=x[i][j]; x[4][j]+=x[i][j]; x[4][3]+=x[i][j]; } 12 4 6 15 7 9 8 23 3 2 5 17 12 4 6 22 15 7 9 31 8 23 3 34 2 5 17 24 37 39 35 111 for(i=0;i<5;i++) { for(j=0;j<4;j++) printf("%5d\t",x[i][j]); printf("\n"); }

{int a[M][N]; int i,j,k,m; int flag=0; #define M 5 #define N 4 main() {int a[M][N]; int i,j,k,m; int flag=0; printf("please input array:\n"); for(i=0;i<M;i++) for(j=0;j<N;j++) scanf("%d",&a[i][j]); { m=0; for(j=2;j<N;j++) if (a[i][j]<a[i][m]) m=j; for(k=0;k<M;k++) if(a[k][m]>a[i][m]) break; 【例7.4】编程序查找一个矩阵中的鞍点,并输出。 32 30 56 49 15 7 9 31 8 23 3 34 2 5 17 24 37 19 35 111 if (k>=M) { flag=1; printf("\n%d,%d,%d", i,m,a[i][m]); } }/*for i*/ if(flag==0)printf("\nnone. "); }/*main*/

#include <stdio.h> main() { int k , a[10]; for(k=0;k<10;k++) 例 有十个学生的成绩,求平均分 92 85 68 75 54 88 98 45 61 79 a a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 92 85 68 54 88 98 45 75 61 79 #include <stdio.h> main() { int k , a[10]; for(k=0;k<10;k++) scanf(“%d”,&a[k]); sum+=a[k]; printf(“Average is %d\n”,sum/10); }

求每人的平均成绩,并安平均成绩从大到小排序, 按排序结果输出。 例 有 M 个学生,每个学生 N 门课成绩, 求每人的平均成绩,并安平均成绩从大到小排序, 按排序结果输出。 如原始数据为: 输出数据格式为: 62 75 68 75 54 88 98 45 91 79 81 70 1 2 3 数学 化学 英语 物理 91 79 81 70 80.25 54 88 98 45 71.25 62 75 68 75 70.0 3 2 1 数学 化学 英语 物理

7.1.3 字符数组和字符串 1.字符数组的定义和使用 2.字符串和字符数组 3.常用字符串处理函数 4.字符数组应用举例

字符数组就是数据类型为“char”的数组 。 1、字符数组的定义和使用 字符数组就是数据类型为“char”的数组 。 定义 例 char ch[5]={‘B’,’o’,’y’}; ch[0] B o y \0 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char c[10], ch[3][4]; 例 char ch[5]=“Boy”; ch[0] B o y \0 字符串常量赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[]={‘H’,’e’,’l’,’l’,’o’}; ch[0] H e l o 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[]=“Hello”; ch[0] H e l o 字符串常量赋值 ch[1] ch[2] ch[3] ch[4] 字符数组的初始化 和前面所讲的数组相同,逐个字符赋值 用字符串常量

字符数组的引用: 【例7.5】从键盘输入一行字符,存放在字符数组中,然后 逆序输出。 main() {char a[80],c; int k=0,j; printf("\nplease input the chars: "); scanf("%c",&c); while(c!= '\n') /*输入字符序列输入字符为回车时结束*/ {a[k++]=c; } printf("\n"); for(j=k-1;j>=0;j--) /*逆序输出字符序列*/ printf("%c",a[j]);

2.字符串和字符数组 字符串是作为一个整体对待的字符序列。在C语言中, 没有字符串这种数据类型,因此可以将字符串存放在字符数组 中。这是处理字符串的方法之一。 在用字符数组存放字符串时,字符数组必须预先设定足够的长,在足够长的情况下我们一般并不关心数组的具体长度,而是关心有效字符的长度。 对于字符串,并不显式的保存它的长度,而是用字符串结束标志来表示字符串到此结束,隐含着字符串的长度,字符串结束标志也就是前面所介绍的空字符'\0'。 没有‘\0’,不能作为字符串用! 例 char ch[5]={‘H’,’e’,’l’,’l’,’o’}; ch[0] H e l o 逐个字符赋值 ch[1] ch[2] ch[3] ch[4] 例 char ch[6]={“Hello”}; char ch[6]=“Hello”; char ch[]=“Hello”; 用字符串常量 ch[0] H e l o ch[1] ch[2] ch[3] ch[4] \0 ch[5] 例 char ch[5]=“Boy”; ch[0] B o y \0 用字符串常量 ch[1] ch[2] ch[3] ch[4]

不但用字符数组存放字符串采用‘\0’表示字符串的结束, 对于字符串常量,也采用字符串结束标志‘\0’来作为结束符。 编译系统在处理字符串时会自动的在字符串的最后一个字符 之后加上‘\0’,也就是说,对于含有n个字符的字符串在内存 中占n+1个字节的空间,因为需要用一个字节来存放字符串结 束标志'\0'。 请注意区分字符常量和字符串常量:字符常量是用单引号引起来的单个字符,字符串常量是用双引号引起来的字符序列,当然,字符序列可以为空,也可以是一个字符。

① ""表示空串,在内存中保存的是空字符'\0',占一个字节。 ② "A"表示含有一个大写字母A的字符串,在内存中保存的是字母A和空字符'\0',占两个字节。 ③ 'A'表示字母A,在内存中占一个字节。 ④ "ABCDEF"表示含有6个字母的字符串,在内存中占7个字节。 需要注意的是:处理字符串常量的时候,字符串结束标志是编译系统自动添加的,不用人为的在字符串最后加上‘\0’ 。

h e l l o \0 h e l l o 例 char name[0]; float weight[10.3]; int array[-100]; 例 char str[]=“Hello”; char str[]={‘H’,‘e’,‘l’,‘l’,‘o’}; h e l l o 2 3 1 4 h e l l o \0 5 例 int a[10]; float i=3; a[i]=10; 例 int a[5]; a={2,4,6,8,10}; 例 int a[][10]; float f[2][]={1.2 ,2.2}; 5 6 0 7 8 0 5 6 7 8 0 0 例 比较 int a[2][3]={{5,6},{7,8}}; 与 int a[2][3]={5,6,7,8};

例 char diamond[][5]={{'.', '.','*'},{'.','*','.','*'}, {'*', '.', '.', '.' ,'*'},{'.','*', '.','*'},{'.', '.','*'}}; 二维字符数组初始化 . * \0 diamond[0] diamond[1] diamond[2] diamond[3] diamond[4] 例 char fruit[][7]={“Apple”,”Orange”, ”Grape”,”Pear”,”Peach”}; 二维字符数组初始化 fruit[0] fruit[1] fruit[2] fruit[3] fruit[4] A p l e \0 O r a n g G P c h

#include <stdio.h> main() 例 输出一个字符串 I a m b o y 1 2 3 4 5 6 7 8 9 #include <stdio.h> main() { char c[10]={'I',' ','a','m',' ','a',' ','b','o','y'}; int i; for(i=0;i<10;i++) printf("%c",c[i]); printf("\n"); }

h e l l o \0 字符串 字符串及其结束标志 无字符串变量,用字符数组处理字符串 字符串结束标志:‘\0’ 104 101 108 108 111 0 内存存放字符ASCII码

字符串的输入输出 逐个字符I/O: %c 整个字符串I/O: %s 例 用%c main() { char str[5]; int i; 用字符数组名,不要加& 输入串长度<数组维数 遇空格或回车结束 自动加‘\0’ 例 用%c main() { char str[5]; int i; for(i=0;i<5;i++) scanf(“%c”, &str[i]); printf(“%c”, str[i]); } 例 用%s main() { char str[5]; scanf(“%s”, str); printf(“%s”, str); } 用字符数组名, 遇‘\0’结束

h e l l o 例 main( ) { char a[5]={‘H’,’e’,’l’,’l’,’o’}; printf(“%s”,a); 2 3 1 4 结果:Hello#-=* 用“%s”输出时,遇‘\0’结束 例 main( ) { char a[ ]=“Hello”; printf(“%s”,a); } 结果:Hello

main() { char a[]={'h','e','l','\0','l','o','\0'}; printf("%s",a); } 例 main() { char a[]={'h','e','l','\0','l','o','\0'}; printf("%s",a); } 输出:hel h e l \0 l o \0 数组中有多个‘\0’时, 遇第一个结束

main() { int i; char a[5]; scanf("%s",a); for(i=0;i<5;i++) printf("%d,",a[i]); } 输入字符串长度<数组维数 h e l \0 h e l l \0 h e l l o 运行情况: (1)若输入 hel , 正常 (2)若输入 hell , 正常 (3)若输入 hello , 用%s 输出时,会出现问题

#include <stdio.h> main() { char a[15],b[5],c[5]; 运行情况: 输入:How are you? 输出:a=How b=are c=you? 例 字符串输入举例 #include <stdio.h> main() { char a[15],b[5],c[5]; scanf("%s%s%s",a,b,c); printf("a=%s\nb=%s\nc=%s\n",a,b,c); scanf("%s",a); printf("a=%s\n",a); } scanf中%s输入时,遇空格或回车结束 运行情况: 输入:How are you? H o w \0 a r e \0 y o u ? \0

例 若准备将字符串“This is a string.”记录下来, 错误的输入语句为: (A)scanf(“%20s”,s); (B)for(k=0;k<17;k++) s[k]=getchar(); (C)while((c=getchar())!=‘\n’) s[k++]=c;

例 #include <stdio.h> main( ) { char string[80]; 3.常用字符串处理函数 包含在头文件 string.h 例 #include <stdio.h> main( ) { char string[80]; printf(“Input a string:”); gets(string); puts(string); } 输入: How are you? 输出: How are you ? 字符串输出函数puts 格式:puts(字符数组) 功能:向显示器输出字符串(输出完,换行) 说明:字符数组必须以‘\0’结束 字符串输入函数gets 格式:gets(字符数组) 功能:从键盘输入一以回车结束的字符串放入字符数组中, 并自动加‘\0’ 说明:输入串长度应小于字符数组维数

例 char str1[20],str2[20]; str1={“Hello!”}; () str2=str1; () 字符串连接函数strcat 格式:strcat(字符数组1,字符数组2) 功能:把字符数组2连到字符数组1后面 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消, 新串最后加‘\0’ 例 char str1[20],str2[20]; str1={“Hello!”}; () str2=str1; () 字符串拷贝函数strcpy 格式:strcpy(字符数组1,字符串2) 功能:将字符串2,拷贝到字符数组1中去 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 拷贝时‘\0’一同拷贝 不能使用赋值语句为一个字符数组赋值

#include <string.h> #include <stdio.h> void main() 例 strcpy与strcat举例 T r b o 1 2 3 4 5 6 7 8 9 u \0 24 ……. T r b o \0 1 2 3 4 5 6 7 8 9 u 24 ……. …... T r b o C + 1 2 3 4 5 6 7 8 9 u \0 24 ……. #include <string.h> #include <stdio.h> void main() { char destination[25]; char blank[] = " ", c[]= "C++", turbo[] = "Turbo"; strcpy(destination, turbo); strcat(destination, blank); strcat(destination, c); printf("%s\n", destination); }

例 对于以下字符串,strlen(s)的值为: (1)char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’}; 字符串比较函数strcmp 格式:strcmp(字符串1,字符串2) 功能:比较两个字符串 比较规则:对两串从左向右逐个字符比较(ASCII码), 直到遇到不同字符或‘\0’为止 返值:返回int型整数,a. 若字符串1< 字符串2, 返回负整数 b. 若字符串1> 字符串2, 返回正整数 c. 若字符串1== 字符串2, 返回零 说明:字符串比较不能用“==”,必须用strcmp 字符串长度函数strlen 格式:strlen(字符数组) 功能:计算字符串长度 返值:返回字符串实际长度,不包括‘\0’在内 例 对于以下字符串,strlen(s)的值为: (1)char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’}; (2)char s[ ]=“\t\v\\\0will\n”; (3)char s[ ]=“\x69\082\n”; 答案:1 3 1

#include <string.h> #include <stdio.h> main() { char str1[] = ”Hello!", str2[] = ”How are you?”,str[20]; int len1,len2,len3; len1=strlen(str1); len2=strlen(str2); if(strcmp(str1, str2)>0) { strcpy(str,str1); strcat(str,str2); } else if (strcmp(str1, str2)<0) { strcpy(str,str2); strcat(str,str1); } else strcpy(str,str1); len3=strlen(str); puts(str); printf(”Len1=%d,Len2=%d,Len3=%d\n”,len1,len2,len3); } 例 strcmp与strlen举例 How are you?Hello! Len1=6,Len2=12,Len3=18

【例7.6】不使用字符串比较函数,比较两个字符串的大小。 #include "stdio.h" main() {char a[20],b[20]; int k,flag; printf("\nplease input the first string: "); gets(a); /*输入第一个字符串*/ printf("\nplease input the second string: "); gets(b); /*输入第二个字符串*/ k=0; while(a[k]==b[k]&&a[k]!= '\0'&&b[k]!= '\0') k++; /*比较对应字符的大小*/ flag=a[k]-b[k]; printf("\nthe first string "); /*输出比较的结果*/ if (flag==0) printf("="); else if (flag<0) printf("<"); else printf(">"); printf("the second string \n"); }

#include "stdio.h" main() {char c[60]; int k; printf("\nplease input the string : "); gets(c); /*输入字符串*/ printf("\n"); k=0; while(c[k]!= '\0') /*以小写形式输出字符串*/ {if (c[k]>= 'a'&&c[k]<= 'z') putchar(c[k]-32); else putchar(c[k]); k++;} while(c[k]!= '\0') /*以大写形式输出字符串*/ {if (c[k]>= 'A'&&c[k]<= 'Z') putchar(c[k]+32); } 【例7.7】输入一个由字母组成的字符串,再分别以大写字母和小写字母形式输出该字符串。

#include <stdio.h> main() { char string[81]; int i,num=0,word=0; 应用举例 #include <stdio.h> main() { char string[81]; int i,num=0,word=0; char c; gets(string); for(i=0;(c=string[i])!='\0';i++) if(c==' ') word=0; else if(word==0) { word=1; num++; } printf("There are %d words \ in the line\n",num); } 例 输入一行字符,统计其中有多少个单词 输入一字符串给 string i=0 num=0 word=0 当((c=string[i])!=‘\0’) c=空格 真 假 word=0 word=1 num=num+1 i=i+1 输出:num word==0

例 输入:I am a boy. 当前字符=空格 是 否 未出现新单词,使word=0,num不累加 是否空格 word原值 新单词开始否 word新值 num值  I a m b o y . 否 是 1 是 1 未 否 是 1 2 否 1 未 2 是 1 未 2 否 是 1 3 是 1 未 3 否 是 1 4 否 1 未 4 否 1 未 4 否 1 未 4

#include <stdio.h> #include <string.h> main() { char string[20],str[3][20]; int i; for(i=0;i<3;i++) gets(str[i]); if(strcmp(str[0],str[1])>0) strcpy(string,str[0]); else strcpy(string,str[1]); if(strcmp(str[2],string)>0) strcpy(string,str[2]); printf("\nThe largest string \ is:\n%s\n",string); } 例 有三个字符串,找出其中最大者 H o w \0 H e l l o \0 H i g h \0 str[0] str[1] str[2]

7.2 结构体 7.2.1 结构体类型定义------形式 7.2.2 结构体变量 1、结构体变量的定义 7.2.3 结构体数组 7.2 结构体 7.2.1 结构体类型定义------形式 7.2.2 结构体变量 1、结构体变量的定义 2、结构体变量的初始化 3、 结构体变量的引用 7.2.3 结构体数组 7.2.4 位段 7.2.5 向函数传递结构体型数据

结构体:是一种自定义 de 构造数据类型。 用途:把不同类型的数据组合成一个整体。 7.2.1 结构体类型定义: 合法标识符 可省:无名结构体 7.2.1 结构体类型定义: struct [结构体名] { 类型标识符 成员名; ……………. }; 成员类型可以是 基本型或构造型 struct是关键字, 不能省略

… ….. 例 struct student { int num; char name[20]; char sex; int age; score addr 2字节 20字节 1字节 4字节 30字节 … ….. 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; 结构体类型定义描述结构 的组织形式(图纸),不分配内存 结构体类型的定义

7.2.2 结构体变量 1、结构体变量的定义 (1)、先定义结构体类型,再定义结构体变量 7.2.2 结构体变量 1、结构体变量的定义 (1)、先定义结构体类型,再定义结构体变量 一般形式: struct 结构体名 { 类型标识符 成员名; ……………. }; struct 结构体名 变量名表列; 例 #define STUDENT struct student STUDENT { int num; char name[20]; char sex; int age; float score; char addr[30]; }; STUDENT stu1,stu2; 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; struct student stu1,stu2;

(2)、定义结构体类型的同时定义结构体变量 一般形式: struct 结构体名 { 类型标识符 成员名; ……………. }变量名表列; 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2;

(3)、直接无名结构体的同时定义结构体变量 一般形式: struct { 类型标识符 成员名; ……………. }变量名表列; 例 struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; 用无名结构体直接定义 变量只能一次

几点说明 结构体类型与结构体变量概念不同 结构体成员名(域名)与程序中变量名地位相同 结构体可嵌套 例 struct date 类型:不分配内存; 变量:分配内存 类型:不能赋值、存取、运算; 变量:可以 结构体成员名(域名)与程序中变量名地位相同 结构体可嵌套 例 struct date { int month; int day; int year; }; struct student { int num; char name[20]; struct date birthday; }stu; num name birthday month day year 例 struct student { int num; char name[20]; struct date { int month; int day; int year; }birthday; }stu; num name birthday month day year

2、结构体变量的初始化 和其他类型的变量相同, 在定义结构体变量时赋初值 形式一: 例 struct student { int num; 类型标识符 成员名; ……………. }; struct 结构体名 结构体变量={初始数据}; 例 struct student { int num; char name[20]; char sex; int age; char addr[30]; }; struct student stu1={112,“Wang Lin”,‘M’,19, “200 Beijing Road”};

形式二: 例 struct student { int num; char name[20]; char sex; int age; 类型标识符 成员名; ……………. }结构体变量={初始数据}; 形式二: 例 struct student { int num; char name[20]; char sex; int age; char addr[30]; }stu1={112,“Wang Lin”,‘M’,19, “200 Beijing Road”};

形式三: 例 struct { int num; char name[20]; char sex; int age; 类型标识符 成员名; ……………. }结构体变量={初始数据}; 例 struct { int num; char name[20]; char sex; int age; char addr[30]; }stu1={112,“Wang Lin”,‘M’,19, “200 Beijing Road”};

3 结构体变量的引用 引用规则 引用方式: 结构体变量名.成员名 结构体变量不能整体引用,只能引用变量成员 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; printf(“%d,%s,%c,%d,%f,%s\n”,stu1); () stu1={101,“Wan Lin”,‘M’,19,87.5,“DaLian”}; () 引用方式: 结构体变量名.成员名 例 struct student { int num; char name[20]; struct date { int month; int day; int year; }birthday; }stu1,stu2; num name birthday month day year stu1.birthday.month=12; 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; stu1.num=10; stu1.score=85.5; stu1.score+=stu2.score; stu1.age++; 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; stu2=stu1; ( ) 例 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu1,stu2; if(stu1==stu2) …….. () 成员(分量)运算符 优先级: 1 结合性:从左向右 可以将一个结构体变量赋值给另一个结构体变量 结构体嵌套时逐级引用

7.2.3 结构体数组 1、结构体数组的定义和初始化 定义:三种形式: 形式一: 形式二: 形式三: struct student num name sex age stu[0] stu[1] 25B 形式一: struct student { int num; char name[20]; char sex; int age; }; struct student stu[2]; 形式二: struct student { int num; char name[20]; char sex; int age; }stu[2]; 形式三: struct { int num; char name[20]; char sex; int age; }stu[2];

初始化:与其他类型的数组赋初值的方法相同 分元素初始化: struct student { int num; char name[20]; char sex; int age; }; struct student stu[ ]={{100,“Wang Lin”,‘M’,20}, {101,“Li Gang”,‘M’,19}, {110,“Liu Yan”,‘F’,19}}; 全部初始化时维数可省 顺序初始化: struct student { int num; char name[20]; char sex; int age; }; struct student stu[ ]={100,“Wang Lin”,‘M’,20, 101,“Li Gang”,‘M’,19, 110,“Liu Yan”,‘F’,19}; 例 struct { int num; char name[20]; char sex; int age; }stu[ ]={{……},{……},{……}};

strcpy(stu[0].name,”ZhaoDa”); 2、结构体数组引用 引用方式: 结构体数组名[下标].成员名 num name sex age stu[0] stu[1] 25B stu[1].age++; struct student { int num; char name[20]; char sex; int age; }str[3]; strcpy(stu[0].name,”ZhaoDa”);

}leader[3]={“Li”,0,“Zhang”,0,”Wang“,0}; main() 例: 统计后选人选票 struct person { char name[20]; int count; }leader[3]={“Li”,0,“Zhang”,0,”Wang“,0}; main() { int i,j; char leader_name[20]; for(i=1;i<=10;i++) { scanf("%s",leader_name); for(j=0;j<3;j++) if(strcmp(leader_name,leader[j].name)==0) leader[j].count++; } for(i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count); name count Li Zhang Wang

函数之间的参数传递也可以是结构体型数据,既可以通过参数传送结构体变量的成员,也可以通过参数传递整个结构体变量。 7.2.5 向函数传递结构体型数据 函数之间的参数传递也可以是结构体型数据,既可以通过参数传送结构体变量的成员,也可以通过参数传递整个结构体变量。 1.向函数传递结构体变量的成员 若结构体变量的成员是基本类型,则作函数的实参时的用法与普通变量作函数的实参的用法相同,形参与实参之间仍然是“值传递”的方式。 2.向函数传递结构体变量 ANSI C允许函数之间传递结构体变量。若实参是结构体变量,那么形参也应是同类型的结构体变量。

例 用结构体变量作函数参数 (main) (main) (main) (main) a :27 a :27 struct data 例 用结构体变量作函数参数 arg a :27 b: 3 c :30 (main) (func) parm copy arg a :27 b: 3 c :30 (main) (func) parm a :18 b: 5 c :90 arg a :27 b: 3 c :30 (main) arg a :27 b: 3 c :30 (main) struct data { int a, b, c; }; main() { void func(struct data); struct data arg; arg.a=27; arg.b=3; arg.c=arg.a+arg.b; printf("arg.a=%d arg.b=%d arg.c=%d\n",arg.a,arg.b,arg.c); printf("Call Func()....\n"); func(arg); } void func(struct data parm) { printf("parm.a=%d parm.b=%d parm.c=%d\n",parm.a,parm.b,parm.c); printf("Process...\n"); parm.a=18; parm.b=5; parm.c=parm.a*parm.b; printf("parm.a=%d parm.b=%d parm.c=%d\n",parm.a,parm.b,parm.c); printf("Return...\n");

由上面的例子可见:在发生函数调用时,形参结构体变量也要占用内存空间,接收实参结构体变量传递来的信息,因此函数之间传递结构体变量会带来时间和空间的巨大开销;而且,形参与实参之间是“值传递”的方式,被调函数对形参结构体变量的修改并不能传递给实参,即主调函数无法得到处理后的数据,所以虽然语法上允许,但一般很少采用这种传递方式。而是采用传递结构体地址的方法,使得在被调用单位与调用单位函共享结构体变量数据。

7.3 共用体 有时需要将几个不同时出现的变量共享一个内存单元,如:将一个整型变量、实型变量、字符型变量共同放入同一个地址空间(当然这几个变量不能同时用),怎么办?C提供了共用体(联合体)类型支持。 7.3.1 共用体类型 union 共用体名 { 类型标识符 成员名; ……………. }; 定义形式: 例 union data { int i; char ch; float f; }; f ch i 100地址开始 类型定义不分配内存

7.3.2 共用体变量的定义 1、共用体变量的定义 形式一: union data { int i; char ch; float f; 7.3.2 共用体变量的定义 1、共用体变量的定义 形式一: union data { int i; char ch; float f; }; union data a,b,c,*p,d[3]; 形式二: union data { int i; char ch; float f; }a,b; 形式三: union { int i; char ch; float f; }a,b,c; f ch i a b 共用体变量任何时刻 只有一个成员存在 共用体变量定义分配内存, 长度=最长成员所占字节数

p->i p->ch p->f 2 共用体变量引用 引用方式: 共用体指针名->成员名 共用体变量名.成员名 (*共用体指针名).成员名 引用规则 不能引用共用体变量,只能引用其成员 union data { int i; char ch; float f; }; union data a,b,c,*p,d[3]; a.i a.ch a.f p->i p->ch p->f (*p).i (*p).ch (*p).f d[0].i d[0].ch d[0].f 共用体变量中起作用的成员是最后一次存放的成员 不能在定义共用体变量时初始化 例 union { int i; char ch; float f; }a; a=1; () 例 a.i=1; a.ch=‘a’; a.f=1.5; printf(“%d”,a.i); (编译通过,运行结果不对) 例 float x; union { int i; char ch; float f; }a,b; a.i=1; a.ch=‘a’; a.f=1.5; b=a; () x=a.f; () 例 union { int i; char ch; float f; }a={1,’a’,1.5}; () 可以用一个共用体变量为另一个变量赋值

x.ch[0],x.ch[1],x.ch[0],x.ch[1]); } 例 将一个整数按字节输出 main() { union int_char { int i; char ch[2]; }x; x.i=24897; printf("i=%o\n",x.i); printf("ch0=%o,ch1=%o\n ch0=%c,ch1=%c\n", x.ch[0],x.ch[1],x.ch[0],x.ch[1]); } 01100001 01000001 低字节 高字节 01000001 01100001 ch[0] ch[1] 运行结果: i=60501 ch0=101,ch1=141 ch0=A,ch1=a

结构体与共用体 区别: 存储方式不同 struct node { char ch[2]; ch int k; a }a; k union node }b; a ch k b 变量的各成员同时存在 任一时刻只有一个成员存在 联系: 两者可相互嵌套

例: 结构体中嵌套共用体 struct { int num; char name[10]; char sex; char job; class position Li Wang 1011 2086 F M S T 501 prof 例: 结构体中嵌套共用体 struct { int num; char name[10]; char sex; char job; union { int class; char position[10]; }category; }person[2]; 循环n次 读入姓名、号码、性别、职务 job==‘s’ 真 假 读入class 读入 position 输出 “输入错” 输出:姓名,号码, 性别,职业,班级 性别,职业,职务 job==‘t’

例共用体中嵌套结构体,机器字数据与字节数据的处理 struct w_tag { char low; char high; }; union u_tag { struct w_tag byte_acc; int word_acc; }u_acc; 00010010 00110100 低字节 高字节 00110100 00010010 low high 0x1234 00010010 11111111 低字节 高字节 11111111 00010010 low high 0x12ff word_acc byte_acc.low byte_acc.high u_acc

7.5 用typedef 定义已知类型 功能:用自定义名字为已有数据类型命名 类型定义简单形式: typedef type name; 例 typedef int INTEGER; 例 INTEGER a,b,c; REAL f1,f2; 类型定义语句关键字 已有数据类型名 用户定义的类型名 例 typedef float REAL; int a,b,c; float f1,f2; 类型定义后,与已有类型一样使用 说明: 1.typedef 没有创造新数据类型 2.typedef 是定义类型,不能定义变量 3.typedef 与 define 不同 define typedef 预编译时处理 编译时处理 简单字符置换 为已有类型命名

typedef定义类型步骤 类型定义可嵌套 按定义变量方法先写出定义体 如 int i; 将变量名换成新类型名 如 int INTEGER; 最前面加typedef 如 typedef int INTEGER; 用新类型名定义变量 如 INTEGER i,j; 类型定义可嵌套 例 定义结构体类型 struct date { int month; int day; int year; }d; 例 定义结构体类型 struct date { int month; int day; int year; }DATE; 例 定义数组类型 int a[100]; int ARRAY[100]; typedef int ARRAY[100]; ARRAY a,b,c; 例 定义指针类型 char *str; char *STRING; typedef char *STRING; STRING p,s[10]; 例 定义函数指针类型 int (*p)(); int (*POWER)(); typedef int (*POWER)(); POWER p1,p2; 例 定义结构体类型 typedef struct date { int month; int day; int year; }DATE; 例 定义结构体类型 DATE birthday, *p; GROUP为结构体类型 PG为指向GROUP的指针类型 例 typedef struct club { char name[20]; int size; int year; }GROUP; typedef GROUP *PG; PG pclub;  struct date { int month; int day; int year; }birthday, *p;  int (*p1)(),(*p2)();  int a[100],b[100],c[100];  char *p; char *s[10];  GROUP *pclub;  struct club *pclub;