教案
序号
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 (只有p1p2都指向同一数组中的元素时才有意义)
(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+ia+i就是数组元素a[i]的地址,或者说,它们指向a数组序号为i的元素
(3)  *(p+i)*(a+i)指针与二维数组p+ia+i所指向的数组元素,即a[i]
(4) 如果指针p1p2都指向同一数组
  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 通过指针变量输出整型数组a10个元素。
解题思路:
  用指针变量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 将数组an个整数按相反顺序存放
解题思路:将a[0]a[n-1]对换,……将a[4]a[5]对换。
8.8 将数组an个整数按相反顺序存放
解题思路:将a[0]a[n-1]对换,……将a[4]a[5]对换。
8.8 将数组an个整数按相反顺序存放
解题思路:将a[0]a[n-1]对换,……将a[4]a[5]对换。
8.8 将数组an个整数按相反顺序存放
解题思路:将a[0]a[n-1]对换,……将a[4]a[5]对换。
8.8 将数组an个整数按相反顺序存放
解题思路:将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小时内删除。