项目六 用指针优化学生成绩排名 项目要求 项目分析

Slides:



Advertisements
Similar presentations
第 8 章 数组 计算机科学学院 李淮 Tel QQ
Advertisements

《C语言程序设计》复习
电子成绩单项目实现.
C语言程序设计教程 单位:德州学院计算机系.
第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习.
C语言基础——指针的高级应用 Week 05.
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
第4章 选择结构程序设计 在现实生活中,需要进行判断和选择的情况是很多的 如果你在家,我去拜访你 如果考试不及格,要补考
C语言程序设计 第十二章 位运算.
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
复习与总结.
程序设计基础.
第六章 数 组 主讲教师 贾月乐 联系电话:
由C程序结构所知,一个完整的C语言程序是由一个且只能有一个main()函数(又称主函数)和若干个其他函数组合而成的。而前面各章仅学习main()函数的编程,本章将介绍其他函数的编程,包括其他函数的定义、调用、参数传递及变量的作用域等。
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
選擇排序法 通訊一甲 B 楊穎穆.
第3章 顺序结构程序设计 本章要点: 格式化输出函数──printf() 格式输入函数——scanf() 字符输出函数——putchar()
目录 10.1 指针的基本概念 10.2 指向变量的指针变量 10.3 指向数组的指针变量 10.4 指向函数的指针变量和指针型函数
第4章 选择结构程序设计 4.1 选择结构和条件判断 4.2 用if语句实现选择结构 4.3关系运算符和关系表达式
C程序设计.
If … else 選擇結構 P27.
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
Introduction to the C Programming Language
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
C语言程序设计 李祥.
第八章 函数.
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
第8章 善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
6.4.1指针与二维数组 1、二维数组结构的分析 设有数组定义为:int a[3][4]; 则有: a表示数组在内存中的首地址。
算法的基本概念.
C语言 程序设计基础与试验 刘新国、2012年秋.
第13章 结构体的应用 13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组
第八章 使用指针.
第十章 指针.
第三章 顺序结构程序设计 主讲教师 贾月乐 电话:
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
目录 9.1 结构体类型 9.2 共用体类型 9.3 枚举类型 9.4 类型声明符typedef 1.
C语言概述 第一章.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
C语言复习3----指针.
第 二 章 数据类型、运算符与表达式.
for 迴圈 while迴圈 do-while迴圈 break 與 continue goto 與 標籤 程式觀摩
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之
第八章 指標 (Pointer).
C语言的特点 1. C程序由许多函数组成 2. C程序必须有且只有一个主函数main( ) 3. 函数用“{”和“}”表示起点和终点
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
C程序设计.
C程序设计.
第九章 指针.
第二章 类型、对象、运算符和表达式.
C程序设计.
程序设计基础.
本节内容 指针类型.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第七章  数 组.
Introduction to the C Programming Language
第九章 指针 C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C语言基础学习 从外行到入门.
Presentation transcript:

项目六 用指针优化学生成绩排名 项目要求 项目分析 项目六 用指针优化学生成绩排名 项目要求 一个班有40位学生参加了期终考试(考了三门课),请用指针优化学生成绩排名。即用指针实现数组的输入输出以及数组的排序(在函数中进行)。 项目分析 要用指针优化学生成绩排名,第一必须要了解指针的概念、引用; 第二必须会用指针实现数组的输入输出; 第三在函数中用指针实现数组的排序,然后调用此函数。 为了在介绍的时候条理清晰,所以分解成5个任务。

任务1 了解指针 一、问题情景 知识点: 1、指针的概念; 2、指针的引用; 任务1 了解指针 一、问题情景 一个班进行了一次考试,现要将几个学生的成绩输入,用指针的方式输出。 知识点: 1、指针的概念; 2、指针的引用;

