1.45k likes | 1.71k Views
计算机实习. 第 2 讲. 复习. 结构体 struct 结构体类型名 { 类型 成员 1; 类型 成员 2; 类型 成员 n; };. 复习. 结构体 struct 结构体类型名 { 类型 成员 1; 类型 成员 2; 类型 成员 n; } 变量 1, 数组 1;. 复习. #include "stdio.h" #include "math.h" struct point { float x; float y; };. 复习.
E N D
计算机实习 第2讲
复习 结构体 struct 结构体类型名 { 类型 成员1; 类型 成员2; 类型 成员n; };
复习 结构体 struct 结构体类型名 { 类型 成员1; 类型 成员2; 类型 成员n; }变量1,数组1;
复习 #include "stdio.h" #include "math.h" struct point { float x; float y; };
复习 void input(struct point a[]) { int i; for(i=0;i<2;i++) { printf("输入第%d点的坐标\n",i+1); scanf("%f%f",&a[i].x,&a[i].y); } }
复习 void midpoint(struct point a[]) { int i;struct point m;m.x=0;m.y=0; for(i=0;i<2;i++) {m.x=m.x+a[i].x; m.y=m.y+a[i].y;} m.x=m.x/2;m.y=m.y/2; a[2].x=m.x;a[2].y=m.y; }
复习 float dis(struct point a[]) { int i;float s;struct point m;m.x=a[0].x;m.y=a[0].y; { m.x=m.x-a[1].x;m.y=m.y-a[1].y;} s=sqrt(m.x*m.x+m.y*m.y); return s; }
复习 main() { struct point a[3]; input(a); printf(" 第1点%f %f 第2点%f %f\n",a[0].x,a[0].y,a[1].x,a[1].y); midpoint(a); printf(" 中点%f %f \n",a[2].x,a[2].y); printf("距离%f\n",dis(a)); }
复习 #include "stdio.h" #include "string.h" struct data { int month; int day; int year; }; struct stud { char name[20]; char tele[12]; char zip[7]; struct data birthday; char addre[30]; }; struct stud stud1[30]={"liming","1331187907","210020",3,14,1988,"beijing","chaening","13789087907","260020",8,14,1980,"tianjing","being","13678987907","710020",9,14,1990,"nanjing"};
main() { int k,i,j,n=3; struct stud temp; for ( i = 0; i < n-1; i++) { k = i; for (j= i+1;j<n; j++) if (strcmp(stud1[j].name,stud1[k].name)<0) k =j; temp= stud1[i]; stud1[i]= stud1[k]; stud1[k]= temp; } printf("姓名 电话 邮编 生日 地址\n"); for(i=0;i<3;i++) printf("%10s%12s%8s %2d-%2d-%4d %15s\n",stud1[i].name,stud1[i].tele,stud1[i].zip,stud1[i].birthday.month,stud1[i].birthday.day,stud1[i].birthday.year,stud1[i].addre); }
复习 文件 1.定义 FILE *指针名; 2.打开文件 if((指针名=fopen("file9_3.txt","w"))==NULL) { printf("%s不能打开\n","e:\\file9_3.txt"); exit(1); }
复习 文件 3.读或写文件 fprintf(指针名,"%5d ",b[i]); 4.关闭文件 fclose(fp);
复习 对职工工资进行统计。职工信息包含工号和姓名、基本工资、奖金、提成、实发工资,分别统计平均工资、最高工资和最低工资,将职工工资信息存入文件(diy2.dat)中。
#include "stdio.h" #include "string.h" struct staff { int num; char name[20]; float basic_wage; float percentage; float bonus; float real_wages; float wages_should; }sp[200]={901,"张川",432,120,66,0,0,902,"李洪",488,123,75,0,0,903,"罗庆",423,240,24,0,0,904,"秦汉",356,789,72,0,0,905,"刘少文",530,765,114,0,0,906,"苏南昌",488,456,87,0,0,907,"孙红",530,345,102,0,0}; FILE *fp3;
void file(struct staff a[],int n) { int i;FILE *fp3; if((fp3=fopen("diy2.dat", "w"))==NULL) { printf("Open error \n");exit(0); } for(i=0;i<n;i++) { fprintf(fp3,"%d,%s,%f,%f,%f,%f,%f",a[i].num,a[i].name,a[i].basic_wage,a[i].percentage,a[i].bonus,a[i].real_wages,a[i].wages_should); } fclose(fp3); }
int max(struct staff a[],int n) { int imax=0,i; for(i=0;i<n;i++) if(a[i].basic_wage>a[imax].basic_wage) imax=i; return imax; }
int min(struct staff a[],int n) { int imin=0,i; for(i=0;i<n;i++) if(a[i].basic_wage<a[imin].basic_wage) imin=i; return imin; }
void comput(struct staff a[],int n) { int i; for(i=0;i<n;i++) {a[i].wages_should=a[i].basic_wage+a[i].percentage+a[i].bonus; a[i].real_wages=a[i].wages_should-a[i].wages_should*0.1; } }
float ave(struct staff a[],int n) { int i;float ave=0; for(i=0;i<n;i++) ave=ave+a[i].basic_wage; ave=ave/n; return ave; }
main() { int m=7; comput(sp,m); printf("最高工资 %f 最低工资 %f 平均工资%f\n",sp[max(sp,m)].basic_wage,sp[min(sp,m)].basic_wage,ave(sp,m)); file(sp,m); }
项目评分标准 • 数据类型 • 数据文件 • 算法 • 界面 • 综合
项目合作与分工 • 数据类型 • 数据文件 • 算法
练习 • 计算5名学生3门课成绩的平均分,学生信息为: • struct stud • { int no; • char name[16]; • float mark[3]; • float ave; • }; • 将5名学生写入文件AA.dat中
void file(struct stud a[],int n) { int i; FILE *fp3; if((fp3=fopen(“AA.dat", "w"))==NULL) { printf("Open error \n");exit(0); } for(i=0;i<n;i++) { fprintf(fp3,"%d,%s,%f,%f,%f,%f\\n",a[i].num,a[i].name,a[i]. mark[0],a[i].mark[1],a[i].mark[2].a[i].ave); } fclose(fp3); }
指针基本概念 基础教研室
目 录 3 3 内存与地址 1 3 指针与指针变量 2 指针初始化 指针运算 4
内存 0 …... 2000 2001 2002 2003 2005 …... • 变量与地址 内存中每个字节有一个编号-----地址 程序中: int i; float k; i 编译或函数调用时为其分配内存单元 k 变量是对程序中数据 存储空间的抽象
指针与指针变量 …... 整型变量i 2000 10 2001 2002 2003 变量i_pointer 2004 2005 变量地址(指针) 指针变量 2006 地址存入 指针变量 指向 …... 变量值 变量 指针 变量的内容 变量的地址 2000 指针变量
指针变量定义 • 一般形式: [存储类型]数据类型 *指针名; 例 int*p1,*p2; float *q ; static char *name; 表示定义指针变量 不是‘*’运算符 合法标识符 指针变量本身的存储类型 指针的目标变量的数据类型 注意: 1、int *p1, *p2;与 int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值
…... 整型变量i 2000 10 2001 2002 2003 变量i_pointer 2004 2000 指针变量 2005 2006 …... 地址符&与指针运算符* 含义:取指针所指向变量的内容 单目运算符 优先级: 2 结合性:自右向左 含义: 取变量的地址 单目运算符 优先级: 2 结合性:自右向左 i_pointer &i &(*i_pointer) i *i_pointer *(&i) i_pointer=&i=&(*i_pointer) i=*i_pointer =*(&i) i_pointer-----指针变量,它的内容是地址量 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址
例题1 • #include <stdio.h> • int main( ) • { int i = 100, j=200; • int *p; • p = &i; //变量i的地址赋给p • printf("&i=%d *(&i)=%d\n", &i, *(&i)); • printf(" p=%d *p =%d\n\n", p, *p); • p = &j; //变量j的地址赋给p • printf("&j=%d *(&j)=%d\n", &j, *(&j)); • printf(" p=%d *p =%d\n", p, *p); • return 0; • } ||
指针初始化 • 当指针变量被定义时应立即赋值,这个过程称为初始化 • “野指针”--未被初始化,该指针是游离的,可能指向任意一个地址单元 例 int i; int *p=&i; 例 int i; int *p=&i; int *q=p;
例题2 …... 整型变量i 2000 10 2001 2002 2003 指针变量p 2004 2005 随机 2006 …... • main( ) • { int i=10; • int *p; • *p=i; • printf(“%d”,*p); • }
指针运算 • 算术运算 • 指针 ± 整型数 • 如果指针变量的定义为 datatype *p; p初始地址值为DS, 那么p ± n = DS ± n*sizeof(datatype)。 • 常运用到数组应用中 • 关系运算 • 前提就是必须指向的是连续的存储单元,比如同一个数组 • 常用来测试是否循环结束 ,如p<=&a[3]判断是否是数组的最后一个元素
案例 …... main() { int *p1,*p2,*p,a,b; scanf("%d,%d",&a,&b); p1=&a; p2=&b; if(a<b) { p=p1; p1=p2; p2=p;} printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); } 2008 2000 指针变量p1 2006 2002 2006 2004 指针变量p2 指针变量p 整型变量b 整型变量a 5 2006 9 2008 …...
指针与一维数组 数组名是一个地址常量,表示数组的首地址值,是一个指针常量。 int a[10]; 下标法a[i]来表示某个数组元素 a+i ——该a[i]元素的首地址。 *(a+i)——该a[i]元素的值
用指针变量引用数组元素 • 定义指向数组的指针变量 int a[5]; int *p; p=&a[0]; p=a; • 用指针法引用数组元素 *(p+i)表示a[i]元素
数组元素表示方法 地址 p[0] a[0] a[0] a[0] *p *a 元素 地址 元素 *(p+1) *(a+1) p[1] a[1] a[1] a[1] *(p+2) *(a+2) p[2] a[2] a[2] a[2] p a a[3] a[3] p+1 a+1 p+2 a+2 a[9] p[9] a[9] *(a+9) *(p+9) a[9] ... ... p+9 a+9 指针法 下标法 [] 变址运算符 a[i] *(a+i) a[i] p[i] *(p+i) *(a+i)
pa a[0] 1 a[1] 2 a[2] 3 a[3] 4 a[4] 5 例 数组元素的引用方法 main() { int a[5],*pa,i; for(i=0;i<5;i++) a[i]=i+1; pa=a; for(i=0;i<5;i++) printf("*(pa+%d):%d\n",i,*(pa+i)); for(i=0;i<5;i++) printf("*(a+%d):%d\n",i,*(a+i)); for(i=0;i<5;i++) printf("pa[%d]:%d\n",i,pa[i]); for(i=0;i<5;i++) printf("a[%d]:%d\n",i,a[i]); }
指向数组元素的指针变量的运算 • p++; ++p; /*使p指向数组的后一个元素 */ • p--; --P; /*使p指向数组的前一个元素 */ • p+n; /*使p往后移n个元素 */ • p-n; /*使p往前移n个元素 */ • p-q; /*若p与q指向同一数组,求指针变量p和q之间元素的个数,且q在p前*/
例 p指向int型数组,且p=&a[0]; 则p+1 指向a[1] 例 int a[10]; int *p=&a[2]; p++; *p=1; 例 int a[10]; int *p1=&a[2]; int *p2=&a[5]; 则:p2-p1=3;
字符串的表示形式 string string[0] I string[1] string[2] l string[3] o string[4] v string[5] e string[6] string[7] C string[8] h string[9] i string[10] n string[11] a string[12] ! string[13] \0 • 用字符数组实现 例 main( ) { char string[]=“I love China!”; printf(“%s\n”,string); printf(“%s\n”,string+7); }
字符指针 • 定义 char *pstr; • 初始化 char *pstr=“C language”; 或 char *pstr; pstr= "C language";
字符串的表示形式 string I l o v e C h i n a ! \0 • 用字符指针表示 例 main( ) { char *string=“I love China!”; printf(“%s\n”,string); string+=7; while(*string) { putchar(string[0]); string++; } }
案例—字符串的复制 main( ) { char a[80],b[80],*pa,*pb; pa=a;pb=b; scanf("%s",pa); while(*pa!= '\0') *(pb++)=*(pa++); *pb=’\0’; printf("%s",b) }
关于指针变量的运算 1、p++ (或p+=1) 使p指向下一个元素的地址。 2、若有*p++ 由于++ 和 * 同优先级,其结合方向为 自右而左,因此它等价于 *(p++)。 main() { int a[8]={2,4,6,8,10,12,14,16}, i, *p; for(p=a, i=0; i<8; i++) printf(“%d,”, *p++); }
p p p 3、*(p++)与 *(++p) 作用不同。前者是先取*p的值 后使 p 加1; 后者是先使 p 加1,再取 *p。 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] *(p++) 2 *(++p) 4 *(++p)与*++p 等价 4、(*p)++表示是 p 所指向的元素值加 1。 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] 5 (*p)++ 3 4
练习 若已定义了一个结构体变量和基类型为同一结构体类型的指针变量,并使该指针指向同类型的变量,则有3种形式来引用结构体变量中的成员。结构体变量名也可以是已经定义的结构体数组的数组元素,形式如下: • 结构体变量名.成员名 • 指针变量名 –> 成员名 • (*指针变量名).成员名