教案
序号 | 031 | 周 次 | 授课形式 | 新 授 | |
授课章节名称 | 通过指针引用数组 | ||||
教学目的 | 通过指针引用数组 | ||||
教学重点 | 通过指针引用数组 | ||||
教学难点 | 通过指针引用数组 | ||||
使用教具 | 机房 | ||||
课外作业 | |||||
课后体会 | |||||
授课主要内容 8.3.1 数组元素的指针 一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址 指针变量可以指向数组元素(把某一元素的地址放到一个指针变量中) 所谓数组元素的指针就是数组元素的地址 可以用一个指针变量指向一个数组元素 int a[10]={1,3,5,7,9,11,13,15,17,19}; int *p; p=&a[0]; 8.3.2 在引用数组元素时指针的运算 在指针指向数组元素时,允许以下运算: ◆加一个整数(用+或+=),如p+1 ◆减一个整数(用-或-=),如p-1 ◆自加运算,如p++,++p ◆自减运算,如p--,--p ◆两个指针相减,如p1-p2 (只有p1和p2都指向同一数组中的元素时才有意义) (1) 如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。 float a[10],*p=a; 假设a[0]的地址为2000,则 ◆p的值为2000 ◆p+1的值为2004 ◆P-1的值为1996 (2) 如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它们指向a数组序号为i的元素 (3) *(p+i)或*(a+i)指针与二维数组是p+i或a+i所指向的数组元素,即a[i]。 (4) 如果指针p1和p2都指向同一数组 p2-p1的值是4 不能p1+p2 8.3.3 通过指针引用数组元素 引用一个数组元素,可用下面两种方法: (1) 下标法,如a[i]形式 (2) 指针法,如*(a+i)或*(p+i) 其中a是数组名,p是指向数组元素的指针变量,其初值p=a 8.3.3 通过指针引用数组元素 例8.6 有一个整型数组a,有10个元素,要求输出数组中的全部元素。 解题思路:引用数组中各元素的值有3种方法:(1)下标法;(2)通过数组名计算数组元素地址,出元素的值;(3) 用指针变量指向数组元素 分别写出程序,以资比较分析。 (1) 下标法。 #include <stdio.h> int main() { int a[10]; int i; printf(“enter 10 integer numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) printf(“%d ”,a[i]); printf("%\n"); return 0; } (2) 通过数组名计算数组元素地址,出元素的值 #include <stdio.h> int main() { int a[10]; int i; printf(“enter 10 integer numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) printf(“%d ”,*(a+i)); printf("\n"); return 0; } (3) 用指针变量指向数组元素 #include <stdio.h> int main() { int a[10]; int *p,i; printf(“enter 10 integer numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(p=a;p<(a+10);p++) printf(“%d ”,*p); printf("\n"); return 0; } 3种方法的比较: ① 第(1)和第(2)种方法执行效率相同 ◆C编译系统是将a[i]转换为*(a+i)处理的,即先计算元素地址。 ◆因此用第(1)和第(2)种方法数组元素费时较多。 3种方法的比较: ② 第(3)种方法比第(1)、第(2)种方法快 ◆用指针变量直接指向元素,不必每次都重新计算地址,像p++这样的自加操作是比较快的 ◆这种有规律地改变地址值(p++)能大大提高执行效率 3种方法的比较: ③ 用下标法比较直观,能直接知道是第几个元素。 用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。 例8.7 通过指针变量输出整型数组a的10个元素。 解题思路: 用指针变量p指向数组元素,通过改变指针变量的值,使p先后指向a[0]到a[9]各元素。 #include <stdio.h> int main() { int *p,i,a[10]; p=a; printf(“enter 10 integer numbers:\n"); for(i=0;i<10;i++) scanf(“%d”,p++); for(i=0;i<10;i++,p++) printf(“%d ”,*p); printf("\n"); return 0; } 8.3.4 用数组名作函数参数 用数组名作函数参数时,因为实参数组名代表该数组首元素的地址,形参应该是一个指针变量 C编译都是将形参数组名作为指针变量来处理的 int main() { void fun(int arr[],int n]; int array[10]; ┇ fun (array,10); return 0; } void fun(int arr[ ],int n) { ┇ } int main() { void fun(int arr[],int n]; int array[10]; ┇ fun (array,10); return 0; } void fun(int *arr,int n) { ┇ } 实参数组名是指针常量,但形参数组名是按指针变量处理 在函数调用进行虚实结合后,它的值就是实参数组首元素的地址 在函数执行期间,形参数组可以再被赋值 void fun (arr[ ],int n) { printf(″%d\n″, *arr); arr=arr+3; printf(″%d\n″, *arr); } 例8.8 将数组a中n个整数按相反顺序存放 解题思路:将a[0]与a[n-1]对换,……将a[4]与a[5]对换。 例8.8 将数组a中n个整数按相反顺序存放 解题思路:将a[0]与a[n-1]对换,……将a[4]与a[5]对换。 例8.8 将数组a中n个整数按相反顺序存放 解题思路:将a[0]与a[n-1]对换,……将a[4]与a[5]对换。 例8.8 将数组a中n个整数按相反顺序存放 解题思路:将a[0]与a[n-1]对换,……将a[4]与a[5]对换。 例8.8 将数组a中n个整数按相反顺序存放 解题思路:将a[0]与a[n-1]对换,……将a[4]与a[5]对换。 #include <stdio.h> int main() { void inv(int x[ ],int n); int i, a[10]={3,7,9,11,0,6,7,5,4,2}; for(i=0;i<10;i++) printf(“%d ”,a[i]); printf("\n"); inv(a,10); for(i=0;i<10;i++) printf(“%d ”,a[i]); printf("\n"); return 0; } void inv(int x[ ],int n) { int temp,i,j,m=(n-1)/2; for(i=0;i<=m;i++) { j=n-1-i; temp=x[i];x[i]=x[j];x[j]=temp; } } 例8.9 改写例8.8,用指针变量作实参。 例8.10 用指针方法对10个整数按由大到小顺序排序。 解题思路: ◆在主函数中定义数组a存放10个整数,定义int *型指针变量p指向a[0] ◆定义函数sort使数组a中的元素按由大到小的顺序排列 ◆在主函数中调用sort函数,用指针p作实参 ◆用选择法进行排序 #include <stdio.h> int main() { void sort(int x[ ],int n); int i,*p,a[10]; p=a; for(i=0;i<10;i++) scanf(“%d”,p++); p=a; sort(p,10); for(p=a,i=0;i<10;i++) { printf(“%d ”,*p); p++; } printf("\n"); return 0; } void sort(int x[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(x[j]>x[k]) k=j; if(k!=i) { t=x[i];x[i]=x[k];x[k]=t; } } } 8.3.5 通过指针引用多维数组 指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用方法上,多维数组的指针比一维数组的指针要复杂一些。 8.3.5 通过指针引用多维数组 1. 多维数组元素的地址 int a[3][4]={{1,3,5,7}, {9,11,13,15},{17,19,21,23}}; a代表第0行首地址 a+1代表第1行首地址 a+2代表第2行首地址 a+i代表行号为i的行首地址(按行变化) *(a+i)代表什么? a[0]代表a[0][0]的地址 a[0]+1代表a[0][1]的地址 a[0]+2代表a[0][2]的地址 a[0]+3代表a[0][3]的地址 a[1]代表谁的地址? a[1]+1代表谁的地址? a[1]+2代表谁的地址? a[1]+3代表谁的地址? a[i]+j代表谁的地址? 例8.11 二维数组的有关数据(地址和值) #include <stdio.h> int main() { int a[3][4]={1,3,5,7,9,11,13,15, 17,19,21,23}; printf(“%d,%d\n”,a,*a); printf(“%d,%d\n”,a[0],*(a+0)); printf(“%d,%d\n”,&a[0],&a[0][0]); printf(“%d,%d\n”,a[1],a+1); printf(“%d,%d\n”,&a[1][0],*(a+1)+0); printf(“%d,%d\n”,a[2],*(a+2)); printf(“%d,%d\n”,&a[2],a+2); printf(“%d,%d\n”,a[1][0],*(*(a+1)+0)); printf(“%d,%d\n”,*a[2],*(*(a+2)+0)); return 0; } printf(“%d,%d\n”,a,*a); printf(“%d,%d\n”,a[0],*(a+0)); printf(“%d,%d\n”,&a[0],&a[0][0]); printf(“%d,%d\n”,a[1],a+1); printf(“%d,%d\n”,&a[1][0],*(a+1)+0); printf(“%d,%d\n”,a[2],*(a+2)); printf(“%d,%d\n”,&a[2],a+2); printf(“%d,%d\n”,a[1][0],*(*(a+1)+0)); printf(“%d,%d\n”,*a[2],*(*(a+2)+0)); return 0; } printf(“%d,%d\n”,a,*a); printf(“%d,%d\n”,a[0],*(a+0)); printf(“%d,%d\n”,&a[0],&a[0][0]); printf(“%d,%d\n”,a[1],a+1); printf(“%d,%d\n”,&a[1][0],*(a+1)+0); printf(“%d,%d\n”,a[2],*(a+2)); printf(“%d,%d\n”,&a[2],a+2); printf(“%d,%d\n”,a[1][0],*(*(a+1)+0)); printf(“%d,%d\n”,*a[2],*(*(a+2)+0)); return 0; } 2. 指向多维数组元素的指针变量 (1) 指向数组元素的指针变量 例8.12 有一个3×4的二维数组,要求用指向元素的指针变量输出二维数组各元素的值。 解题思路: ◆二维数组的元素是整型的,它相当于整型变量,可以用int*型指针变量指向它 ◆二维数组的元素在内存中是按行顺序存放的,即存放完序号为0的行中的全部元素后,接着存放序号为1的行中的全部元素,依此类推 ◆因此可以用一个指向整型元素的指针变量,依次指向各个元素 #include <stdio.h> int main() { int a[3][4]={1,3,5,7,9,11,13,15, 17,19,21,23}; int *p; for(p=a[0];p<a[0]+12;p++) { if((p-a[0])%4==0) printf(“\n”); printf(“%4d”,*p); } printf("\n"); return 0; } (2) 指向由m个元素组成的一维数组的指针变量 例8.13 输出二维数组任一行任一列元素的值。 解题思路:假设仍然用例8.12程序中的二维数组,例8.12中定义的指针变量是指向变量或数组元素的,现在改用指向一维数组的指针变量。 #include <stdio.h> int main() {int a[3][4]={1,3,5,7,9,11,13,15, 17,19,21,23}; int (*p)[4],i,j; p=a; printf(“enter row and colum:"); scanf(“%d,%d”,&i,&j); printf(“a[%d,%d]=%d\n”, i,j,*(*(p+i)+j)); return 0; } 3. 用指向数组的指针作函数参数 一维数组名可以作为函数参数,多维数组名也可作函数参数。 用指针变量作形参,以接受实参数组名传递来的地址。 可以有两种方法: ①用指向变量的指针变量 ②用指向一维数组的指针变量 例8.14 有一个班,3个学生,各学4门课,计算总平均分数以及第n个学生的成绩。 解题思路:这个题目是很简单的。本例用指向数组的指针作函数参数。用函数average求总平均成绩,用函数search出并输出第i个学生的成绩。 #include <stdio.h> int main() { void average(float *p,int n); void search(float (*p)[4],int n); float score[3][4]={{65,67,70,60}, {80,87,90,81},{90,99,100,98}}; average(*score,12); search(score,2); return 0; } void average(float *p,int n) { float *p_end; float sum=0,aver; p_end=p+n-1; for( ;p<=p_end; p++) sum=sum+(*p); aver=sum/n; printf("average=%5.2f\n",aver); } #include <stdio.h> int main() { void average(float *p,int n); void search(float (*p)[4],int n); float score[3][4]={{65,67,70,60}, {80,87,90,81},{90,99,100,98}}; average(*score,12); search(score,2); return 0; } void search(float (*p)[4],int n) { int i; printf("The score of No.%d are:\n",n); for(i=0;i<4;i++) printf("%5.2f ",*(*(p+n)+i)); printf("\n"); } 例8.15 在上题基础上,查有一门以上课程不及格的学生,输出他们的全部课程的成绩。 解题思路:在主函数中定义二维数组score,定义search函数实现输出有一门以上课程不及格的学生的全部课程的成绩,形参p的类型是float(*)[4]。在调用search函数时,用score作为实参,把score[0]的地址传给形参p。 #include <stdio.h> int main() { void search(float (*p)[4],int n); float score[3][4]={{65,57,70,60}, {58,87,90,81},{90,99,100,98}}; search(score,3); return 0; } void search(float (*p)[4],int n) { int i,j,flag; for(j=0;j<n;j++) { flag=0; for(i=0;i<4;i++) if(*(*(p+j)+i)<60) flag=1; if(flag==1) { printf("No.%d fails\n",j+1); for(i=0;i<4;i++) printf(“%5.1f ”,*(*(p+j)+i)); printf("\n"); } } } void search(float (*p)[4],int n) { int i,j,flag; for(j=0;j<n;j++) { flag=0; for(i=0;i<4;i++) if(*(*(p+j)+i)<60) flag=1; if(flag==1) { printf("No.%d fails\n",j+1); for(i=0;i<4;i++) printf(“%5.1f ”,*(*(p+j)+i)); printf("\n"); } } } | |||||
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论