三、相关知识 (一)地址的概念与取地址运算 地址——内存单元的编号(在计算机中,把内存区划 分为一个一个的存储单元,每个单元为一个字节,它 们都有一个编号,这个编号就是内存地址) 取地址运算——& 如:int a = 3 ; &a 就是变量在内存中的地址。 可以用printf(“%x \n” , &a); 看出其地址。 #include <stdio.h> main() { int a=3; printf("%d\n",a); printf("%x\n",&a); } 注意: 这个地址并不是始终不变的,这是由机器和操作系统来安排的,我们无法预先知道。 但&不能施加在常量或表达式前。

三、相关知识 (二)指针的概念 ——一个变量在内存中存储时的地址, 它并不占内存中的存储空间。 简单地说,指针就是地址。二者是同一个概念的两种说法。只不过指针更形象一些,就像一个针一样,可以指向某个地方。

三、相关知识 (三)指针变量 概念 既然存储在内存中的各种变量都有一个地址,我们能否这样设想:定义某种变量,让这个变量的值始终等于某个变量的地址,如同某个房间号、门牌号一样?回答是肯定的。我们把这种存放某种变量地址的变量称为指针变量。 …. 35 10 a b 240ff52 240ff56 p q 因此,在C语言中,将地址形象化地称为指针

三、相关知识 指针变量的定义和赋值 [存储类型 ] 数据类型 * 指针变量名 1、定义 [存储类型 ] 数据类型 * 指针变量名 如: int *p, a=3; int *q, b=5; 说明 a. * 是定义指针变量的标志,不可丢掉 b. 数据类型是指针变量所指向的变量的类型 c. 指针变量定义后,其值是不确定的

三、相关知识 2、赋值:可以进行初始化,也可以使用赋值语句 (1)初始化: int a, *s=&a; (2)赋值语句 int a, *s; (3)注意:只能用同类型变量的地址进行赋值! 如定义:int *s; float f; 则 s=&f;是非法的。

三、相关知识 指针变量的引用 1、 &——取地址运算 如: int *p , i=3, j=5; p=&i; /*让p其指向变量i*/ 2、 *——指针运算,则代表取指针所指向的单元的内容。 区分:*运算符在不同场合的作用, 编译器能够根据上下文环境判别*的作用。int a,b,c; int *p; (*表示定义指针) p = &a; *p = 100; (*表示指针运算符) c = a * b; (*表示乘法运算符)

【例6-1】指针与地址的应用 #include <stdio.h> void main() { int a,b,*pointer_1,*pointer_2; a=100,b=200; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,*pointer_1); printf("%d,%d\n",b,*pointer_2); }

printf(“%d , %d \n” , *p1, *p2); } 指针赋值, 若输入“3 4”,则输出为什么? 定义指针变量 main( ) { int *p1, *p2, a1, a2; scanf(“%d %d” , &a1, &a2 ); p1 =&a1; p2=&a2; printf(“%d , %d \n” , *p1, *p2); p2 = p1; printf(“%d , %d \n” , *p1, *p2); } 指针赋值, 把a1的地址给p1 直接赋值, 把p1指针的地址给p2, 即p2也指向a1 指针运算, p1指针所指向的变量a1的内容

任务1的具体实现 #include <stdio.h> void main() { int *p1,*p2,a,b; printf("输入:"); scanf("%d,%d",&a,&b); p1=&a;p2=&b; printf("输出:"); printf("a=%d,b=%d\n",a,b); printf("*p1=%d,*p2=%d\n",*p1,*p2); }

【例6-2】输入两个学生的成绩,按从小到大的顺序输出。 #include <stdio.h> void main() { int *p1,*p2,*p,a,b; printf("输入:"); scanf("%d,%d",&a,&b); p1=&a; p2=&b; if(a>b) {p=p1;p1=p2;p2=p;} printf("输出:"); printf("a=%d,b=%d\n",a,b); printf("min=%d,max=%d\n",*p1,*p2); }

? 形参不能传递给实参! 此方法不能实现两个数的调换! 如何用函数调用的方式实现两个数的调换? swap(int x,int y) {int temp; temp= x ; x= y ; y=temp ; } main( ) { int a, b; scanf(“%d,%d”,&a,&b); if(a<b) swap(a, b); printf(“%d, %d \n ” , a, b); } 形参不能传递给实参! 此方法不能实现两个数的调换! ?

指针变量作为函数参数 注意: 指针变量作为函数的参数,从实参向形参的数据传递仍然遵循“单向值传递”的原则,只不过此时传递的是地址. 函数可以通过return返回一个值,如果要函数返回多个值怎么办? 指针传递的方式来改变 【例6-3】用指针变量作为函数参数,实现数据的交换。 #include <stdio.h> void swap(int *p1,int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; } void main() { int a,b,*pointer_1,*pointer_2; printf("输入a,b的值:"); scanf("%d,%d",&a,&b); pointer_1=&a,pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("调用函数后输出a,b的值为:"); printf("%d,%d\n",a,b); }

【例6-12】如果上例中的交换函数交换的是指针, 则结果如何? 【例6-12】如果上例中的交换函数交换的是指针, 则结果如何? void main() { int a,b,*pointer_1,*pointer_2; printf("输入a,b的值:"); scanf("%d,%d",&a,&b); pointer_1=&a,pointer_2=&b; swap(pointer_1,pointer_2); printf("调用函数后输出a,b的值为:"); printf("%d,%d\n",a,b); printf(“调用函数后输出 *pointer_1,*pointer_2的值为:"); printf("%d,%d\n",*pointer_1,*pointer_2); } #include <stdio.h> void swap(int *p1,int *p2) { int *temp; temp=p1; p1=p2; p2=temp; }

举一反三 【例6-11】输入a、b、c 3个整数,按从大到小顺序输出。 void main() { int a,b,c,*p1,*p2,*p3; printf("请输入3个数,以逗号隔开:"); scanf("%d,%d,%d",&a,&b,&c); p1=&a; p2=&b;p3=&c; if(a<b) swap(p1,p2); if(a<c) swap(p1,p3); if(b<c) swap(p2,p3); printf("从大到小的顺序为:"); printf("%d,%d,%d\n",a,b,c); } #include <stdio.h> void swap(int *a,int *b) { int t; t=*a; *a=*b; *b=t; }

任务2 用指针优化全班同学一门课成绩的输入输出 一、问题情景 一个班有40个同学进行了一次考试,现要用指针实现全班同学成绩的输入输出。 二、具体实现(以十个学生为例) 方法一:下标法(常用,很直观) #include <stdio.h> main() {int score[10],i; printf("请输入10个学生的成绩\n"); for(i=0;i<10;i++) scanf("%d",&score [i]); printf("输出的10个学生的成绩为\n"); printf("%3d", score [i]); printf("\n"); }

三、相关知识 (一)指向一维数组的指针 复习:一维数组在内存中的存放方法? int a[5]; a[0] a[1] 数组元素的地址:&a[i] 数组首地址:&a[0]或a

三、相关知识 指向数组 1、指针与一维数组的对应关系 int a[10],*p=a; memory 使p指向a数组的第一个元素a[0] 各元素的指针按存储单元递增 a[0] a[2] a[4] a[3] a[6] a[7] a[1] a[5] a[8] a[9] memory p p+1 p+2 p+9 2、用指针访问数组的一般形式 对下标为i的元素访问: a[i],*(a+i),*(p+i) 对a[i]的地址表示: &a[i],a+i,p+i 访问数组的两种方式:下标方式,指针方式

三、相关知识 (1)下标法(常用,很直观) #include <stdio.h> main() {int score[10],i; printf("请输入10个学生的成绩\n"); for(i=0;i<10;i++) scanf("%d",&score [i]); printf("输出的10个学生的成绩为\n"); printf("%3d", score [i]); printf("\n"); }

三、相关知识 (2)用数组名计算数组元素的地址。 (效率与下标法相同,不常用) #include <stdio.h> main() {int score[10],i; printf("请输入10个学生的成绩\n"); for(i=0;i<10;i++) scanf("%d",& score [i]); printf("输出的10个学生的成绩为\n"); printf("%3d", *(score+i)); printf("\n"); }

三、相关知识 (3)用指针访问各元素。(常用,效率高) #include <stdio.h> main() {int score[10],*p,i; printf("请输入10个学生的成绩\n"); for(i=0;i<10;i++) scanf("%d",& score [i]); printf("输出的10个学生的成绩为\n"); for(p=score;p<score+10;p++) printf("%3d", *p); printf("\n"); }

#include <stdio.h> void main() { int a[10],*p,i; p=a; 【例6-5】下面的程序在输入1 2 3 4 5 6 7 8 9 0后的输出结果还是1 2 3 4 5 6 7 8 9 0吗? #include <stdio.h> void main() { int a[10],*p,i; p=a; for(i=0;i<10;i++) scanf("%d",p++); printf("\n"); for(i=0;i<10;i++,p++) printf("%d ",*p); } #include <stdio.h> void main() { int a[10],*p,i; p=a; for(i=0;i<10;i++) scanf("%d",p++); /*特别要注意输入时指针的变化*/ printf("\n"); /*使p指针重新指向了数组的首地址*/ for(i=0;i<10;i++,p++) printf("%d ",*p); } 输入:1 2 3 4 5 6 7 8 9 0 输出: 怎样解决? 小结: (1) 指针变量可以实现自身值的改变。如:pa++; 而数组名所代表的地址则不能改变,a++是错误的用法。 (2)应注意指针变量的当前值。如上例。 (3)指针变量可以指向数组中各个内存单元。

注意 指针使用的几个细节 设指针p指向数组a(p=a),则: ①*p++,相当于*(p++) ② *(p++):先取*p,再使p加1

实训报告11

指向二维数组的指针 1、二维数组结构的分析 设有数组定义为:int a[3][4]; 则有: a表示数组在内存中的首地址。 a+i=a[i]=&a[i][0] 代表第i行的首地址

指向二维数组的指针 a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] 二维数组的逻辑结构图如下: a+0 a[0] 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+1 a[1] a[2][0] a[2][1] a[2][2] a[2][3] a+2 a[2]

2、指向二维数组中一行的指针变量 我们可以定义一种指向行向量的指针,让它指向二维数组的第一行,该指针加1,就指向二维数组的下一行,这样的指针就叫做行指针。 (1)格式:类型名 (*指针变量名)[每一行的元素个数]; (2)例如:int (*p)[4]; (3)含义:p是指针变量,它指向一个数组,数组 每一行含有4个元素,每个元素的类型是int。

若定义:int a[3][4], (*pa)[4]=a; 则关系图为: (*pa)[0] (*pa)[1] (*pa)[2] (*pa)[3] a pa pa 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] pa++ 如果执行pa++, 则变为如图所示 那么(*pa)[0]、(*pa)[1]、(*pa)[2]、(*pa)[3] 也变了

设p为指向二维数组的指针变量, 若p=b[0],可定义为int(*p)[4],p=b, 则p+i指向一维数组b[i],而*(*(p+i)+j)则是i行j列元素的值。 *(*(b+i)+j)式子是根据二维数组名计算i行j列元素的值; 还有一种直接采用首元素地址计算i行j列元素的方法。 其格式如下: *(首元素地址+行号*列数+列号)

【例6-6】 用几种方法输出二维数组各元素的值。 #include <stdio.h> void main() { int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int i,j,(*p)[4]; int row,col; p=s; printf("用二维数组的指针变量计算i行j列元素的方法\n"); for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%8d",*(*(p+i)+j)); printf("\n"); } printf("用二维数组的数组名计算i行j列元素的方法\n"); for(i=0;i<3;i++) { for(j=0;j<4;j++) printf("%8d",*(*(s+i)+j)); printf("\n"); } printf("用直接采用首元素地址计算i行j列元素的方法\n"); row=3;col=4; for(i=0;i<row;i++) { for(j=0;j<col;j++) printf("%8d",*(&s[0][0]+i*col+j)); printf("\n"); }}

有3个学生,各学4门课, 计算某一位学生的平均成绩 例 有3个学生,各学4门课, 计算某一位学生的平均成绩 #include <stdio.h> void average(float (*p)[4]) { int j; float sum=0; for(j=0;j<4;j++) sum+= (*p)[j]; printf ("这位学生的平均分为%5.2f\n ",sum/4); } main() { float score[3][4]={{66,67,70,60},{80,87,90,81},{90,99,100,98}}; average(score[2]); }

任务4 用指针优化学生姓名的排序 一、问题情景 分析: 要将3个候选人以姓氏的英文顺序排队, 要求用C中的字符指针解决此问题, 所以,在本任务中将要解决什么是字符指针,字符指针如何引用。

三、相关知识 一、字符串的表现形式 C语言中,有两种方式可以实现字符串:字符数组、字符指针。 (一)字符串的表示形式 1. 用字符数组实现 #include <stdio.h> main() { char string[ ]="I love China! "; printf("%s\n",string); } 2. 用字符指针实现 #include <stdio.h> main() { char *string="I love China! "; printf("%s\n",string); }

【例6-9】将字符串a复制到字符串b。 #include <stdio.h> void main() { 方法一 #include <stdio.h> void main() { char a[]="I am a boy.",b[20],*p1,*p2; int i; p1=a; p2=b; for(;*p1!='\0';p1++,p2++) *p2=*p1; *p2='\0'; printf("string a is:%s\n",a); printf("string b is:%s\n",b); printf("\n"); } 方法二 #include <stdio.h> void main() { char *a="I am a boy.",*b; b=a; printf("string a is:%s\n",a); printf("string b is:%s\n",b); printf("\n"); } 注意:若a,b都是字符指针,则可以用b=a,即将a的地址赋给b, 但是若a,b是字符数组,则不能用b=a,应用strcpy(b,a)

用指针实现: 输入一个字符串,把其中大写字母变成小写字母 。 #include <stdio.h> main() { char str[80],*pt; gets(str); for(pt=str;*pt!='\0';pt++) if(*pt>='A'&&*pt<='Z') *pt+=32; printf("string is:\n%s\n",str); }

用指针实现:输入一个字符串,求出字符串长度的函数。 并在主函数中实现调用。 #include <stdio.h> int str_len(char *str) { char *pt; int count=0; for(pt=str;*pt!='\0';pt++) count++; return count; } main() char str[80]; printf("请输入一个字符串\n"); gets(str); printf("该字符串的长度为%d\n",str_len(str));

任务5的具体实现 #include <stdio.h> #include "string.h" main( ) { char *name1="张小明",*name2="李大刚",*name3="周建华",*tt; if( strcmp(name1,name2)<0) {tt=name1;name1=name2;name2=tt;} if( strcmp(name1,name3)<0) {tt=name1;name1=name3;name3=tt;} if( strcmp(name2,name3)<0) {tt=name2;name2=name3;name3=tt;} printf("输出的姓名为:\n"); printf("%s\n",name1); printf("%s\n",name2); printf("%s\n",name3); }

字符数组与字符串指针变量的区别 字符数组 字符串指针变量 存放的是首地址 每个元素放一个字符 可以整体赋值 不能整体赋值 char *p; p=“abcde”; char s[6]; s=“abcde”; /* 不对*/ char s[6]; 使用s不能加/减 p可以加/减

指针数组 指针数组中每一个元素都是一个指针变量, 并且它们具有相同的数据类型。 指针数组的引用 char *p[4]; 格式: 类型标识 *数组名[数组长度] 功能: 指向一维数组的指针变量。 说明: 适合于指向若干个字符串, 使字符串处理更加方便灵活。 char *p[4];

字符指针数组的初始化。 #include <stdio.h> main() { char *week[]={"Sunday","Monday","Tuesday", "Wednesday","Thursday","Friday","Saturday"}; int i; while(1) printf("Enter week No:"); scanf("%d",&i); if(i<0||i>6) break; printf("Week No.%d--%s\n",i,week[i]); }

将4个字符串:dog,cat,pig和all animal 用指针数组输出。 #include <stdio.h> main() { char *s[4]; int i; s[0]="dog"; s[1]="cat"; s[2]="pig"; s[3]="all animal"; for(i=0;i<4;i++) printf("%s\n",*(s+i)); }